1.指针的认识和应用int val 0 char* a val; char* *b a; //指针就是取地址分指针等级 char* pa,pb; //pa是char* pb是char char* pa,*pb; //pa pb都是char* typedef; 是对变量进行重命名 // typedef char* PChar PChar pa,pb char* pa,*pb 变量名升级为类型名 #define 是同义替换//#define PCHAR char* PCHAR pa,pb char* pa,pb * --解引用(回到上一级变量) *(p1) arr[1] *(arr1)指针大小只与平台有关 x86 (win32) --4B x64(win64) --8B指针解析能力与指针类型有关2.简单定义与const结合指针指向变量变量值不能被修改const int val 0;//const所修饰的有常量不可改变 变量类型对const可忽略从右到左可以进行范围的缩小(权限缩小) const int * p a; //*p具有常性,p的指向可以改变 const可以修饰不需要改变字符串或数组 例如show函数、strcmp比较字符串不需要改变该数组用const修饰3.指针运算3.1指针 -n 的能力//指针 n 的能力 int* p; p1 -- 偏移量 1*sizeof(*p) 4B long long **q; q1 -- 偏移量 1*sizeof(*q) 4B (因为*q的类型为指针所以为4字节) *(p1) arr[1] *(arr1) 指向i*sizeof(*p)位置 所指类型不变3.2指针与--int arr[] {1,2,3,4,5,6,7,8,9,10}; int *p arr2; 开始时指向arr[2] -- 3 以下均为指针自增自减 *p -- 3 先解引用表达式的值为3 后P的指针指向加一指向arr[3] *p -- 5 p先自增后解引用 -- 5 (*p) -- 6 -- 自增操作P指向的值不变将arr[4]的值自增1 (*p) -- arr[4] arr[4]1 先解引用在自增 *--p -- arr[3]:4 --*p -- arr[3] arr[3] - 1 -- 3 偏移量解引用 char *arr[] {abc,def,ghi}; char **p arr; p;//此时p指向arr[1]; printf(%s,*p1); *p1 -- 先对P解引用 -- arr[1]再指针向后偏移一个字符位置(char)类型 *p → *(p) 取值指针后移 (*p) → 先取值值自增指针不动 *p → *(p) 指针先移再取值 *p → (*p) 取值然后值自增指针不动4.指针与数组4.1数组指针 --定义一个指针指向数组数组指针 char str[] hello\0;//6个 两种定义方式 char (*p)[6] (char(*)[6])str;//类型强转 char (*p)[6] str; p1的偏移量 1*sizeof(*p) // char[6] --直接偏移一个行数 //访问\0 str[strlen(str)]; (char*)(p1)[-1];(往前挪一个小字节类型强转)4.2指针数组 --是一个数组每个元素都是指针指针数组 const char* names[] {zs,lisi}; sizeof(names): 2*4 B char arr[] hello; //[hello] const char* str hello; //数据区常量 char brr[] hello; //[hello] const char* sub hello; //数据区常量 str sub 地址和值都相等从同一份数据区拿出来的 在常量区中相同字符串只有一份 arr 与 brr 是数组定义定义一个数组分别在main中开辟一块内存 存储abc 修改字符 -- char arr[] abc;sizeof(names): 2*4 B 其中 4 是指--指针的大小固定为4 字节5.指针与函数5.1返回值为指针不能返回局部变量地址,应该延长局部变量生存周期 static 到main函数结束储存在数据区 静态局部变量: 只被定义1次 局部变量作用完立即销毁空间 int main() { int val; //0x123 int* q fun(val); return 0; } 此时返回的是q的值保存的是val的地址在main中可以找到该地址并且可以解引用5.2形参是指针1.形参的修改要影响实参必须传地址通过解引用修改值 2.指针大小只与平台有关(固定值)可以节省空间 --不需要重新开辟新的空间 void Show(const int* arr,int len) void mystrcpy(char* sub,const char* str)5.3函数指针 --是一个指针指向一个函数int add(int a,int b){ } int mul(int a,int b){ } 函数返回值类型 (*p)(形参列表) 函数地址; 函数名: 函数入口地址 int (*p)(int,int) add; p mul; //add(1,2); p(1,2); eg: long* fun1(){ } 定义指针 指向fun1并完成函数调用 long * (*p1)() fun1; p1(); 调用 fun1函数 typedef long*(*PFun)(); PFun p1 fun1; p1();6.1void* -- 无类型指针void * p val; 无类型指针 不能1 不能解引用 崩 int * p (int*)malloc(100);6.2野指针和空指针不能解引用空指针--崩 int* p; //野指针 *p 1; --崩 所指地址不明确随机地址 地址对应值没有访问权限 int* p NULL; //0号地址空间不具有访问权限 #define NULL 0 int* p 200000; //错误 类型错误 200000 -- int int* p (int*)200000; //不建议 不安全7.mem系列函数 --头文件string.hmemcpy不用考虑内存重叠从前往后memmove考虑内存重叠先用指针比较大小从后往前memset(地址,值,字节数); 内存初始化用于快速清空数组 将一块内存区域的前 n 个字节设置为指定的值 void mymemcpy(void* arr,const void* brr,unsigned int size) { char* Arr (char*) arr; const char* Brr (const char*) brr; while (size--) { *Arr *Brr; } } void mymemmove(void* arr, const void* brr, unsigned int size) { char* Arr (char*)arr; const char* Brr (const char*)brr; if (Arr size Brr) { while (size--) { Arr Arr size -1; Brr Brr size -1; *Arr-- *Brr--; } } else mymemcpy(arr,brr,size); }8.面试题1.大小端/大小字节序 --- 数据在内存中的存储模式 小端 : 低地址存储低位数据(滴滴) int val 0x12345678; _0x78__ _0x56__ __0x34__ _0x12__ 低地址 高地址 char* p (char*)val; 类型强转只解析一个字节 if( *p 0x78) 小 else 大 大端: 与小端相反2. 数组指针 和 指针数组 1) 数组指针 -- 指针 指针1(偏移量能力) 2) 指针 数组 --- 数组 每个元素是指针 3) int arr[2]; int(*p)[2]arr; 数组指针 const char* p[] {zs,lisi}; 指针数组