目录
一:字符指针
先看一段有意思的代码
char str1[] = "hello world.";
char str2[] = "hello world.";
const char *str3 = "hello world.";
const char *str4 = "hello world.";
if(str1 ==str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if(str3 ==str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
结果
原因:
arr1和arr2创建了两个不同的数组来存放 hello world,同时,arr1和arr2存的是首元素的地址,两个h的地址不同,所以arr1和arr2不相等。
arr3和arr4为字符指针,指向同一个常量字符hello world的首元素地址
二:数组指针和指针数组
int arr1[5]={1,2,3,4,5};
int arr2[5]={1,2,3,4,5};
int arr3[5]={1,2,3,4,5};
int arr4[5]={1,2,3,4,5};
int *arr[4]={arr1,arr2,arr3,arr4};
arr1,arr2,arr3,arr4都为数组指针;arr即为指针数组,数组中都是指针
数组指针的意义
但
由此可见arr1和&arr1[0]等价,都表示数组首元素地址,且向后一位都是移动一个元素位,&arr1的地址表示整个数组,加一移动整个数组位
同理
指针数组调用其中的数组时加一走一个元素位
二维数组指针
int a[2][3]={{1,2,3},{4,5,6,}};
a即为二维数组
由此可见a+1是移动了一行的长度,从第一行移动到第二行
数组传参
一维数组传参的表现形式(三种接收方式)
void Add(int *a);//一级指针接收
void Bdd(int a[5]);//数组接收
void Cdd(int a[])//一维数组大小可省
int main() {
int arr1[5] = {1, 2, 3, 4, 5};
Add(arr1);
Bdd(arr1);
Cdd(arr1);
}
二维数组传参的接收方式
void Add(int (*arr)[3]);
int main()
{arr[2][3]={{1,2,3},{3,4,5}};
Add(arr);//传的是第一行的地址,要有数组指针接收
return 0;
}
二级指针的传递
void Add(int **pp);
int main()
{int **pp;
int *p;
int *arr[3];
Add(pp);//可传二级指针
Add(&p);//可传一级指针到地址
Add(arr);//可传一级指针数组的地址
return 0;
}
三:函数指针
int Add(int a,int b);
int main()
{int(*p)(int ,int)=Add;//==&Add
int ret=(*p)(2,3);//使用
return 0;
}
看段有意思的代码
(*(void(*)())0)();
将0强制类型转换为void(*)()的函数指针,前面在加*进行解引用,所以代码的意思是调用位于0的函数
再来一个
void(*signal(int,void(*)(int)))(int);
函数名为signal,void *(int)为函数的返回类型,int,和void (*)(int)为给signal的参数
理解上为void *(int) signal (int,void(*)(int))
如果加上typedef
typedef void(*p)(int);
p signal(int,p);
一下子就简单多了,注意:定义函数指针时名称放在*后面如(*p)