初识C语言
C语言是一门通用计算机编程语言,广泛应用于底层开发。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。
尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电脑等作业平台。
二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言制定了一套完整的美国国家标准语法,称为ANSI C,作为C语言最初的标准。 [1] 目前2011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC)发布的C11标准是C语言的第三个官方标准,也是C语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉字编程。
C语言是一门面向过程的计算机编程语言,与C++,Java等面向对象的编程语言有所不同。
其编译器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。
注
创建项目



创建源文件



编写代码


注:
main函数总结:
main函数是程序的入口,一个工程中main函数有且仅有一个
当出现程序函数"int main()"已有主体这样的错误时,说明一个工程中出现了多个main函数
一个工程中可以有多个.c文件,但是多个.c文件中只能有一个main函数
编译代码以及运行


注意:以上是在VS2019下运行的,如果在VS2013中运行需要注意当运行时会发现程序执行的太快看不到结果,这时需要设置VS2013中的属性(VS2019不需要设置项目属性)
设置项目属性:右击项目->点击属性

注意:VS2013和VS2019的使用大同小异

出现这么多种的类型,是因为计算机语言在编写程序时需要解决生活中问题,计算机语言必须有能力来描述生活中问题(eg:年龄、体重、收入……)以及类型丰富选择性更多空间利用率更高。
每种类型的大小
int main()
{
printf("%d\n", sizeof(char)); //1
printf("%d\n", sizeof(short)); //2
printf("%d\n", sizeof(int)); //4
printf("%d\n", sizeof(long)); //4
printf("%d\n", sizeof(long long)); //8
printf("%d\n", sizeof(float)); //4
printf("%d\n", sizeof(double)); //8
printf("%d\n", sizeof(long double)); //8
return 0;
}
注:
%d用于打印整数、%lf用于打印double类型、%f用于打印float类型
sizeof是关键字也是操作符,用来计算类型或者变量所占空间的大小
sizeof的单位是字节byte
二进制由0-1组成、八进制由0-7组成、十进制由0-9组成、十六进制由0-f组成
计算机中最小的单位是bit(比特位),一个比特位是存放一个二进制位的
计算机中的单位由小到大:bit、byte(1byte=8bit)、kb(1kb=1024byte)、mb(1mb=1024kb)、gb(1gb=1024mb)、tb(1tb=1024gb)、pb(1pb=1024gb)、……
long和int类型大小相同,这是因为C语言标准规定sizeof(long)>=sizeof(int)即可(在VS中采用的是大小相等)
注意:存在这么多的类型,其实是为了更加丰富的表达生活中的各种值。
常量描述的是不能改变的量
变量描述的是能被改变的量
定义变量的方法
int age = 150;
float weight = 45.5f; //代表单精度,如果不加f默认代表双精度(d)
char ch = 'w';
变量的分类:局部变量、全局变量
局部变量:在大括号内部定义的变量
全局变量:在大括号外部定义的变量
变量的使用
//全局变量 - {}外部定义的
int a = 100;
int main()
{
//局部变量 - {}内部定义的
int a = 10;
printf("%d\n", a);
return 0;
}

注意:当局部变量和全局变量名字冲突的情况下,局部优先。不建议把全局变量和局部变量的名字写成一样的

注意:

#define _CRT_SECURE_NO_WARNINGS 1
scanf_s函数是VS编译器提供的,不是C语言标准规定的,因此如果使用了在VS中能跑,但在其他平台就不行了(可移植性太差了),综上使用scanf函数
scanf_s函数和scanf函数的使用方法是有区别的
当该文件中添加这句代码时#define _CRT_SECURE_NO_WARNINGS 1,每当创建新源文件时都会有这句代码
VS2019路径:

VS2013路径:

变量的作用域和生命周期
作用域
作用域(scope),程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的而限定这个名字的可用性的代码范围就是这个名字的作用域。
注:当在整个工程中一个源文件创建的全局变量(eg:int a=10;)另一个源文件想要使用就需要提前声明该变量(extern int a;)
生命周期
变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
常量
C语言中的常量分为以下以下几种:
int main()
{
//字面常量
3.14;
10;
'a';
"abcdef";
return 0;
}
int main()
{
//const修饰的常变量
const int num = 10;//num就是常变量 - 具有常属性(不能被改变的属性)
return 0;
}

