在这里,我将介绍一下C语言中的数据类型和操作符;
数据类型如图:

在这里我们主要讲内置类型,其中包括了字符型,整型,浮点型和布尔类型
字符的英⽂单词是 character ,在C语⾔中使⽤ char 表⽰字符类型

整数的英⽂单词是 integer ,在C语⾔中使⽤ int 表⽰整型类型

长,短,更长整型中,int可以省略
long; short; longlong;
浮点型,小数的就是浮点型(float),又分为单精度浮点型(float)和双精度浮点型(double).
精度要求不高,可以用float,反之double
float
double
long double
C 语⾔原来并没有为布尔值单独设置⼀个类型,⽽是使⽤整数 0 表⽰假,⾮零值表⽰真。
在 C99 中也引⼊了 布尔类型 ,是专⻔表⽰真假的
_Bool
布尔类型的使⽤得包含头⽂件 <stdbool.h>
布尔类型变量的取值是: true 或者 false

原始是_Bool,但是为了方便,后面规定了
bool 也可以:

每⼀种数据类型都有⾃⼰的⻓度,使⽤不同的数据类型,能够创建出⻓度不同的变量,变量⻓度的不同,存储的数据范围就有所差异。
sizeof 是⼀个关键字,也是操作符,专⻔是⽤来计算 sizeof 的操作符数的类型⻓度的,单位是
字节
sizeof( 类型 )
sizeof 表达式

sizeof计算的值如果要打印,应该用%zd格式,如图,计算了a这个整型类型的长度,和a的大小无关。
需要注意:
sizeof 在代码进⾏编译的时候,就根据表达式的结果的类型,推到并确定了类型的⻓度,
⽽表达式 真要被执⾏,却要在程序运⾏期间才会发⽣,如果在编译期间已经将 sizeof
处理掉了,所以在运⾏ 期间就不会执⾏表达式了。
sizeof 的操作数如果不(int),是表达式(3+5)的时候,可以省略掉后边的括号的
(省略后可能会降低代码可读性,并且改变原意义)
例子:
sizeof(3+5);
sizeof 3+5;
sizeof 后边的表达式是不真实参与运算的,根据表达式的类型来得出⼤⼩。
sizeof 的计算结果是 size_t 类型的。
sizeof 操作符的操作数可以(int),也变量(x)或者表达式(3+5)
根据sizeof的用处,我们可以这样,获取各数据类型的长度:

注:编译器不同,测出的长度可能也不同,比如在VS中long double是8,而在gcc上是16,
并且C语言标准规定 sizeof(long)>=sizeof(int)
这是数据类型大小的图,供参考:

C语言中用unsigned和signed这两个关键字来修饰整型和字符型类型
unsigned关键字,表示这个类型不带有正负号,只能表示0和正整数
signed关键字,表示这个类型带有正负号,包含负值
int 类型默认包含负值,所以int等价于signed int,所以因为这个,signed可以省略,但写了也是对的。当然,为了使int不带有正负号,只表示非负整数,这时候就必须使用关键字unsigned来声明变量
值得注意:
整数变量声明为 unsigned 的好处是,同样⻓度的内存能够表⽰的最⼤整数值,增⼤了⼀倍
unsigned int ⾥⾯的 int 可以省略,创建变量可以这样写:unsigned a;
上述的数据类型很多,尤其数整型类型就有short、int、long、long long 四种,为什么呢?
其实每⼀种数据类型有⾃⼰的取值范围,也就是存储的数值的最⼤值和最⼩值的区间,有了丰富的
类型,我们可以根据大小适当选择类型。如果要查看当前系统上不同数据类型的极限值:
limits.h ⽂件中说明了整型类型的取值范围。
float.h 这个头⽂件中说明浮点型类型的取值范围。
为了代码的可移植性,需要知道某种整数类型的极限值时,应该尽量使⽤这些常量。
•
SCHAR_MIN , SCHAR_MAX :signed char 的最⼩值和最⼤值。
•
SHRT_MIN , SHRT_MAX :short 的最⼩值和最⼤值。
•
INT_MIN , INT_MAX :int 的最⼩值和最⼤值。
•
LONG_MIN , LONG_MAX :long 的最⼩值和最⼤值。
•
LLONG_MIN , LLONG_MAX :long long 的最⼩值和最⼤值。
•
UCHAR_MAX :unsigned char 的最⼤值。
•
USHRT_MAX :unsigned short 的最⼤值。
•
UINT_MAX :unsigned int 的最⼤值。
•
ULONG_MAX :unsigned long 的最⼤值。
•
ULLONG_MAX :unsigned long long 的最⼤值。
以上数据类型,是用来创建变量的。
C语言中把经常变化的值称为变量,不变的值称为常量
变量创建的形式:
数据类型(空格)变量名; 例如: int a; double b;
变量创建的规则:
•
只能由字⺟大小写、数字和下划线 _ 组成
•
不能以数字开头
•
⻓度不能超过63个字符
•
变量名区分大小写
•
变量名不能使⽤关键字
变量在创建的时候就给他一个值,这叫做初始化
int age = 18;
char ch = 'w';
double weight = 48.0;
unsigned int height = 100;
变量分为全局变量和局部变量;
•
全局变量:在⼤括号外部定义的变量就是全局变量
全局变量的使⽤范围更⼴,整个⼯程中想使⽤,都是有办法使⽤的。
•
局部变量:在⼤括号内部定义的变量就是局部变量
局部变量的使⽤范围是⽐较局限,只能在⾃⼰所在的局部范围内使⽤的

