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

进阶指针

文章目录

  • 进阶指针
    • 一、字符指针
      • 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也是指的是二维数组中第一行的数组名

所以直接用就行,外面的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 *


你可能感兴趣的:(c,programing,language,c语言,c++)