编程的本质是按照逻辑通过流程解决生活中的问题,而要正确的描述问题并使计算机读懂就要有各种各样的数据类型(整数、小数、字符、字符串......)和变量来描述问题。
一、数据类型:
1.内置类型(c语言本身就具有的):字符型、整型、浮点型()、布尔型。
2.自定义类型(自己创造的):数组、结构体-struct、枚举-enum、联合体-union.
3.字符型:char
整型:
短整型-short(int)
整型-int
长整型-long(int)
长长整形-long long(int)
5.浮点型(小数):
float-单精度浮点型
double-双精度浮点型
long double
6.布尔类型(c语言本来没有为布尔值单独设置一个类型,而是使用0表示假,非零表示真;在c99中引入了布尔类型专门表示真假。)
表示真假的变量-布尔值
_Bool(bool)
布尔类型的使用得包含头文件。 布尔类型变量的取值是:true或false。
二、各种数据类型的长度:
每一种数据类型都有各自,使用不同的数据类型能够创造长度不同的变量,变量长度决定了数据存储的范围
sizeof操作符:
sizeof既是一个关键词也是一个操作数,它专门用来计算其操作目标的类型长度,单位是字节。
sizeof的操作目标是可以是数据类型,也可以是变量或表达式。
1.sizeof (数据类型(int))/2.sizeof 表达式(可以省略括号)。
sizeof后面的表达式是不进行真实计算的,它根据表达式的数据类型得出结果。
sizeof计算的结果为size_t类型。
在c语言中只规定了sizeof运算符的返回值为无符号整数,并没有详细的规定具体的类型,而是让操作系统自己决定。所以sizeof具体返回什么类型?这在不同的系统中,返回值的类型可能是unsigned int,也可能是unsigned long或unsigned long long,对应的占位符是%u、%lu、%llu,这样不利于程序的可移植性。于是c语言提供了一个解决方案,创造了一个叫size_t的数据类型,用来统一表示sizeof的返回值类型。
三、signed与unsigned
c语言用signed和unsigned关键字修饰字符型和整型
signed关键字(有符号)表示一个类型带有正负号,包含负值(int a==signed int a)。
unsigned(无符号)只能表示0和正数(unsigned int a)。
只写int默认带有正负号(int=signed int),所以signed一般省略。
char/signed char/unsigned char:单纯只有char时并不能确定它是有符号还是无符号,它取决于编译器的实现(对于大部分编译器来说char==signed char)。
四、数据类型的取值范围
设置多种数据类型其本质是限定了不同的取值范围,有了丰富的取值范围我们就可以在相应的场景下选择合适的数据类型创建变量
lmiits.h文件中说明了整型的取值范围。
float.h文件中浮点型的取值范围。
这些数据类型的取值范围使用数学知识都有迹可循,不过多赘述。
五、变量的创建
我们一直所说的数据类型其意义就是用来创建不同类型的变量的。
创建的形式:data_type(数据类型) name(变量名)
变量在创建时要给一个初始值,这个过程叫变量的初始化。(int a = 0;)
六、变量的类型
1.全局变量:在大括号外部定义的变量叫全局变量,全局变量使用范围广,在整个项目中都可以使用。
2.局部变量:在大括号内部定义的变量叫局部变量,局部变量的使用非常局限,只能在自己所在的局部范围内使用。
值得注意的是,当局部变量与全局变量的变量名一样时,局部优先。
全局变量与局部变量在内存中储存在哪里呢?
局部变量-->栈区
全局变量-->静态区
其实内存区域的划分非常细致,学操作系统时才涉及。
七、算术操作符
c语言为方便运算,提供了一系列操作符,叫做算术操作符(+ - * / %)
由于完成加减乘除取余都需要两个操作数,所以它们也叫双目运算符。
值得注意的是利用/来完成除法运算时,如果除号两端是整数,那么执行整数除法,得到的结果也是整数(只得到商)。
如果希望得到浮点数的结果,两个操作数必须至少有一个为浮点数,这时c语言会进行浮点数除法。
求模运算符%只能用于整数不能用于浮点数。
八、赋值操作符:
关于赋值操作符(=),我们会时常看到连续的赋值(a=b=c+1),c语言虽然支持这样的赋值方法,但写的代码不容易理解,还是建议拆分(b=c+1; a=b;)。
在写代码时,有时会不得已的对一个变量进行自增或自减的操作(如:a=a+3或a=a-3),但是,我们可以换一种写法(a += 3或a -= 3),这叫复合赋值符,当然还有许多复合赋值符,暂不提及。
九、单目操作符:
只有一个操作符的叫做单目操作符(++ -- + -)。
++和--:
++和--为自增和自减操作符,分为前置和后置(a++,++a和a--,--a)。
a++表示先使用后自增1。
a先赋值给b,使b=3,后a在自增1变成4。
++a表示a先自增1后使用。
a先自增1变成4,后赋值给b。
所以,a--与--a也是同理。
十、强制类型转换:
int a = 5.20 --> int a = (int)5.20.
将5.20强制转换为整型,结果只取整数部分(这感觉是真没用啊)。
十一、printf和scanf介绍:
1.printf:
基本用法:printf()的作用是将参数文本输出到屏幕上,print(打印)+format(格式化),表示可以定制输出文本的格式。 * 占位符:printf()可以在输出文本中指定占位符,所谓占位符,即是这个位置可以被其他值替换。*
占位符列举:
1.%c:字符。
2.%f:float类型。
3.%lf:double。
4.%hd:十进制short int类型。
5.%hu:unsigned short int类型。
6.%ld:十进制long int类型。
7.%lu:unsigned long int类型。
8.%Lu:long double类型。
9.%p:指针(打印地址)。
10.%s:字符串。
11.%u:无符号整数(unsigned int)。
12.%zd:size_t类型。
13.%o:八进制整数。
14.%x:十六进制整数。
......
限定宽度:
printf()允许限定占位符的最小宽度。
%5d表示这个占位符所表示的值的宽度至少为五位,所以在5的前面补4个空格,输出的值默认为右对齐,要想为左对齐,则在%后面加上负号变成%-5d,会在5的后面补4个空格。
另外,%f与%lf在打印时,小数点后默认打印六位。
有时候也会在%后面加上正号变为%+d。
限定小数位数:
输出小数时,有时希望限定小数的位数,若保留3位小数,则写成%.3d。
当然,可以同时限定小数位数与宽度。
当然,还有一种写法,%*.f的两个可以通过printf()的两个参数25与15传入。
对于字符串的打印来说,也可以控制只打印部分字符串。
2.scanf:
printf()函数是将变量的值输出在屏幕上,而scanf()函数是在变量所在的内存空间内输入值,当程序运行到这个语句时会停下来,等待用户的键盘输入,用户输入数据并按下回车后,scanf便会处理用户的标准键盘输入并将其存入变量(scanf("%d",&a);),它的占位符与printf()基本一致,负责告诉编译器如何解读用户的输入,使scanf()提前得知用户输入的数据类型,方便处理数据。
&为取地址运算符。
可以一次性给变量输入多个值。
scanf()在处理数值占位符时,会自动过滤空白字符,包括空格、制表符、换行符等;所以在用户输入的数据间有几个空格(或使用回车)都不影响scanf()的解读。
用户输入的值先被放入指定的缓存后按下回车键,随后scanf()按照占位符对数据进行解读,解读用户输入时会从上一次解读剩下的第一个字符开始,直到遇到不符合条件的字符或读完为止。
浮点数在内存中无法精确保存。
当然,还有一种情况:
所以:
必须严格匹配。
scanf()的返回值:
1.scanf()的返回值是一个整数,表示成功读取的变量个数。
2.如果没有读取任何值或不匹配则返回0。
3.如果在读取数据之前发生读取错误或读到文件结尾,则返回EOF(-1)(EOF-->end of file)。
以下是scanf()返回值可能出现的一些情况,对应了上面的三种情况:
1.
2.
3.
了解:
占位符:
他的占位符与printf()基本一致。
特别的是:%[],在[]之中可指定一组匹配的字符,遇到不在集合之中的字符,匹配将会停止。
%c不忽略空白字符,总是返回当前第一个字符,无论该字符是否为空格。
如果要强制跳过字符前的空白字符,可以写成{scanf(" %c", &a);}(在%前加上空格,表示跳过一个或多个空白字符)。
再来说说%s:它的规则是从当前第一个非空白字符开始读起直到遇到空白字符为止。
scanf()在遇到%s占位符会在字符串变量末尾存储一个空字符\0
另外,scanf()将字符串读入字符数组时不会检查字符串是否超过了字符数组规定的长度,若超过了字符数组规定的长度则可能发生难以预料的结果。所以在使用%s占位符时,应指定读入字符串的极限长度(%[]s,[]内是一个整数,表示读取字符串的极限长度)。
赋值忽略符:
有时,用户的输入可能不符合scanf()中规定的格式。
所以,为了避免这种情况,scanf()提供了一种赋值忽略符(),只要把加在占位符%的后面,该占位符就不会返回值,解析后丢弃。
完结!