优快云话题挑战赛第2期
参赛话题:学习笔记
本人0基础开始学编程,我能学会的,你也一定可以,学会多少写多少。
下载安装请从官网入手,社区版本即可,这里主要使用的软件是VS2019,图标如下。
上一篇:从0开始学c语言-20-指针与地址、指针类型、野指针、指针运算_阿秋的阿秋不是阿秋的博客-优快云博客
接下来的阅读若有不懂的地方,那一定是之前的没学好,这里先给上链接。
数组相关内容:从0开始学c语言-15-一维数组与二维数组的创建、初始化以及在内存中的储存、数组越界和数组作为函数参数_阿秋的阿秋不是阿秋的博客-优快云博客
从0开始学c语言-15-数组作为函数参数的地址、值与类型变化深度解析_阿秋的阿秋不是阿秋的博客-优快云博客
指针相关内容
从0开始学c语言-20-指针与地址、指针类型、野指针、指针运算_阿秋的阿秋不是阿秋的博客-优快云博客
目录
1·指针和数组
上次我们学到的关于指针的结论:指针就是有指向性的地址,地址在运用的时候便有了指向性,变为指针。
我们又知道数组名就是首元素的地址,那么也就是说我们在运用数组名的时候,数组名就会变为指针。
数组名不表示数组首元素地址的时候,有两个例外,
1、sizeof(数组名) 中的数组名代表整个数组,计算的是整个数组的大小,单位是字节(函数调用中的sizeof(数组名)中的数组名只包含首元素的大小)
2、&数组名 中的数组名代表整个数组,取出整个数组的地址
为了进一步验证我们说的指针结论,接下来写这段代码来看看
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = arr;
int i = 0;
for (i = 0; i < 10; i++)
{
printf("&arr[%d]=%p <=> arr+%d=%p <=> p+%d=%p\n", i, &arr[i], i, arr + i, i, p + i);
}
return 0;
}
似乎这段代码只是验证了数组名的确是首元素地址。(但是要记住表达数组中地址的几个写法)
也就是说下标为i 的时候,&arr[i] = arr+i = p+i (这三个都是指针,你信不信?)
不信你就来瞅瞅,(先知道*(&arr[i])=arr[i])
换个代码来看看,通过地址(指针)来改变数组内的值。
print(int* arr)
{
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ",*(arr + i));
//传过来后arr的类型是int*
//所以需要解引用访问
}
printf("\n");
}
int main()
{
int arr[10] = { 0 };
int* p = arr; //指针存放数组首元素的地址
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i)=i;
}
print(arr);
for (i = 0; i < 10; i++)
{
*(arr + i) = 0;
}
print(arr);
for (i = 0; i < 10; i++)
{
arr[i] = 6;
}
print(arr);
return 0;
}
可以看到我们的确做到了改变数组内的值。
补充:
所以,2[arr]=arr[2]
[ ]是一个操作符,2和arr是两个操作数,
比如,+操作符,a+b=b+a
那么2[arr]=arr[2] 同理
同时我们也看到了*(2+arr)=2[arr]=*(2+p)
那么也可以推出来*(2+p)=[2]p=p[2]
2·二级指针
int main()
{
int a = 0;
int* p = &a;
int** pp = &p;
return 0;
}
名称 | 值 | 类型 | |
---|---|---|---|
a | 0 | int | |
◢ | &a | 0x0032fd28 {0} | int * |
0 | int | ||
◢ | p | 0x0032fd28 {0} | int * |
0 | int | ||
◢ | &p | 0x0032fd1c {0x0032fd28 {0}} | int * * |
◢ | 0x0032fd28 {0} | int * | |
0 | int | ||
◢ | pp | 0x0032fd1c {0x0032fd28 {0}} | int * * |
◢ | 0x0032fd28 {0} | int * | |
0 | int |
好好看清楚储存内容和地址的关系。
讲一个小妙招
1·找谁和谁相等
把变量类型去掉,就知道谁和谁的类型相等了。
因为a是int类型,自己没有存储地址,所以不能像数组名一样直接当做指针用。
2·找解引用后=谁
int main()
{
int a = 0;
int* p = &a;
//因为p=&a
*p = *(&a) = a = 1;
printf("%d\n", a);
int** pp = &p;
//因为pp=&p
**pp = **(&p) = *p = *(&a) = a = 2;
printf("%d\n", a);
return 0;
}
不放图了,不信的话,拿代码去试试,记得引用头文件。
3·指针数组
int main()
{
int arr1[2] = { 0 };
char arr2[2] = { 0 };
int* arr3[2] ;
char* arr4[2] ;
return 0;
}
名称 | 值 | 类型 | |
---|---|---|---|
◢ | arr1 | 0x0020f72c {0, 0} | int[2] |
[0] | 0 | int | |
[1] | 0 | int | |
◢ | arr2 | 0x0020f720 "" | char[2] |
[0] | 0 '\0' | char | |
[1] | 0 '\0' | char |
后续会学到数组指针,和那个一起对比会通透些。
下一篇:从0开始学c语言-22-结构体声明和初始化、结构体大小、结构体成员访问、结构体传参_阿秋的阿秋不是阿秋的博客-优快云博客