如果局部变量和全局变量名字相同,优先使用局部变量
全局变量和局部变量在内存在储存在哪?
我们一般关注这三个区域:栈区,静态区,堆区;
1. 局部变量是放在内存的栈区
2. 全局变量是放在内存的静态区
3. 堆区是⽤来动态内存管理的

其实内存远比这复杂,但我们目前只需要知道三个区域
在写代码时,会涉及运算,C语言中就有算术操作符,分别是+ ,- ,* , / , %
这些也被称为双目操作符 注:操作符也被叫做:运算符,是不同的翻译,意思是⼀样的。
很简单,就是用来完成加减法的,举个例子:
int x = 5 + 4;
int y = 9 - 4;
+ 和 - 都是有2个操作数的,位于操作符两端的就是它们的操作数,这种操作符也叫双⽬操作符。
/ 是用来完成除法,* 是用来完成乘法,例子:
int x = 6*4;
int y = 12/3;
除号两端若是整数,那么执行整数除法,得到的结果是整数,但是如果除出来的结果是带有小数的,比如1.9,那么得到的结果是1,因为是整数除法,只得到整数部分,舍弃小数部分
如果希望得到浮点数的结果,两个运算数必须⾄少有⼀个浮点数,这时 C 语⾔就会进⾏浮点数除法
运算符 % 表⽰求模(余)运算,即返回两个整数相除的余值。这个运算符只能⽤于整数,不能⽤于浮点数。
负数求模的规则是,结果的正负号由第⼀个运算数的正负号决定。
例如:

在变量创建的时候给⼀个初始值叫初始化,在变量创建好后,再给⼀个值,这叫赋值。
例如:

赋值操作符 = 是⼀个随时可以给变量赋值的操作符。
赋值操作符也可以连续赋值,如:

C语⾔虽然⽀持这种连续赋值,但是写出的代码不容易理解,建议还是拆开来写,这样⽅便观察代码的
执⾏细节。
在写代码时,我们经常可能对⼀个数进⾏⾃增、⾃减的操作,如下代码:
int a = 10;
a = a+3;
a = a-2;
这样代码C语⾔给提供了更加⽅便的写法:
int a = 10;
a += 3;
a -= 2;
类似这种赋值符还有:
+= -=
*= /= %=
(下面这部分后面会学到)
>>= <<=
&= |= ^=
C语⾔中还有⼀些操作符只有⼀个操作数,被称为单⽬操作符。 ++、--、+(正)、-(负) 就是单⽬操作符
++是⼀种⾃增的操作符,⼜分为前置++和后置++,--是⼀种⾃减的操作符,也分为前置--和后置--‘’

