目录
1:前言
有关c语言的学习,许多小伙伴们最害怕的应该莫过于指针了吧,而同时指针却也是我们笔试面试中较为常见的一类题型,那么在本篇文章,我将尽力为大家解决有关指针的问题,克服大家对指针的恐惧感。
2:关于指针
那么什么是指针呢?我们首先带大家理清一些基本概念。
1.指针就是个变量,用来存放地址,地址唯一标识一块内存空间。
2.指针的大小是固定的4/8个字节(32位平台/64位平台)。
3.指针是有类型,指针的类型决定了指针的+-整数的步长,指针解引用操作的时候的权限。
4. 指针的运算。
3.相关题目
那么我想先请大家看看下面一串代码,想想程序会输出什么样的结果。
#include <stdio.h>
int main()
{
char str1[] = "hello world.";
char str2[] = "hello world.";
char *str3 = "hello world.";
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");
return 0;
}
这里最终会输出一下结果
有的小伙伴可能会好奇为什么会输出这样的结果呢?这四个字符串的内容不是完全一致的吗?
而实际上这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域, 当几个指针指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始 化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4不同。就是说这里strcmp函数实际比较的是他们的地址。
接下来我们看点有意思的东西
关于"&数组名"与”数组名”
大家应该都很清楚的知道数组名是代表是数组首元素的地址,那么&数组名呢?
我们来看看下面的代码,他们会输出什么?
#include <stdio.h>
int main()
{
int arr[10] = {0};
printf("%p\n", arr);
printf("%p\n", &arr);
return 0;
}
直接放出结果
看起来是不是完全一致呢?接下来再看看下面这串代码。
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
printf("arr = %p\n", arr);
printf("&arr= %p\n", &arr);
printf("arr+1 = %p\n", arr+1);
printf("&arr+1= %p\n", &arr+1);
return 0;
}
输出结果如下
但实际上根据上面两串代码我们可以发现虽然arr和&arr的值是一样的,但是其所代表的意义却是截然不同的。
实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。大家可以发现数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40
有了上面的一些知识铺垫,我们再来看看下面的这串代码。
#include <stdio.h>
int main()
{
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a+0));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(a+1));
printf("%d\n",sizeof(a[1]));
printf("%d\n",sizeof(&a));
printf("%d\n",sizeof(*&a));
printf("%d\n",sizeof(&a+1));
printf("%d\n",sizeof(&a[0]));
printf("%d\n",sizeof(&a[0]+1));
return 0;
}
可以看到,这里我们首先定义了一个int的一维数组,对于接下来的几个printf,我们分别做如下解释
1.数组名a单独放在sizeof内部,计算的是整个数组的大小,4*4=16
2.a表示首元素的地址,a+0依然表示首元素地址,故输出4/8
3.a表示首元素地址,*代表对a解引用,得到第一个元素,类型为int,故输出4
4.a表示首元素的地址,a+1表示第二个元素的地址,故输出4/8
5.a[1]代表数组第二个元素,输出4
6.&a代表整个数组的地址,但也是地址,故大小为4/8
7.可理解为*和&相互抵消,实际相当于sizeof(a),输出4*4=16
8.&a+1相当于跳过了一个a数组的大小,但实际上还是一个地址,故输出4/8
9.&a[0]相当于是一个二级指针,指向数组首元素的地址,故输出4/8
10.&a[0]+1相当于二级指针跳过了一个一级指针int*的大小(4字节),本质上还是一个地址,但是不指向原数组的任何一个元素,输出4/8
本期指针的题目解析到此结束,之前也是因为期末考咕咕了很久,时隔2月再度更新,感谢大家的支持,相信我们很快会在下一篇文章见面。对于本文有任何意见也可在评论区下方提出。