注意:const修饰的变量是常变量,不是常量,更不能作为数组的元素个数
#define MAX 10000
int main()
{
// #define 定义的标识符常量
//MAX = 20000;//会报错,不能修改
int n = MAX;
printf("n = %d\n", n); //10000
return 0;
}
//性别
enum Sex
{
//这种枚举类型的变量的未来可能取值
//枚举常量
MALE = 3,//赋初值
FEMALE,
SECRET
};
int main()
{
//枚举常量可以一一列举的常量
enum Sex s = MALE;
//MALE = 3;//不能修改,会报错
printf("%d\n", MALE); //3
printf("%d\n", FEMALE); //4
printf("%d\n", SECRET); //5
return 0;
}
字符串
由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal),或者简称字符串。


%s打印的是字符串,是以\0为结束标志。而arr2数组没有\0因此后面是随机值直到遇到\0结束

strlen函数是计算字符串的长度(不计入\0),遇到\0结束返回字符串长度
总结:字符串的结束标志是一个 \0 的转义字符。在计算字符串长度的时候 \0 是结束标志,不算作字符串内容。
转义字符
转义字符顾名思义就是转变意思(转变他原来的意思)。
下面看一些转义字符:

补充:
经典笔试题:
//程序输出什么?
#include <stdio.h>
int main()
{
printf("%d\n", strlen("abcdef"));
// \32被解析成一个转义字符
printf("%d\n", strlen("c:\test\328\test.c")); //14
//c : \t e s t \32 8 \t e s t . c
return 0;
}
注释
例如:

注释有两种风格:
例如:
int main()
{
int input = 0;//输入的值
printf("好好学习吗(1/0)?>:");
scanf("%d", &input);
if (input == 1)
{
printf("未来可期\n");
}
else
{
printf("回家种地\n");
}
return 0;
}
例如:
int main()
{
printf("变成小白\n");
int line = 0;
//循环
while(line<30000)
{
printf("写代码:%d\n", line);
line++;
}
if (line == 30000)
{
printf("编程大牛\n");
}
return 0;
}
#include <stdio.h>
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
scanf("%d %d", &a, &b);
sum = num1 + num2;
printf("sum = %d\n", sum);
return 0;
}
//上述代码,写成函数如下:
#include <stdio.h>
int Add(int x, int y)
{
int z = x+y;
return z;
}
int main()
{
int num1 = 0;
int num2 = 0;
int sum = 0;
printf("输入两个操作数:>");
scanf("%d %d", &num1, &num2);
sum = Add(num1, num2);
printf("sum = %d\n", sum);
return 0;
}
注意:
数组是一组相同类型的元素的集合
数组的定义:
int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整形数组,最多放10个元素
数组的使用:
int main()
{
//数组 - 一组相同类型的元素的集合
//数组是用下标来访问的,从0下标开始
//10个整形1-10存起来
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int i = 0;
while (i < 10)
{
printf("%d ", arr[i]);
i++;
}
char ch[5] = {'a', 'b', 'c'};//不完全初始化,剩余的默认为0
return 0;
}
注:这样写int arr[3];只是创建了数组arr并未初始化数组元素的值

上面这样初始化是错误的
补充:

注意:在C99 标准中引用一个概念—变长数组(支持数组创建的时候,用变量指定大小的,但是这个数组不能初始化),但是VS2019 不支持C99中的变长数组
算术操作符
+ - * / %
/号两端如果都是整数执行整数除法(无论用什么类型存储结果)。/号两端有一端是小数则执行小数除法
移位操作符
>> <<
移位操作符:移动的是二进制位。如果是左移操作符空缺位永远补0
位操作符
& ^ |
赋值操作符
= += -= *= /= &= ^= |= >>= <<=
单目操作符
双目操作符指的是有两个操作数;单目操作符指的是只有一个操作数
C语言规定:0表示假,非0表示真;如果一个数为0那么对这个数进行逻辑反操作那么这个数是1
sizeof的使用:


~的使用:

前置++和后置++的使用:

前置–、后置–和前置++、后置++的使用一样
int main()
{
int a = 1;
int b = (++a) + (++a) + (++a);//12
printf("%d\n", b);
return 0;
}
注意:上面的代码是有错误的不建议去研究,因为在不同编译器上运行结果可能是不同的,VS下运行结果是12
强制类型转换的使用:

注意:如果想要避免警告,需要使用强制类型转换。不推荐去使用(因为要使用强制类型转换说明设计有缺陷)
关系操作符

