一,运算符优先级
- 括号第一,单目第二,乘除第三,加减第四,位移第五,关系第六,等于不等于第七,位与异或位或八九十,逻辑或和与十二十一,条件高于赋值,逗号运算最低。
二,数组地址分析
- 举例:
int arr[5] = {1};
arr:0x0000
&arr[0]:0x0000
&arr:0x0000
arr+1:0x0004
&arr[0]+1:0x0004
&arr+1:0x0014 - 说明
arr数组名
&arr[0]:数组元素的首地址
三,数组定义及初始化
- 数组需定义并初始化,不能先定义后初始化
int arr[5];
arr[4] = {1}; //未声明,若赋值则arr[4] = 1;
arr[5] = {1,2,5};//数组越界并且未声明
- 数组初始化
int arr[5] = {1};
int arr[4] = {1,2,3,4};
int arr[3] = {[1] = 2}; //不建议
int buf[ ] = {1,2,3,4}; //不建议
int buf[ ] = {}; //ERROR
四,指针表示形式及初始化
- 表示形式
int *p; int* p; //内核代码里见的多 int * p;
- 指针初始化
int *p = NULL; //OK,NULL空地址,是一个宏
int a = 3;
int *p = &a; //OK
int a = 3;
int *p;
p = &a; //OK
int *p;
*p = &a; //ERROR
五,地址间接取值并对其运算
- 间接运算
int *p = NULL;
printf("p = %p\n", p); //输出 p = (nil)
printf("*p = %d", *p); //ERROR,空地址不能访问里面的值
int *p = 10; //不能将常量直接赋值给指针
printf("p = %p\n", p); //输出0xa
printf("*p = %d\n", *p); //内存中并未分派0xa这块内存
int a = 3;
int *pa = &a;
int *pc = pa; //同类型指针可以直接转换
char *pd = (char *)pa; //不强制转换会有警告
六,指针的类型和指针所指向的类型
- 指针的类型:去掉变量名之后的部分
- 指针所指向的类型:去掉变量名及其前面的*
- 指针大小:64位机大小为8,32位机大小为4
七,数组和指针
1,数组元素访问形式
int arr[5] = {1,2,3,4,5};
int *pa = arr;
arr[0];
*(arr);
*(pa);
pa[0];
2,野指针
- 没有初始化,或者其指向的内存被释放,而指针没有被置空
int *p; *p +=10; //直接使用会出错
- 危害:造成系统资源浪费,容易曹诚位置的知名错误
3,指针地址运算
- 自增:指针向高地址方向移动
- 自减:指针向低地址方向移动
- 指针相减表示指针之间的距离,相加没有意义
- 指针加减一个常量,表示地址向高字节或低地址方向移动
4,概念区分
int buf[3]; //数组,其大小为3,存放三个int常量 int *pb; //指针,其类型为int *型 int *arr[3]; //指针数组 int (*pa)[3]; //数组指针,又称行指针