一、大小端
大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。
小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。
一般为小端储存模式。
(字节序:0x 00 00 00 01 -0x01低位 0x00高位)
二、字节对齐
不同系统c语言类型长度
好处:
1.cpu快速访问
2.节省储存空间
*例:32位机,4字节对齐,long类型变量(起始位于四字节边界,cpu只需读一次,否则要读两次)
三、数组指针与指针数组
1.指针数组 int* p[n];
[ ]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1时,则p指向下一个数组元素,这样赋值是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]…p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 p=a; 这里p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
p++; //该语句表示p数组指向下一个数组元素。
for(i=0;i<3;i++)
p[i]=a[i]
这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
所以要分别赋值。
2.数组指针 int (*p)[n]
( )优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。
如要将二维数组赋给一指针,应这样赋值:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
p=a; //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
p++; //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]
所以数组指针也称指向一维数组的指针,亦称行指针。
数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。
四、main函数参数问题
(int argc , char* argv[ ])
从系统操作命令上获得。
命令行可执行文件一般形式:可执行文件名 参数 参数 ······
当我们要运行一个可执行文件时,在命令行键入文件名,再输入实际参数即可把实参传入main的形参中。
argc:命令行中参数个数(文件名本身算一个)
值是在输入命令行时由系统按实际参数个数自动赋予的
argv:字符串指针数组,各元素值为命令行中各字符串(参数均按字符串处理)首地址,数组长度为参数个数。
五、指针强制类型转换
地址都是int型,不同的是指针在内存中每次移动的字节数。
六、静态本地变量static
1,static局部变量
普通局部变量存储于进程栈空间,使用完毕会立即释放。但是有static关键字的局部变量,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。
2.static全局变量
全局变量定义在函数体外部,在全局数据区分配存储空间,且编译器会自动对其初始化。普通全局变量对整个工程可见,其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了(否则编译器会认为它们是同一个变量)。
七、宏与typedef区别
宏只是简单的替换, 而typedef可以看成是彻底的"封装"
例:#define X int*
X a, b;
只有a是指针
typedef int* X
X a, b;
a, b都是指针
八、printf和scanf返回值
输入输出的字符个数。
九、strlen和sizeof区别
strlen不算\0,而sizeof算。
十、关于数组
- 对于一维数组,1[array] == array[1]
对于二维数组,array[i][j] == (i)[array][j] - a:数组首元素首地址(a[0]首地址)
- a+1:下一个元素首地址(a[1]首地址)
- &a:整个数组首地址
- &a+1:偏移整个数组的大小
- a[0]:一维a[0]首元素地址
- a[0]+1:偏移了一个int(+4)
- &a[0]:二维数组a[0][ ]首地址
- &a[0]+1:偏移了一行