指针数组与数组指针

今天被问了这两个概念,十几年的老码农基本被问懵了…
平时工作里基本很少用,稍微再整理下:

这里ptr是一个指针,指针ptr指向对象是一个int型

int *ptr;

这里ptr是一个指向指针的指针,指针ptr指向对象是一个指针

int **ptr;

这里ptr是数组(指针数组),注意这里的*修饰的是后面的[10],数组ptr有10个元素,每个元素都是一个 int *的指针

int *ptr[10];

这里ptr是指针(数组指针),注意这里的*因为有(),所以*修饰的是ptr,数组指针ptr指向一个有10个元素的数组,每个元素都是int

int (*ptr)[10];

这里ptr是数组(指针数组),注意这里的*修饰的是后面的[5][10],数组ptr有5x10个元素,每个元素都是一个 int *的指针

int *ptr[5][10];

这里ptr是指针(数组指针),注意这里的*修饰的是后面的[5][10],数组ptr有5x10个元素,每个元素都是一个 int *的指针

int (*ptr)[5][10];

这里ptr是数组,注意这里的*修饰的是后面的[5],数组ptr有5个元素,每个元素都是一个 指向具有10个int数组的指针

int (*ptr[5])[10];

这里ptr是指针,注意这里的第一个*修饰的是后面的[5][10],第二个*修饰的是ptr,指针ptr指向了一个有5x10个元素的数组,这个数组里的每个元素都是一个 int *的指针

int *(*ptr)[5][10];

这里ptr是数组,注意这里的第一个*和第二个*修饰的都是后面的[5][10],数组ptr有5x10个元素的数组,这个数组里的每个元素都是一个指向 int *的指针的指针

int **ptr[5][10];

所以,判别数组指针和指针数据的关键,就是看*修饰的是否是ptr本身,还是数组里的元素。其实就是看()有没有把*和ptr放在一起。。。
这好多年前关注的东西猛然被问起来确实有点懵。。。囧

有上面的知识后,再来看下面的sizeof就好计算了:

#include <stdio.h>
int main () {
    printf("sizeof(int)      is %d\n", sizeof(int));
    printf("sizeof(int *)    is %d\n", sizeof(int *));

    int **ptr[5][10];
    
    printf("sizeof(ptr)      is %d\n", sizeof(ptr));
    printf("sizeof(*ptr)     is %d\n", sizeof(*ptr));
    printf("sizeof(**ptr)    is %d\n", sizeof(**ptr));
    printf("sizeof(***ptr)   is %d\n", sizeof(***ptr));
    printf("sizeof(****ptr)  is %d\n", sizeof(****ptr));
	printf("\n");
	
    int *(*ptr1)[5][10];
    
    printf("sizeof(ptr1)     is %d\n", sizeof(ptr1));
    printf("sizeof(*ptr1)    is %d\n", sizeof(*ptr1));
    printf("sizeof(**ptr1)   is %d\n", sizeof(**ptr1));
    printf("sizeof(***ptr1)  is %d\n", sizeof(***ptr1));
    printf("sizeof(****ptr1) is %d\n", sizeof(****ptr1));
    return 0;
}  

结果如下:

/* 这个没什么好说的,说明本机是int类型是32bit */
sizeof(int)      is 4
/* 这个没什么好说的,说明本机是一个64bit的机器,指针的大小都是8 */
sizeof(int *)    is 8
/* ptr是一个数组,数组里有5*10个指向指针的指针, 所以ptr的大小是5*10*8 = 400 */
sizeof(ptr)      is 400
/* 数组名其实就是一个指针,指向本数组的指针,所以对其*解引用可以看成是取数组的一个元素,如int a[10], 那么*a就是a[0], 同理,这里的*ptr其实就是取数组ptr[0],这是一维含有10个元素的数组,所以取其一个元素就是一个10列的一维数组,所以sizeof(*ptr)是 8*10 = 80 */
sizeof(*ptr)     is 80
/* 解引用**ptr相当于是取到数组ptr[0][0],很显然,这里的元素是一个指针,指向指针的指针,所以sizeof(**ptr)是8 */
sizeof(**ptr)    is 8
/* 再取一级解引用,这时候,就到了数组里了,数组元素是指向指针的指针,所以这里依然是8 */
sizeof(***ptr)   is 8
/* 再取一级解引用,这时候,因为数组里的元素是指向int型的指针的指针,经过两次解引用后,就到了int本身了,所以这里是4 */
sizeof(****ptr)  is 4

/* 按照上面的分析,ptr1 是一个指针,所以是8 */
sizeof(ptr1)     is 8
/* *ptr1是对ptr1进行第一次解引用,按照上面的分析, ptr1是一个指向5*10大小的数组的指针,这个数组里每个元素都是一个int型的指针,所以ptr1解引用就是一个5*10的数组,因为其中存储的是大小为8的指针,所以*ptr1的大小是5*10*8=400 */
sizeof(*ptr1)    is 400
/* 对ptr1进行2次解引用,第1次是[5][10],第二次就是解引用到一维数组[0][10],所以其大小是 10 * 8 = 80 */
sizeof(**ptr1)   is 80
/* 对ptr1进行3次解引用,第1次是[5][10],第二次就是解引用到一维数组[0][10],第三次解引用就是[0][0], [0][0]中存储的是一个大小为8的int型的指针,所以其大小是 8 */
sizeof(***ptr1)  is 8
/* 对ptr1进行4次解引用,第1次是[5][10],第二次就是解引用到一维数组[0][10],第三次解引用就是[0][0], 第4次解引用就是对[0][0]中的指针本身解引用,也就是取int本身,int的大小是4,所以下面输出4 */
sizeof(****ptr1) is 4

话说,*ptr的叫法是对ptr解引用吧? >_< 有点想不起来了,懒得查了

相关推荐

  1. 指针数组数组指针

    2024-03-13 06:56:02       22 阅读
  2. 字符串数组字符串指针

    2024-03-13 06:56:02       43 阅读
  3. 对象数组指针引用

    2024-03-13 06:56:02       19 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-13 06:56:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-13 06:56:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-13 06:56:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-13 06:56:02       20 阅读

热门阅读

  1. 使用go开发的小tips

    2024-03-13 06:56:02       20 阅读
  2. 如何使用 CSS 中的 :root 伪类选择器

    2024-03-13 06:56:02       25 阅读
  3. SpringCloud-实现基于RabbitMQ的消息队列

    2024-03-13 06:56:02       23 阅读
  4. Linux纯命令行查看文本文件

    2024-03-13 06:56:02       23 阅读
  5. 【系统安全】浅谈保障接口安全的10种技术手段

    2024-03-13 06:56:02       24 阅读
  6. 异步&事件循环输出题-易错知识点

    2024-03-13 06:56:02       19 阅读
  7. python】jupyter notebook导出pdf和pdf不显示中文问题

    2024-03-13 06:56:02       20 阅读