注:先+1,后使⽤
同理,后置++就是放在a后面,先使用,后++;
也是一样的道理,前置先-1,后使用,后置先使用,后-1(优先级问题)
这⾥的+是正号,-是负号,都是单⽬操作符。
运算符 + 对正负值没有影响,是⼀个完全可以省略的运算符,但是写了也不会报错。
运算符 - ⽤来改变⼀个值的正负号,负数的前⾯加上 - 就会得到正数,正数的前⾯加上 - 会得到负
数。
很简单,就是强制把一个类型(比如double)转换为另一个类型(比如int)
int a = 3.14;
//a的是int类型, 3.14是double类型,两边的类型不⼀致,编译器会报警告
int a = (int)3.14;
//意思是将3.14强制类型转换为int类型,这种强制类型转换只取整数部分
俗话说,强扭的⽠不甜,我们使⽤强制类型转换都是万不得已的时候使⽤,如果不需要强制类型转化 就能实现代码,这样⾃然更好的。
首先,scanf和printf都需要包含stdio.h头文件
printf() 的作⽤是将参数⽂本输出到屏幕。它名字⾥⾯的 f 代表 format (格式化),表⽰可以
定制输出⽂本的格式。
printf() 不会在⾏尾⾃动添加换⾏符,运⾏结束后,光标就停留在输出结束的地⽅,不会⾃动换
⾏。
为了让光标移到下⼀⾏的开头,可以在输出⽂本的结尾,添加⼀个换⾏符 \n 。

占位符就是上图的%d,%s,所谓“占位符”,意思是它可被其他值代入(比如 %s 后面的 张三)
占位符的第一个字符一律为百分号 % ,第二个字符表示占位符的类型,比如%d表示这个占位符需要用整型代替
输出文本中可使用多个占位符,如上图的两句话,可以合在一起:

以下是占位符的列举:
%a :⼗六进制浮点数,字⺟输出为⼩写。
•
%A :⼗六进制浮点数,字⺟输出为⼤写。
•
%c :字符。//char
•
%d :⼗进制整数(有符号的10进制整数)。// int
•
%e :使⽤科学计数法的浮点数,指数部分的 e 为⼩写。
•
%E :使⽤科学计数法的浮点数,指数部分的 E 为⼤写。
•
%i :整数,基本等同于 %d 。
•
%f :⼩数(包含 float 类型和 double 类型)。//float %f double - %lf
•
%g :6个有效数字的浮点数。整数部分⼀旦超过6位,就会⾃动转为科学计数法,指数部分的 e
为⼩写。
•
%G :等同于 %g ,唯⼀的区别是指数部分的 E 为⼤写。
•
%hd :⼗进制 short int 类型。
•
%ho :⼋进制 short int 类型。
•
%hx :⼗六进制 short int 类型。
•
%hu :unsigned short int 类型。
•
%ld :⼗进制 long int 类型。
•
%lo :⼋进制 long int 类型。
•
%lx :⼗六进制 long int 类型。
•
%lu :unsigned long int 类型。
•
%lld :⼗进制 long long int 类型。
•
%lld :⼋进制 long long int 类型。
•
%llx :⼗六进制 long long int 类型。
•
%llu :unsigned long long int 类型。
•
%Le :科学计数法表⽰的 long double 类型浮点数。
•
%Lf :long double 类型浮点数。
•
%n :已输出的字符串数量。该占位符本⾝不输出,只将值存储在指定变量之中。
•
%o :⼋进制整数。
•
%p :指针(⽤来打印地址)。
•
%s :字符串。
•
%u :⽆符号整数(unsigned int)。
•
%x :⼗六进制整数。
•
%zd : size_t 类型。
•
%% :输出⼀个百分号。
此外,printf允许限定占位符的最小宽度:
如%5d表示这个占位符的宽度最小为5位,如果输出位数大于或者等于5没事,但是如果小于5位数,在其前面就需要用空格填充至5位数的宽度,输出的值默认是右对齐,想改为左对齐,则需要在5前面加个 - :
%-5d

图中%-5d的左对齐由于右边没参照物不好观察,但需要知道,会填充空格,我用鼠标选中了%-5d进行填充的空格
这种限制有许多:
%+d:原本%d默认有正号,所以没打印在屏幕上,而%+d的输出会自动添加上正号
%.2f: f前面加 .2 ,则会限制小数位数为2位,2可随意改,限制的位数也随之不同,(浮点数输出6位小数),f 也可以换成别的浮点数,比如ld
%6.2f:限制小数位数和最小宽度的结合,同理,然后,
最⼩宽度和⼩数位数这两个限定值,都可以⽤ * 代替,通过 printf() 的参数传⼊:
printf("%*.*f\n", 6, 2, 0.5); // 等同于printf("%6.2f\n", 0.5);
%.[m]s: 输出字符串中的前m个长度:
printf("%.5s\n", "hello world"); //输出前5个字符,即hello
当我们有了变量,我们需要给变量输⼊值就可以使⽤ scanf 函数,如果需要将变量的值输出在屏幕上 的时候可以使⽤ prinf 函数,下⾯看⼀个例⼦:

