目录
首先我们要有对指针的基本概念的理解。指针基本就可以理解为一个带数字的箭头。
1、指针就是变量,用来存放地址。
2、指针的大小固定为4/8个字节。
3、指针有类型,比如 char* 和int* 都是4个字节。但是char类型是一个字节,而int型是四个字节。
那么接下来,我们就对指针进行分类分析以及详解。
1、字符指针
char ch1 = 'w';
const char* ch2 = "abcdef";
char* p1 = &ch1;
cout << *p1///w
cout << *ch2;//abcdef
cout<<ch2;//a
在这段代码中,p1直接指向ch1,即p1就是ch1的地址。
而ch2,它是指向整个字符串的首地址,即指向’a’。
我们在这里引出一个例子:
char str1[]="abcdef";
char str2[]="abcdef";
const char *str3="abcdef";
const char *str4="abcdef";
if(str1==str2)
cout<<"str1 and str2 are same"<<"\n";
else
cout<<"str1 and str2 are not same"<<"\n";
if (str3==str4)
cout<<"str3 and str4 are same"<<"\n";
else
cout<<"str3 and str4 are not same"<<"\n";
运行结果如下图:
2、指针数组
顾名思义,当我们把这四个字拆开之后,他就是“指针的数组”,而指针数组也就是这个意思。在指针数组内,存放的都是各个指针。
int *p[10];//一个简单的数组指针定义
//例如 int (*p)[10],这样的定义就是错误的
3、数组指针
数组指针即数组的指针。指向首元素地址的指针。
int (*p)[10];//定义指针p是数组的指针
//int *p[10]此类是数组指针,注意分辨
//注意:[]的优先级是大于*号的,所以我们才要()来保证结合准确。
3.1、对于数组的 &(符号) 的讲解
int arr[10];
printf("%p\n",arr); //00000043A8CFFB58
printf("%p\n",&arr);//00000043A8CFFB58
两者输出一样
定义一个数组,数组名表示首元素地址
而 &arr 同样也是数组的首元素地址
但是实际上,&arr的意思是整个数组的地址,若让指向&arr的指针+1,那么他会跳过整个数组,但是指向arr的指针+1的话,便是第二个元素。
4、函数指针
首先我们要知道如何定义一个函数指针。
int my_add(int a, int b){} //假设函数
int (*pf)(int,int)=my_add;
//pf就是函数的指针名称,(int,int)是函数传参类型
若我们此时多定义几个函数
int my_plus(int a,int b){}
int my_div(int a,int b){}
那我们就可以用数组指针进行简化
int (*pf[3])(int,int)={my_add,my_plus,my_div};
5、对地址、内存和数组的更深理解体型详解
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//这里a代表整个数组 4(四个元素)*4(每一个元素4个字节)=16
printf("%d\n", sizeof(a + 0));//a代表首元素地址 4/8
printf("%d\n", sizeof(*a));//指针类型 就是4
printf("%d\n", sizeof(a + 1));//int元素4
printf("%d\n", sizeof(a[1]));//int元素大小4
printf("%d\n", sizeof(&a));//&arr是地址,是地址就是4/8
printf("%d\n", sizeof(*&a));//解引用之后还是a那么就是16
printf("%d\n", sizeof(&a + 1));//地址->4/8
printf("%d\n", sizeof(&a[0])); //地址->4 / 8
printf("%d\n" ,sizeof(&a[0]+1)); //地址->4 / 8
char arr[] = { 'a', 'b', 'c', 'd' ,'e' ,'f'};
printf("%d\n", sizeof( arr)) ;//char类型数据一个符号一个字节答案是6
printf("%d\n", sizeof(arr + 0)); //仍然是指向第一个元素的地址,那么就是4/8
printf("%d\n", sizeof(*arr)); //指针类型,4
printf("%d\n", sizeof(arr[1]));//第二个元素 1
printf("%d\n", sizeof(&arr)); //取地址 ,仍然是地址,4/8个字节
printf("%d\n", sizeof(&arr + 1)); //同上,4/8
printf("%d\n", sizeof(&arr[0] + 1));//同上,4/8
printf("%d\n", strlen(arr));//随机值,因为对于strlen来说是找到’/0’才会停止否则就会继续搜索
printf("%d\n", strlen(arr + 0));//仍然是随机值
printf("%d\n", strlen(*arr));//err,将a的ASCII码传入,那儿就从97开始往后统计数据,造成非法访问
printf("%d\n", strlen(arr[1]));//无法对一个元素进行长度分析
printf("%d\n", strlen(&arr)); //err
printf("%d\n", strlen(&arr + 1)); //随机值
printf("%d\n", strlen(&arr[0] + 1));//从第二项往后面搜索,仍然造成随机值