c|指针进阶——字符指针、指针数组和数组指针如何辨别和判断

进阶指针
文章目录

  • 进阶指针
    • 一、字符指针
      • 1. 单个字符指针
      • 2. 常量字符串指针
    • 二、指针数组
      • 1. 存放整型指针
      • 2. 存放常量字符串指针
    • 三、数组指针
      • 1. 数组指针实现打印一维数组
      • 2. 数组指针实现打印二维数组
    • 如何判断是数组指针还是指针数组

一、字符指针 1. 单个字符指针
char ch = 'x'; char* p = &ch;

2. 常量字符串指针
char* p = "asdwjwd"; //后面一串数字为常量字符串

常量字符串单独存在,不是字符串数组
p中存放的是常量字符串中首元素a的地址
打印*p也只会打印首元素,同时验证了上面的猜想
printf("%s", p); //打印整个字符串,只需要首字母地址就行

就像数组
char arr[] = "asbdjw"; printf("%s", arr);

但是
常量字符串存储在内存的常量区,不能进行修改
所以常量字符串指针修改数值时候在不同的编译器可能会报错
我们在定义常量字符串指针的时候会加个const
const char* p = "adwdfe";

重点区分
const char* p = "asa"; const char* r = "asa";

因为常量字符串存储在内存的常量区,指针所指向的地址永远是字符串第一个字符的地址,所以p = r
二、指针数组
存放指针的数组
1. 存放整型指针
int* arr[3]; //存放整型指针的数组

数组中每个元素的类型都是整型指针int*
//打印指针数组 printf("%d", *(arr[1]));

利用(p+i) = p[i]去理解
int arr1[] = {1,2,3}; int arr2[] = {3,3,5,6}; int* p[] = {arr1,arr2}; printf("%d", p[1][2]); //打印5 //其中p[1][2] = *(p + 1)[2] = arr2[2] = *(arr2 + 2) = 5

2. 存放常量字符串指针
const char* p[2] = {"abs", "ashw", "swnd"};

打印 打印字符串只需要给予数组的首元素地址即可
printf("%s", p[1]); //打印ashw

三、数组指针
指向数组的指针
数组指针加1跳过一个数组
int arr[4] = { 0 }; int* p = arr; //指向数组首元素地址 int(*p)[4] = &arr; //这里[]的优先级比*高,所以需要加括号 //指针指向整个数组,把(*p)去掉就是指向数组中元素的类型

如何判断类型:把名字去掉即为类型
加深印象
int main() { int* arr[10]; //这里是指针数组 int* (*p)[10] = &arr; }

*先确定指针指向的元素的类型,再写(p)
1. 数组指针实现打印一维数组
void print(int (*p)[4], int sz) //传参形式,数组指针p指向一个arr[4],传进去的数是&arr { int i = 0; for(i = 0; i < sz; i++) { printf("%d", p[0][i]); //p[0] = *(p + 0) = arr 数组(首元素地址) //p[0][i] = arr[i] = (*(p + 0))[i] = (*p)[i] } }

2. 数组指针实现打印二维数组
void print(int (*p)[4], int line, int column) //传参形式,数组指针p指向一个arr[4] //传进去的数是arr,这里arr指的是二维数组第一行数组的数组名 { int i = 0; int j = 0; for(i = 0; i < line; i++) { for(j = 0; j < column; j++) { printf("%d", p[i][j]); //p[i] = *(p + i) = arr[i] (arr的i行数组地址) //p[0][i] = arr[i] = (*(p + 0))[i] = (*p)[i] } } }

思路再解读:
传参传的是arr
而二维数组中的arr代表,二维数组中,arr的第一行这一行的数组名
所以传参相当于传了一个一维数组
需要int (*p)[4] 的数组指针去接收
要想打印整个数组
int(*p)[4] = arr; 这里的arr是指的二维数组中第一行的数组名
p指向的是二维数组中第一行的地址
假如我们需要 arr [0] [2]
*(p + 0) 指的是二维数组中第一行的数组名
*(p + 1) 指的是二维数组中第二行的数组名
(*(p + 0) + 2)指的是二维数组中第一行,第二列数字的地址
再换个更容易理解的方式:
传参没传进去的时候,arr指的是二维数组中第一行的数组名
传参传进去的时候,p也是指的是二维数组中第一行的数组名
【c|指针进阶——字符指针、指针数组和数组指针如何辨别和判断】所以直接用就行,外面的arr [i] [j] 和 里面的 p [i] [j] 差不多
如何判断是数组指针还是指针数组
int* arr[10]; int (*arr)[10]; int * (*arr) [10];

分析:
1:[]的优先级比()高,所以arr与[10]先结合,arr是数组,有10个元素,每个元素类型是int*
2:()的优先级更高,arr和*先结合,所以arr是指针,指向的类型是int[10]是一个有10个int类型的整型数组
3:arr与*先结合,所以arr是指针,指向的类型是int *[10],这是一个有10个元素的数组,每个元素的类型是int *

    推荐阅读