逻辑操作符
逻辑与是所有条件都为真时,结果才为真,否则就为假;逻辑或是只要有一个事件为真,结果就为真,否为为假
条件操作符(三目操作符)
exp1 ? exp2 : exp3
exp1成立,exp2计算,整个表达式的结果是exp2的结果;exp1不成立,exp3计算,整个表达式的结果是exp3的结果。
条件操作符的使用:

逗号表达式
exp1, exp2, exp3, …expN
逗号表达式是逗号隔开的一串表达式
逗号表达式的使用:
int main()
{
(2, 4 + 5, 6); //逗号表达式
int a = 0;
int b = 3;
int c = 5;
//a=5 c=1 b=3
int d = (a = b + 2, c = a - 4, b = c + 2);
//逗号表达式,是从左向右依次计算的
//整个表达式的结果是最后一个表达式的结果
printf("%d\n", d); //3
return 0;
}
注:逗号表达式是从左向右依次计算的,整个表达式的结果是最后一个表达式的结果。
下标引用、函数调用和结构成员
[] () . ->(间接引用操作符)
下标引用、函数调用操作符的使用:

注:. -> * &下面会提到
常见关键字需要注意的事项:
auto关键字
auto是自动变量,每个局部变量(自动创建自动销毁的)都是auto修饰的自动变量,基本都省略掉了。
auto的使用:
auto int a=10;
注:auto 新的C语言语法中也有其他用法 ( 暂时不考虑)
extern关键字
extern是用来声明外部符号的
extern关键字的使用:


注:
register关键字(寄存器关键字)
register寄存器关键字作用是用register创建的变量建议把它放到寄存器里,具体将变量放不放进去由编译器说了算,register只是起到建议的作用
register关键字的使用:
register int num = 100;//建议num的值存放在寄存器中
注意:register关键字的应用——大量频繁被使用的数据想放在寄存器中,目的是提升效率。目前编译器比较智能了,它会自动判断该变量是否需要放入寄存器中
补充:

signed关键字
signed有符号的 ;unsigned 无符号的
typedef关键字
typedef 顾名思义是类型定义,这里应该理解为类型重命名(类型重定义)。
typedef关键字的使用:
typedef unsigned int u_int;
//将unsigned int 重命名为u_int, 所以u_int也是一个类型名
int main()
{
unsigned int num = 100;
u_int num2 = 100;
return 0;
}
static关键字
在C语言中static是用来修饰变量和函数的(static - 静态的)
static关键字的使用:
static修饰局部变量

static修饰局部变量,改变了局部变量的生命周期(本质上是改变了变量的存储类型)
static修饰全局变量

static修饰全局变量,使得这个全局变量只能在自己所在的源文件(.c)内部可以使用,而其他源文件不能使用
注意:static修饰的局部变量只限于在该函数内部有效,出其作用域该变量无效(否则会报错)
static修饰函数

static修饰函数,使得函数只能在自己所在的源文件内部使用,不能在其他源文件内部使用。本质上static是将函数的外部链接属性变成了内部链接属性(和static修饰全局变量一样)
注:
总结:
union关键字
union - 联合体(共用体)
void关键字
void - 无、空
注意:
define 是一个预处理指令
作用一:define定义标识符常量(define定义符号)
#define MAX 1000 //MAX也可称为符号
int main()
{
printf("%d\n", MAX);
return 0;
}
作用二:define定义宏
//define 定义宏
#define ADD(X,Y) ((X)+(Y))
int main()
{
printf("%d\n", 4*ADD(2, 3));
return 0;
}
内存
内存是电脑上特别重要的存储器,计算机中所有程序的运行都是在内存中进行的 。所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。

注:
取出变量地址(&操作符)以及定义指针变量:

指针的使用实例(*操作符):
//指针 就是 地址
int main()
{
int a = 10;
int* pa = &a;
*pa = 20;//* 解引用操作 , *pa就是通过pa里边的地址,找到a并对a进行操作
printf("%d\n", a);
return 0;
}

