C语言数据类型和变量
1.数据类型的介绍
所谓类型是指相似数据的共同特征
数据类型包括内置类型和自定义类型两种
内置类型为:
◎字符型(类型长度为1字节)
包括:char,signed char,unsigned char
PS:signed用于声明有符号整型变量。有符号整型变量可以表示正数、负数和零。它们的取值范围是从负的最大值到正的最大值signed关键字用于声明有符号整型变量,这些变量可以表示正数、负数和零。它们的取值范围是从负的最大值到正的最大值。
unsigned关键字用于声明无符号整型变量,这些变量只能表示非负数和零。它们的取值范围是从0到正的最大值。
使用signed或unsigned关键字修饰整型变量时,只是指定了变量的表示方式和取值范围,并没有直接影响变量在内存中的存储方式。存储方式由编译器决定。
整数变量申明为unsigned的好处是,同样长度的内存能表示的最大整数数值增大了一倍。
无符号整型变量使用二进制表示,而有符号整型变量使用补码表示。
◎整形
包括:
◎short(类型长度为2字节)
◎int(类型长度为4字节)
◎long(类型长度为4字节)
◎long long(类型长度为4字节)
◎浮点型
包括:
◎float(类型长度为4字节)
◎double(类型长度为8字节)
◎long double(类型长度为8字节)
◎布尔类型
C99中引入,是专门表示真假的
布尔类型的使用需包含头文件〈stdbool.h〉
布尔类型变量的取值是:true或者false
ps:在没有布尔类型前,C语言用0表示假,非零值表示真
自定义类型为:
◎数组
◎结构体-struct(数据之间互不干扰)
◎枚举-enum
◎联合体-union(后一个会覆盖前一个,如果后一个数据较小就部分覆盖)
2.数据类型的长度
使用sizeof关键字/操作符计算类型/变量/表达式的长度,单位为字节
◎sizeof后面的操作数如果不是类型,是表达式的时候,可以省略掉后边的括号
◎sizeof后面的表达式是不真实参与运算的,根据表达式的类型来得出大小
◎sizeof的计算结果是size_t类型的,size_t即专用于表示sizeof的返回值
3.sizeof和strlen的区别
strlen()计算字符数组的字符数,以'\0'为结束判断,不计算为'\0'的数组元素。
而sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示,包含'\0'所占空间。
4.sizeof中代码不计算
sizeof在代码进行编译的时候,就根据表达式的类型确定了,表达式的执行在程序运行期间才能执行,在编译期间已经将sizeof处理掉了,运行期间就不会执行表达式。
5.unsigned int里面的 int可以省略,所以上面的变量申明也可以写为unsigned a;
即int就等同于signed int
6.字符类型char也可以设置signed和unsinged
C语言规定char类型默认是否带正负号,由当前系统决定即char可能是signed char也可能是unsigned char
7.变量创建的语法:数据类型➕变量名
8.变量在创建的时候就给一个初始值,就叫初始化。
9.变量分为全局变量和局部变量
全局变量:定义在大括号外部,整个作用域
局部变量:定义在大括号内部,作用域部分
ps:当全局变量和局部变量同名时,局部变量优先使用
10.内存的三个区域:栈区,堆区,静态区
局部变量是放在内存的栈区
全局变量是放在内存的静态区
堆区是用来动态内存管理的
11.算术操作符:+ - * / %也都是双目操作符
因为要有左右两个数字才能运算,操作符也叫做运算符
ps:/的两端如果是整数,执行的是整数除法,得到的结果也是整数,只会返回整数部分,丢弃小数部分。
如果希望得到浮点数的结果,两个运算数必须至少有一个是浮点数,这时C语言就会进行浮点数除法
%表示取模运算,即两个整数相除的余数。注意:这个运算符只能作用于整数,不能作用于浮点数。
负数取模的规则是,结果的正负号是由第一个运算数的正负号决定的。
12.赋值操作符:=
在变量创建时给一个初始值叫初始化,在变量创建好后,再给一个数,这叫赋值,一个等号是赋值操作符。C语言支持连续赋值如c=b=a+3从右向左依次赋值
13.复合赋值符
加等,减等,乘等,除等,移位等
14.单目操作符(只有一个操作数)
前置++,后置++,前置--,后置--,正+负-
前置++:先+1,再使用
后置++:先使用,在+1
14.(类型)可以实现类型的强制转换
15.printf不会在结尾自动添加换行符,运行结束后,光标就停在输出结束的地方,不会自动换行。
是〈stdio.h〉这个头文件定义的库函数,记得引用头文件
16.占位符(这个位置可以用其他值带入)
printf()可以在输出文本中指定占位符
占位符的第一个字符一律为%,第二个字符是占位符的类型
int类型的整数的10进制形式打印:%d
int类型的整数的8进制形式打印:%o
int类型的整数的16进制形式打印:%x
short int类型的整数的10进制形式打印%hd
short int类型的整数的8进制形式打印:%ho
short int类型的整数的16进制形式打印:%hx
long int类型的整数的10进制形式打印:%ld
long int类型的整数的8进制形式打印:%lo
long int类型的整数的16进制形式打印:%lx
%a:十六进制浮点数,字母输出为小写
%A:十六进制浮点数,字母输出为大写
%c:字符
%s:字符串
%u:无符号整形
%f:单精度浮点型float
%lf:双精度浮点型double
%Lf:长浮点型long double
%p:地址打印/指针
%zd:size_t是sizeof的输出类型
17.printf能定制占位符的输出格式,允许限制占位符的最小宽度
printf是默认向右对齐的%5d表示这个占位符的宽度至少为5位,如果不满5位,对应的值的前面会添加空格,如果希望改成左对齐,为%-5d
对于小数,这个限定符会限制所有数字的最小显示宽度,%12f表示输出的浮点数至少要占据12位,在控制精度是,小数点也算一位,小数默认显示精度是小数点后6位。
printf里的%+d可以确保输出的数值总是带有正负号,正的还是+,负的有-号。
18.限定小数位数
输出小数时,有时希望限定小数的位数。举例来说,希望小数点后面只保留两位,占位符可以写成:%.2f
如:%6.2f表示输出的字符串最小宽度为6(包含整数部分,小数点以及小数部分),小数位数为2,前面不够补空格。
最小宽度和小数位数这两个限定值,都可以通过*代替,通过printf()的参数传入。
如:printf("%*.*f\n",6,2,0.5);
19.输出部分字符串
%s占位符用来输出字符串,默认是全部输出。如果只想输出开头部分,可以用%.[m]s指定输出的长度,其中〔m〕代表一个数字,表示所要输出的长度。
如占位符%.〔5〕s表示只输出字符串“Hello world"的前五个字符,即“Hello"。
20.scanf函数,用于读取用户的键盘输入
scanf处理数值占位符时,会自动过滤空白字符,包括空字符,制表符,换行符等,可以忽略起首的空格,所以用户输入一个或多个空格不影响解读,使用回车键分成好几行也不影响解读。
解读用户输入时,会从上一次解读遗留的第一个字符开始,直到解读完缓存,或者遇到第一个不符合条件的字符为止。
ps:scanf可以处理连续多个占位符,所以
如int x;float y;scanf("%d%f",&x,&y);也没有问题
21.scanf的返回值
scanf的返回值是一个整数,表示成功读取变量的个数。如没有读去任何项,或匹配失败,返回0。如果在成功读取任何数据之前,发生读取错误,或读取到文件结尾,返回常量EOF也就是-1
22.占位符中的特殊情况
%〔〕:在方括号中指定一组匹配的字符(如%〔0-9〕),遇到不在集合中的字符,匹配将会停止。
%c:不能忽略每一个字符,无论是不是空白字符。其他占位符都会忽略起首的空白字符。
强制跳过字符前的空白字符,可以写成scanf(" %c",&ch),即%c前面加一个空格,表示跳过一个或多个空白字符。
%s:从当前的第一个非空白字符开始读起,直到遇到空白字符(即空格,换行符,制表符等)为止。因为%s不包含空白符,所以无法用来读取多个单词,除非多个%s一起使用。
23.scanf将字符读入字符数组时,不会检测字符串是否超过了数组长度。所以,储存字符串时,很可能会超过数组的边界,导致意想不到的结果发生。为了防止这种情况的发生,使用%s占位符时,应该指定读如字符串的最长长度,即写成%〔m〕s,其中的〔m〕是一个整数,表示读取字符串的最大长度,后面的字符将被丢弃,不会有数组溢出的风险。
24.赋值忽略符:*
如:用户输入2023-01-01就会正确解读出年月日,问题是,用户可能输入其他格式如2023/01/01,这种情况下,scanf解读就会失败。
但只要加上*在任何占位符的百分号后面,改占位符就不会返回值,解析后将被丢弃。
scanf("%d%*c%d%*c%d%*c",&yuer,&month,&day)意思是,年月日中间的字符%c改为%*c就不再理会它,这个占位符没有对应的变量,解读后不返回。