注:标准输⼊⼀般指的就是键盘,标准输出⼀般指的就是屏幕
scanf() 函数⽤于读取⽤⼾的键盘输⼊
程序运⾏到这个语句时,会停下来,等待⽤⼾从键盘输⼊
⽤⼾输⼊数据、按下回⻋键后, scanf() 就会处理⽤⼾的输⼊,将其存⼊变量
它的原型定义在头⽂件 stdio.h
scanf() 的语法跟 printf() 类似
int i = 0; //初始化
scanf("%d", &i); //赋值
同样,scanf和printf一样,需要占位符。 不同的是后面的变量 i 前要加 & 符号,因为传递的不是值,而是地址,即将变量 i 的地址指向⽤⼾输⼊的值。
如果这⾥的变量是指针变量(⽐如字符串变量),那就不⽤加 & 运算符。
scanf("%d%d%f%f", &i, &j, &x, &y); //可以进行多组输入
scanf() 处理数值占位符时,会⾃动过滤空⽩字符,包括空格、制表符、换⾏符等。
所以,⽤⼾输⼊的数据之间,有⼀个或多个空格不影响 scanf() 解读数据。另外,⽤⼾使⽤回⻋
键,将输⼊分成⼏⾏,也不影响解读。
scanf() 处理⽤⼾输⼊的原理是,⽤⼾的输⼊先放⼊缓存,等到按下回⻋键后,按照占位符对缓存
进⾏解读 ,解读⽤⼾输⼊时,会从上⼀次解读遗留的第⼀个字符开始,直到读完缓存,或者遇到
第⼀个不符合条件的字符为⽌。
举个例子:

上⾯⽰例中, scanf() 读取⽤⼾输⼊时, %d 占位符会忽略起⾸的空格,从 - 处开始获取数据,读
取到 -13 停下来,因为后⾯的 . 不属于整数的有效字符。这就是说,占位符 %d 会读到 -13 。
第⼆次调⽤ scanf() 时,就会从上⼀次停⽌解读的地⽅,继续往下读取。这⼀次读取的⾸字符
是 . ,由于对应的占位符是 %f ,会读取到 .45e12 ,这是采⽤科学计数法的浮点数格式。后⾯的
# 不属于浮点数的有效字符,所以会停在这⾥。
scanf() 的返回值是⼀个整数,表⽰成功读取的变量个数
如果没有读取任何项,或者匹配失败,则返回 0
如果在成功读取任何数据之前,发⽣了读取错误或者遇到读取到⽂件结尾,则返回常量 EOF (-1)
EOF - end of file ⽂件结束标志
scanf的占位符和printf基本相同,下面补充:
%[ ] :在⽅括号中指定⼀组匹配的字符(⽐如 %[0-9] ),遇到不在集合之中的字符,匹配将会停止
上⾯所有占位符之中,除了 %c 以外,都会⾃动忽略起⾸的空⽩字符。 %c 不忽略空⽩字符,总是返回当前第⼀个字符,⽆论该字符是否为空格。
如果要强制跳过字符前的空⽩字符,可以写成 scanf(" %c", &ch) ,即 %c 前加上⼀个空格,表
⽰跳过零个或多个空⽩字符。
下⾯要特别说⼀下占位符 %s ,它其实不能简单地等同于字符串。它的规则是,从当前第⼀个⾮空⽩字符开始读起,直到遇到空⽩字符(即空格、换⾏符、制表符等)为⽌。
因为 %s 不会包含空⽩字符,所以⽆法⽤来读取多个单词,除⾮多个 %s ⼀起使⽤。这也意味着,
scanf() 不适合读取可能包含空格的字符串,⽐如书名或歌曲名。另外, scanf() 遇到 %s 占位
符,会在字符串变量末尾存储⼀个空字符 \0
scanf() 将字符串读⼊字符数组时,不会检测字符串是否超过了数组⻓度。所以,储存字符串时
很可能会超过数组的边界,导致预想不到的结果。为了防⽌这种情况,使⽤ %s 占位符时,应该指
定读⼊字符串的最⻓度,即写成 %[m]s ,其中的 [m] 是⼀个整数,表⽰读取字符串的最⼤⻓度,后⾯的字符将被丢弃
如果有误,欢迎指正,请点个小小的赞吧b( ̄▽ ̄)d