《彻底理解C语言指针全攻略(4)--数组与指针的关系专题(下)》
《数组与指针的关系专题(下)》
🔥小龙报:个人主页
❄️个人专栏:《C语言》《算法》KelpBar海带Linux智慧屏项目
✨永远相信美好的事情即将发生
文章目录
- 《数组与指针的关系专题(下)》
- 前言
- 一、二级指针
- 二、指针数组
- 三、指针数组模拟二维数组
- 四、字符指针变量
- 4.1引入
- 4.2《剑指offer》中一道了和字符串相关的笔试题
- 五、 数组指针变量
- 5.1 数组指针变量是什么?
- 5.1.1数组指针变量和指针数组
- 5.1.2数组指针变量的书写形式
- 5.2 数组指针变量的初始化
- 六、二维数组传参的本质
- 总结--每日励志时刻
前言
继上篇文章后这篇文章将继续为大家分享指针的相关知识,本篇主要是二级指针,指针数组,指针数组模拟二维数组,字符指针变量,数组指针变量,二维数组传参的本质等知识点,让我们向着更优秀的自己出发go!
一、二级指针
指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪⾥那便是二级指针我们以一幅图来展示
对于⼆级指针的运算有:
• *ppa通过对ppa中的地址进⾏解引⽤这样找到的是pa ,*ppa 其实访问就是pa
int b = 20;*ppa = &b;//等价于pa = &b;
**ppa 先通过*ppa找到pa然后对pa 进⾏解引⽤操作:*pa 那找到的就是a
**ppa = 30; //等价于*pa = 30;
//等价于a = 30;
二、指针数组
指针数组是指针还是数组?
我们类比⼀下,整型数组,是存放整型的数组,字符数组是存放字符的数组。那指针数组呢?是存放指针的数组
指针数组的每个元素都是⽤来存放地址(指针)的
PS:指针数组的每个元素是地址,⼜可以指向⼀块区域。
三、指针数组模拟二维数组
#include <stdio.h>
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 2,3,4,5,6 };int arr3[] = { 3,4,5,6,7 };//数组名是数组⾸元素的地址,类型是int*的,就可以存放在parr数组中int* arr[] = { arr1,arr2,arr3 };for (int i = 0; i < 3; i++){for (int j = 0; j < 5; j++){printf("%d ", arr[i][j]); }printf("\n");}return 0;
}
运行结果:
图解:
PS:parr[i]是访问parr数组的元素,parr[i]找到的数组元素指向了整型⼀维数组,parr[i][j]就是整型⼀维数组中的元素。
上述的代码模拟出⼆维数组的效果,实际上并⾮完全是⼆维数组,因为每⼀⾏并⾮是连续的。
四、字符指针变量
4.1引入
在指针的类型中我们知道有⼀种指针类型为字符指针:char*,一般这么使用:
#include <stdio.h>
int main()
{char ch = 'w';char* pc = &ch;*pc = 'w';return 0;
}
还有⼀种使⽤⽅式如下:
#include <stdio.h>
int main()
{const char* pstr = "hello bit.";//这⾥是把⼀个字符串放到pstr指针变量⾥了吗?printf("%s\n", pstr);return 0;
}
PS:代码const char* pstr = “hello bit.”; 特别容易让同学以为是把字符串到字符指针pstr ⾥了,但是本质是把字符串hello bit 放hello bit. ⾸字符的地址放到了pstr中
本质:上⾯代码的意思是把⼀个常量字符串的⾸字符h的地址存放到指针变量pstr 中
4.2《剑指offer》中一道了和字符串相关的笔试题
#include <stdio.h>
int main()
{char str1[] = "hello bit.";char str2[] = "hello bit.";const char* str3 = "hello bit.";const char* str4 = "hello bit.";if (str1 == str2)printf("str1 and str2 are same\n");elseprintf("str1 and str2 are not same\n");if (str3 == str4)printf("str3 and str4 are same\n");elseprintf("str3 and str4 are not same\n");return 0;
}
运行结果:
解析:这⾥str3和str4指向的是⼀个同⼀个常量字符串。C/C++会把常量字符串存储到单独的⼀个内存区域,当⼏个指针指向同⼀个字符串的时候,他们实际会指向同⼀块内存。但是⽤相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4相同。
五、 数组指针变量
5.1 数组指针变量是什么?
5.1.1数组指针变量和指针数组
PS: 指针数组是⼀种数组:数组中存放的是地址(指针)。
数组指针变量是指针变量:存放的应该是数组的地址,能够指向数组的指针变量。
5.1.2数组指针变量的书写形式
int (*p)[10];
解析:[]的优先级要⾼于号的*,所以必须加上()来保证p先和结合*
5.2 数组指针变量的初始化
#include <stdio.h>int main()
{int arr[10] = { 0 };int (*p)[10] = &arr;return 0;
}
调试结果:发现到&arr 和p的类型是完全⼀致的
PS: 数组指针类型解析
六、二维数组传参的本质
过去我们有⼀个⼆维数组的需要传参给⼀个函数的时候,可以这样写:
#include <stdio.h>
void test(int a[3][5], int r, int c)
{int i = 0;int j = 0;for (i = 0; i < r; i++){for (j = 0; j < c; j++){printf("%d ", a[i][j]);}printf("\n");}
}
int main()
{int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };test(arr, 3, 5);return 0;
}
⾸先我们再次理解⼀下⼆维数组,⼆维数组其实可以看做是每个元素是⼀维数组的数组,也就是⼆维数组的每个元素是⼀个⼀维数组。那么⼆维数组的⾸元素就是第⼀⾏,是个⼀维数组。
如下图:
所以,根据数组名是数组⾸元素的地址这个规则,⼆维数组的数组名表⽰的就是第⼀⾏的地址,是⼀维数组的地址。,第⼀⾏的⼀维数组的类型就是型就是数组指针类型int [5] ,所以第⼀⾏的地址的int()[5] 。那就意味着⼆维数组传参本质上也是传递了地址 ,传递的是第⼀⾏这个⼀维数组的地址,那么形参也是可以写成指针形式的。如下:
#include <stdio.h>
void test(int(*p)[5], int r, int c)
{int i = 0;int j = 0;for (i = 0; i < r; i++){for (j = 0; j < c; j++){printf("%d ", *(*(p + i) + j));}printf("\n");}
}
int main()
{int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };test(arr, 3, 5);return 0;
}
运行结果:
总结:⼆维数组传参,形参的部分可以写成数组,也可以写成指针形式