总结:指针的大小是相同的。因为指针是用来存储地址的,指针需要多大空间取决于地址的存储需要多大空间。在32位机器上其实是32个比特位组成的二进制序列作为地址(存储需4字节);在64位机器上其实是64个比特位组成的二进制序列作为地址(存储需8字节)
注:指针大小在32位平台(x86)是4个字节,64位平台(x64)是8个字节。
结构体使得C语言有能力描述复杂类型。比如描述学生,学生包含: 名字+年龄+成绩 这几项信息。这里只能使用结构体来描述了。
结构体的创建:
//结构体可以让C语言创建新的类型出来
//创建一个学生
struct Stu
{
char name[20];//成员变量
int age;
double score;
};
//创建一个书的类型
struct Book
{
char name[20];
float price;
char id[30];
};
结构体的初始化以及.操作符和->操作符的使用:
//结构体可以让C语言创建新的类型出来
//创建一个学生
struct Stu
{
char name[20];//成员变量
int age;
double score;
};
//创建一个书的类型
struct Book
{
char name[20];
float price;
char id[30];
};
int main()
{
struct Stu s = { "张三", 20, 85.5 };//结构体的创建和初始化
printf("1: %s %d %lf\n", s.name, s.age, s.score);//结构体变量.成员变量名
struct Stu* ps = &s;
printf("2: %s %d %lf\n", (*ps).name, (*ps).age, (*ps).score);
printf("3: %s %d %lf\n", ps->name, ps->age, ps->score); //结构体指针->成员变量名
return 0;
}
注:.和->用于访问和修改结构体中成员变量的值
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------
嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来
关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭11年前。Improvethisquestion我不经常使用ruby-通常它加起来相当于每两个月或更长时间编写一次脚本。我的大部分编程都是使用C++进行的,这与ruby有很大不同。由于我与ruby之间的差距如此之大,我总是忘记语言的基本方面(比如解析文本文件和其他简单的东西)。我想每天练习一些基本的东西,我想知道是否有一些我可以订阅的网站,并且会向我发送当天的Ruby问题或类似的东西。有人知道这样的站点/Internet服务吗?
如果特定语言环境中缺少翻译,如何配置i18n以使用en语言环境翻译?当前已插入翻译缺失消息。我正在使用RoR3.1。 最佳答案 找到相似的question这里是答案:#application.rb#railswillfallbacktoconfig.i18n.default_localetranslationconfig.i18n.fallbacks=true#railswillfallbacktoen,nomatterwhatissetasconfig.i18n.default_localeconfig.i18n.fallback
在我的双语Rails4应用程序中,我有一个像这样的LocalesController:classLocalesController用户可以通过此表单更改其语言环境:deflocale_switcherform_tagurl_for(:controller=>'locales',:action=>'change_locale'),:method=>'get',:id=>'locale_switcher'doselect_tag'set_locale',options_for_select(LANGUAGES,I18n.locale.to_s)end这有效。但是,目前用户无法通过URL更改
我使用Ruby编程已经有一段时间了,现在只使用Ruby的标准MRI实现,但我一直对我经常听到的其他实现感到好奇。前几天我在读有关Rubinius的文章,这是一个用Ruby编写的Ruby解释器。我试着在不同的地方查找它,但我很难弄清楚这样的东西到底是如何工作的。我在编译器或语言编写方面从来没有太多经验,但我真的很想弄明白。一门语言究竟如何才能被自己解释?编译中是否有一个我不明白这有意义的基本步骤?有人可以像我是个白痴一样向我解释这个吗(因为无论如何这都不会太离谱) 最佳答案 它比你想象的要简单。Rubinius并非100%用Ruby编
Ruby是完全面向对象的语言。在ruby中,一切都是对象,因此属于某个类。例如5属于Objectclass1.9.3p194:001>5.class=>Fixnum1.9.3p194:002>5.class.superclass=>Integer1.9.3p194:003>5.class.superclass.superclass=>Numeric1.9.3p194:005>5.class.superclass.superclass.superclass=>Object1.9.3p194:006>5.class.superclass.superclass.superclass.su
前面一篇关于智能合约翻译文讲到了,是一种计算机程序,既然是程序,那就可以使用程序语言去编写智能合约了。而若想玩区块链上的项目,大部分区块链项目都是开源的,能看得懂智能合约代码,或找出其中的漏洞,那么,学习Solidity这门高级的智能合约语言是有必要的,当然,这都得在公链``````以太坊上,毕竟国内的联盟链有些是不兼容Solidity。Solidity是一种面向对象的高级语言,用于实现智能合约。智能合约是管理以太坊状态下的账户行为的程序。Solidity是运行在以太坊(Ethereum)虚拟机(EVM)上,其语法受到了c++、python、javascript影响。Solidity是静态类型