C语言是一种有类型的语言
C语言的变量必须在使用前:
1. 定义;
2. 确定类型。
C语言以后的语言的两个发展方向:
1. C++/Java更强调类型,比C语言检查类型还更加严格;
2. JavaScript、Python、PHP不看重类型,甚至不需要事先定义。
早期的语言强调类型,面向底层的语言强调类型。
1. 整数:
char、short、int、long、long long;
2. 浮点数:
float、double、long double;
3. 逻辑:
bool
5. 指针
6. 自定义类型
类型的不同体现在什么地方
- 类型名称;
- 输入输出时的格式化如:%d、%ld、%lf;
- 所表达数的范围:char< short< int< float< double;
- 内存中所占据数的大小:1个字节到16个字节;
- 内存中的表达形式:二进制数(补码)、编码。
可以运用“sizeof”给出某个变量在内存中所占据的字节数。
sizeof(int);
sizeof(i).
一个字节是8个比特。
int a;
a=6;
printf("sizeof(int)=%ld\n",sizeof(int));
printf("sizeof(a)=%ld\n",sizeof(a));
在64位下:
char是1个字节,short是2个字节,int是4个字节,long、long long、double都是8个字节。
在32位下:
char是1个字节,short是2个字节,int是4个字节,long是4个字节,long long是8个字节。
总结:char是1个字节,short是2个字节,int和long取决于编辑器,通常的意义是”1个字“,long long是8个字节。
注: sizeof是静态运算符,它的结果在编译时就决定了,所以不要在sizeof的括号里做运算,这些运算是不会做的。
sizeof(a++)运算出等于6,sizeof(a+1.0)运算出等于8。因为1.0是double所以会把等号两边都变成double加起来。
注: 叫做字长原因是寄存器一次可以处理的数据就是32bit,总线上一次可以传输的数据就是32bit。int就是表达一个寄存器的大小。
补码的意义就是拿补码和原码可以加出一个溢出的”零“。
数的范围:
对于一个字节(8位),可以表达的是:
00000000-11111111;
其中00000000——>0;
11111111~10000000——> -1~ -128;
00000001~01111111——> 1~127.
eg:
char c=255;
int i=255;
printf("c=%d,i=\n",c,i);
得到c=-1,i=255。
原因是int是4个字节,32个比特,所以255填满之后上一位仍可以保持1,但是char是8个比特,255填满了8个比特,所以为0。
相当于char看到的是“1111 1111”,但是int看到的是“00000000 00000000 00000000 11111111”。
所以:
char:1字节:-128~127;
short:2字节:-32768~32767;
int取决于编辑器(CPU),通常的意义是一个字节;-2^32~2^32-1。//减一是因为还有0要占一个位置。
long:4字节;
long long:8字节。
负的可以到-2^(n-1)~2^(n-1)-1。
Unsigned
想要不以补码的形式表述,看成纯二进制,用Unsigned。
如果一个字面想要表达自己是unsigned,可以在后面加u或者U;
255U;
用了unsigned之后,能表达正数的量扩大一倍,但是不能表达负数了,扩大范围不是设计的初衷。
用L或者l表达long。
整数越界
这一章节概念较多,所以我用了很多截图。
概念:
整数越界的解释:
255的圆:
数能输出最大数的代码:
原理: 一直加1知道越界,然后再减1,就是能输出的最大的数。
Unsigned的int最大的数是:
这是P_123大神写的代码:
#include<stdio.h>
int main()
{
unsigned int a=0;
printf("unsigned int最大的数是%u",a-1);
return 0;
}
unsigned int最大的数是4294967295
整数的输入输出
只有两种形式:int和long long;
%d:int;
%u:unsigned;
%ld:long long;
%lu:unsigned long long。
char c=-1;
int i=-1;
printf("c=%u,i=%u\n",c,i);
这里不是很听得懂:
输出结果是c=4294967295,i=4294967295,是unsigned的int所能表达的最大的数。当把所有小于int的变量传给printf的时候,编译器会把这些变量转换成int传进去。
8进制和16进制
一个以0开头的数字字面量是8进制;
一个以0x开头的数字字面量是16进制。
char c=012;
int i=0x12;
printf("c=%d,i=%d\n",c,i)//以%输出是想看十进制
结果是c=10,i=18。
想要输出8进制用%o,想要输出16进制用%x,但是想要输出0和0x就需要:
printf("c=0%o,i=0x%x\n",c,i)
这里,如果:
char c=012;
int i=0x1A;
printf("c=0%o,i=0x%x\n",c,i)
小写的x输出小写的a:0x1a;
大写的X输出大写的A:0x1A。
char c=012;
int i=0x1A;
printf("c=0%o,i=0x%X\n",c,i)
注: 8进制和16进制只是如何表达字符串,与内部如何表达数字无关,内部永远是2进制,只是如果写的8进制或者16进制它先转换为2进制再处理。
8进制和16进制
0001 0010
| |
1 2 ——>char
早年习惯用8进制,现在习惯用16进制。
选择整数的类型
如果不是迫不得已,没必要用unsigned,老师也不建议用short、char等。
浮点类型
有效范围
inf是无穷大的意思。nan表达有效数字,可以用浮点表达不是一个有效数字的值。有效数字是7是指,第7个数字是有效的,第8个数字是不准确的。
浮点的输入输出
float的输出%e是输出科学计数法,而%E则输出大写E。
但比如:
printf("%E,%.16f\n",ff,ff)
可以在小数点后输出16位数字。
输出精度
eg:
浮点数的误差
计算机能表达的数是离散的。double所能表达的相邻两个数之间的距离比float要小,所以它能表达更多的数。
浮点的范围与精度
printf("%f\n",12.0/0.0);
printf("%f\n",-12.0/0.0);
printf("%f\n",0.0/0.0);
得到inf,-inf,nan。
但是如果:
printf("%d\n",12/0);
是不能运行的,因为整数不能除以0,因为无穷不能用浮点数表示。
浮点运算的精度
注:
- 带小数点的字面量是double而非float,float需要用f或者F后缀来表明身份。
- 判断浮点数是否相等不能f1==f2来判断,应该求差的绝对值是否小于某一个很小的数,一般是有效数字:fabs(f1-f2)<1 e-12。1 e-8就可以了,-12为了更保险。
- 一般来说尽量用整数来做运算,因为带小数点的数只有在一定范围是精确的。比如1.23元不要用小数点算,换算成分123分做运算是精确的。
浮点数的内部表达
不一定是图上的52比特,因为不一定64个全用完。
选择浮点类型
整数只选int,浮点只选double。
字符类型
char是character前4个字母而来的。
带单引号的是字符,不带单引号的是数字。
每一个字符在计算机内部都有一个数字来表示。
字符的输入输出
输入:1,得到:c=49,c=’1’
字符的输入输出
混合输入——有没有空格的区别
%c是从输入里读出字符来。
如果%d后面没有空格,意思是只读到空格结束为止。
字符计算:
char c='A';
c++;
printf("%c\n",c);
结果是:B
注:
1. 一个字符加一个数字得到ASCII码表中那个数之后的字符;
2. 两个字符的减,得到它们的距离。
逃逸字符
逃逸字符有哪些?
解释输出结果的不同
\b做的事情是回到上一个输出的位置。如果之后没有其他的输出,那就看不出结果,如果有其他的输出,就会替换掉最后一个字符。
输出:
12A
456
\t
table的位置是行当中固定的位置,而不是固定大小的字符数量(或者说距离)。
起源于打印机,所以换行\n和回车\r是两个动作。
但是shell会把\n翻译成回车和换行两个动作。
类型转换
所以在printf时用%f就足以输出double不需要%lf,因为不论是float还是double,在传给printf时都已经变成double了;
但是在scanf时不行,因为它要明确后面那个变量的大小,比如要输出short要用%hd,int用%d,long long用%ld,但是如果要输入char必须先输入一个整数然后交给char的类型。
做的只是计算出一个新的量,而不是改变i。
bool类型
#include< stdbool.h >
之后就可以使用bool和true和false。
但是printf无法输出true和false只能输出bool的值。
逻辑运算
不能那么写是因为会先判断x是不是大于4,得到1或0,然后判断1或0是不是小于6,但是肯定小于6的,所以这个式子的结果怎么都是1。
要写:x>4 && x<6。
如何判断一个字符c是否是大写字母?
c>=’A’ && c<=’Z’
理解一下
- age在20到30之间;
- index不在0到99之间;
- 因为!是单目运算符,优先级高于双目运算符,所以会先算!age,age不是1就是0,那么相反,也不是1就是0,都小于20,输出结果为1。
!(age<20)就是age>=20。
优先级
短路
注: 不要把赋值包括复合赋值写进表达式!
因为有的逻辑符号左边不对,右边就不会做了。
条件运算符
优先级
最好不要使用嵌套的条件表达式。
逗号运算符
逗号的优先级最低。
作用: 主要是在for当中使用。
最后说句无关的:
虽然在学习电脑,但是还是希望柯洁能赢!