目录
signed int//-2147483648~2147483647
调试技巧
调试实例
#include <stdio.h>
int main()
{
int i = 0;
int arr[10] = {0};
for(i=0; i<=12; i++)
{
arr[i] = 0;
printf("hehe\n");
}
return 0;
}
我第一眼看到这个代码的反应是 越界了!跑不了吧!
实际上,可以跑,而且一直跑。(死循环)
分析:在vs编译器中,变量i和arr数组在内存中存储的时候,隔着8个字节,就是2个int类型。 当i=10,11,12时,数组越界访问了,会把i的地址的内容变成0。 又开始重新从arr[0]开始循环。
注意:不同的编译器中,变量间存储隔着的空间不一样,上述代码在gcc中就隔着一个整形,这意味着,如果想让代码死循环,可以将for循环中的条件改为i<=11。
以上代码中,变量是存储在栈区的,栈区是从高地址向低地址增长,数组随着下标的增长,从低地址向高地址处增长。
高地址————————————————————————————————————
i
0xcc cc cc cc
0xcc cc cc cc
arr[9]
...
arr[1]
arr[0]
低地址————————————————————————————————————
关于assert
aeert在 release版本,就被优化掉了。只在debug中起作用。
建议在程序里对指针判空时,使用assert。
头文件为<assert.h>
数据基本类型
整型类型的取值范围在limits.h头文件中。
浮点数类型的取值范围在float.h头文件中。
char //字符数据类型 1字节
short //短整型 2字节
int //整形 4字节
long //长整型 4/8字节
long long //更长的整形 8字节
float //单精度浮点数 4字节
double //双精度浮点数 8字节
long double//大于double
注:long的定义是比int大的都算long,所以有些平台是4字节,有些平台是8字节。为避免争议,可以直接用long long。
整形家族
分类
char
分成3类,①char,②signed char,③unsigned char。
①char取决于编译器,可能是无符号或者有符号
short
分成2类,①unsigned short,②signed short。
写成short,表示的是②有符号short,两者完全等价。
int
分成2类,①unsigned int,②signed int。
写成int,表示的是②有符号int,两者完全等价。
long
分成2类,①unsigned long,②signed long。
写成long,表示的是②有符号long,两者完全等价。
存储方式
三种:原码、反码、补码。在内存中存储的是补码
正整数的原反补相同,最高位符号位为0;
负整数 原码--符号位不变,其余按位取反得到反码--+1得到补码,最高位符号位为1;
原码到补码
原码取反,+1得到补码
补码到原码 2种方式 1、补码-1,再取反,得到原码 2、补码取反,+1,得到原码
大小端
内存中最小单位是一个字节。当1个数值超过1个字节了,要存储到内存中,就有顺序问题。
大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址 中; 小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地 址中。
浮点数家族
float
double
构造类型/自定义类型
数组类型
结构体类型 struct
枚举类型 enum
联合类型 union
指针类型 *
空类型 void
void* p = NULL;
只能往里面存放,当作一个临时存储变量。不能进行解引用或者算数运算。 (因为不知道指针所指向类型,无法决定要往后走几步)
在使用前,要先强制转换成具体类型的指针。
数据存储进阶
char/signed char//-128~127
00000000//0
00000001//1
...
01111111//127
10000000//-128
10000001//-127
...
11111110//-2
11111111//-1
关于-128的转换。10000000规定死了,就是128
10000000//-128
1 1000 0000//-128原码
1 0111 1111//-128反码
1 1000 0000//-128补码
unsigned char//0~255
00000000//0
00000001//1
...
01111111//127
10000000//128
10000001//129
...
11111110//254
11111111//255
signed short//-32768~32767
00000000 00000000//0
00000000 00000001//1
...
01111111 11111111//32767
10000000 00000000//-32768
10000000 00000001//-32767
...
11111111 11111110//-2
11111111 11111111//-1
unsigned short//0~65535
signed int//-2147483648~2147483647
unsigned int//0~4,294,967,295
%u是打印无符号整型,系统会认为内存中存放的补码对应的是一个无符号数
%d是打印有符号整型,系统会认为内存中存放的补码对应的是一个有符号数