首页 > 其他分享 >指针数组与数组指针(超详细!!!)

指针数组与数组指针(超详细!!!)

时间:2024-07-04 20:56:08浏览次数:18  
标签:arr 20 数组 指向 int 详细 指针

指针数组

秘诀:括号优先,先右后左,由近及远

        指针数组是一个数组,其中每个元素都是一个指针。指针数组可以用于存储指向不同数据类型的指针,例如字符、整数或结构体等。

int *p[n]; //定义了一个指针数组,数组大小为n,数组中的每个元素都是一个int*指针

 存储指向整型数组的指针

#include <stdio.h>

int main() {
    // 声明几个整型数组
    int arr1[] = {1, 2, 3};
    int arr2[] = {4, 5, 6};
    int arr3[] = {7, 8, 9};

    // 声明一个指针数组,每个元素是一个指向整型的指针
    int *arr[] = {arr1, arr2, arr3};

    // 打印指针数组中的每个数组的内容
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            printf("arr[%d][%d] = %d\n", i, j, arr[i][j]);
        }
    }

    return 0;
}

    运行结果:
            arr[0][0] = 1
            arr[0][1] = 2
            arr[0][2] = 3
            arr[1][0] = 4
            arr[1][1] = 5
            arr[1][2] = 6
            arr[2][0] = 7
            arr[2][1] = 8
            arr[2][2] = 9

存储指向字符串的指针

#include <stdio.h>

int main() {
    // 声明一个指针数组,数组中的每个元素都是一个指向字符常量的指针
    const char *arr[] = {"Hello", "World", "Pointer", "Array"};

    // 打印指针数组中的每个字符串
    for (int i = 0; i < 4; i++) {
        printf("arr[%d]: %s\n", i, arr[i]);
    }

    return 0;
}

    运行结果:
                arr[0]: Hello
                arr[1]: World
                arr[2]: Pointer
                arr[3]: Array

问题思考        

         有同学会问数组里存放的不是字符串吗,指针数组里存放的不应该是指针吗?一开始我也有这样的疑问,后来通过查阅相关资料后终于理解。

解答:

        "Hello", "World", "Pointer", 和 "Array" 确实是 arr 数组中的元素,但它们在数组中存储的是指向这些字符串的指针,而不是字符串本身。字符串本质就是地址,地址是指针类型的数据;数组名也是一样。对于本例指针数组,每个元素都是一个 const char* 类型的指针,指向相应的字符串常量。 (友友们是否理解了)

数组指针

        数组指针是一种特殊的指针,用来存放数组的地址。在C语言中,数组指针的定义形式为  int (*p)[n];   ,其中 p 是指向一个包含 n 个 int 类型元素的数组的指针。

数组指针与指向数组首元素的指针不同,它直接指向    整个数组  。

#include<stdio.h>
  
   int main(){
      int arr[20] = {1,2,3,4,5,6,7,8};
   
      int (*p)[20] = &arr;
       //数组的大小
       printf("arr = %28lu\n",sizeof(arr));
       printf("*p = %29lu\n",sizeof(*p));
       //打印首元素地址
       printf("arr = %28p\n",arr);
       //打印数组整体地址
       printf("&arr = %27p\n",&arr);
  
       //表示加一个数组整体地址大小
       printf("&arr + 1 = %23p\n",&arr+1);
       printf("(void*)(p + 1) = %17p\n",(void*)(p + 1));
  
       //表示加一个数组元素大小
       printf("arr[0] + 1 = %21p\n",&arr[0] + 1);
       printf("arr + 1 = %24p\n",arr+1);
       printf("(void*)((*p) + 1) = %13p\n",(void*)((*p) + 1));
       return 0;
  }

    运行结果:       
            arr =                           80
            *p =                            80
            arr =               0x7fff2475a290
            &arr =              0x7fff2475a290
            &arr + 1 =          0x7fff2475a2e0
            (void*)(p + 1) =    0x7fff2475a2e0
            arr[0] + 1 =        0x7fff2475a294
            arr + 1 =           0x7fff2475a294
            (void*)((*p) + 1) = 0x7fff2475a294
                 

例如,如果我们有一个 int 类型的数组 arr[5],我们可以定义一个数组指针来指向它:

int arr[5] = {1, 2, 3, 4, 5};
int (*p)[5] = &arr;

这里,p 是一个数组指针,它指向由5个 int 元素组成的数组 arr。通过数组指针,我们可以访问数组中的元素,例如 (*p)[i] 将访问 arr 数组中的第 i 个元素。

理解 arr&arr 的区别

  1. arr

    • arr 是一个数组名,在表达式中它会衰减为指向数组首元素的指针。
    • 例如,对于 int arr[20]arr 的类型是 int*,指向第一个元素 arr[0]
  2. &arr

    • &arr 是整个数组的地址,它的类型是 int (*)[20],即指向包含20个整数的数组的指针。
    • &arr 指向整个数组,而不是数组的第一个元素。

为什么 int (*p)[20] = &arr; 是正确的

  • p 的类型是 int (*)[20],表示 p 是一个指向包含20个整数的数组的指针。
  • &arr 的类型也是 int (*)[20],表示它是一个指向包含20个整数的数组的指针。
  •   因此,int (*p)[20] = &arr; 类型匹配,是正确的。

为什么 int (*p)[20] = arr; 是不正确的 

  • arr 的类型在表达式中衰减为 int*,表示它是一个指向 int 的指针。
  • p 的类型是 int (*)[20],表示它是一个指向包含20个整数的数组的指针。
  • int*int (*)[20] 类型不匹配,因此编译器会报错。

理解数组指针和解引用

#include <stdio.h>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int (*p)[5] = &arr;


    // 访问数组元素
    for (int i = 0; i < 5; i++) {
        printf("(*p)[%d] = %d\n", i, (*p)[i]);
    }

    // 也可以直接使用 p[0] 访问数组元素,因为 p[0] 等价于 (*p)
    for (int i = 0; i < 5; i++) {
        printf("p[0][%d] = %d\n", i, p[0][i]);
    }

    return 0;
}

    运行结果:
                (*p)[0] = 1
                (*p)[1] = 2
                (*p)[2] = 3
                (*p)[3] = 4
                (*p)[4] = 5
                p[0][0] = 1
                p[0][1] = 2
                p[0][2] = 3
                p[0][3] = 4
                p[0][4] = 5

1.声明数组和数组指针

int arr[5] = {1, 2, 3, 4, 5};
int (*p)[5] = &arr;

  • arr 是一个包含5个 int 元素的数组。
  • p 是一个指向 arr 的指针,它的类型是 int (*)[5]

2.解引用数组指针

  • *p 解引用数组指针 p,得到它所指向的数组 arr
  • (*p) 的类型是 int[5],即包含5个 int 元素的数组。

3.访问数组元素

  • (*p)[i] 访问数组 arr 中的第 i 个元素。
  • p[0][i] 也可以访问数组元素,因为 p[0] 等价于 (*p)

关键点

  • p 是指向数组的指针,直接使用 p 得到的是指向数组的指针,而不是数组本身。
  • 通过解引用 p(即 *p),我们得到数组 arr,然后可以使用数组下标来访问数组中的元素。
  • p[0] 等价于 (*p),因为 p 指向的是数组的首地址,p[0] 解引用第一个元素,即整个数组。

问题思考

        数组指针为什么被称为行指针   (参考上一代码运行结果p[0][0], p[0][1]......)

 

标签:arr,20,数组,指向,int,详细,指针
From: https://blog.csdn.net/qq_62850449/article/details/140161748

相关文章

  • 从 URL 到页面:浏览器加载过程的详细解析
    当你在浏览器中输入一个URL并按下回车键,直到页面内容显示在屏幕上,这个过程中发生了许多步骤。以下是一个详细的分解,解释从输入URL到看到内容之间的整个过程:1.用户输入URL用户在浏览器地址栏中输入URL(例如 https://www.example.com)并按下回车键。2.浏览器解析URL浏......
  • 「代码随想录算法训练营」第二天 | 数组 part2
    977.有序数组的平方题目建议:本题关键在于理解双指针思想题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/题目难度:简单文章讲解:https://programmercarl.com/0977.有序数组的平方.html视频讲解:https://www.bilibili.com/video/BV1QB4y1D7ep题目状态:通过......
  • Java 中Json中既有对象又有数组的参数 如何转化成对象
    1.示例一:解析一个既包含对象又包含数组的JSON字符串,并将其转换为Java对象在Java中处理JSON数据,尤其是当JSON结构中既包含对象又包含数组时,常用的库有org.json、Gson和Jackson。这里我将以Gson为例来展示如何解析一个既包含对象又包含数组的JSON字符串,并将其转换为Java对象。首先......
  • Qt Json详细介绍
    一.概念介绍JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,常用于前后端数据传输和存储。它具有以下特点:易读性:JSON使用人类可读的文本格式表示数据,采用键值对的方式组织数据,易于阅读和编辑。轻量级:JSON数据格式较为简洁,不包含冗余信息,适合网络传输和存......
  • 云服务器部署flask项目详细步骤
    云服务器部署flask项目详细步骤,从服务器选择开始(本文选用的是阿里云)1.购买服务器,我们目前选择镜像Ubuntu16.0464位的系统,因为这个系统目前运行比较稳定 2.设置远程链接密码 如果忘了自己的ssh链接密码,可以以下地方重置密码3.添加安全组 添加5000端口,添加80端口,有的......
  • 软件开发资料汇总(规格说明书、详细设计、测试计划、验收报告)
       前言:在软件开发过程中,文档资料是非常关键的一部分,它们帮助团队成员理解项目需求、设计、实施、测试、验收等各个环节,确保项目的顺利进行。以下是各个阶段的文档资料概述:软件项目管理部分文档清单: 工作安排任务书,可行性分析报告,立项申请审批表,产品需求规格说明书,需求......
  • 代码随想录算法训练营第2天 | 数组滑动窗口、螺旋打印
    有序数组的平方。常规方法复习冒泡排序,也可以使用双指针。因为有序数组的平方,最大值一定在两侧,最小值在中间。可以两侧往中间收拢。2024年7月4日笔记:双指针法,两侧往中间逼近一定是从大到小,然后给res数组倒着填即可实现从小到大。题977.有序数组的平方classSolution{pub......
  • 黑客入门教程(非常详细)从零基础入门到精通,看完这一篇就够了
    想要成为黑客,却苦于没有方向,不知道从何学起,下面这篇黑客入门教程可以帮你实现自己的黑客梦想,如果想学,可以继续看下去,文章有点长,希望你可以耐心看到最后 1、Web安全相关概念(2周)·熟悉基本概念(SQL注入、上传、XSS、、CSRF、一句话木马等)。通过关键字(SOL注入、上传、XSSC......
  • 黑客入门教程(非常详细)从零基础入门到精通,看完这一篇就够了
    想要成为黑客,却苦于没有方向,不知道从何学起,下面这篇黑客入门教程可以帮你实现自己的黑客梦想,如果想学,可以继续看下去,文章有点长,希望你可以耐心看到最后 1、Web安全相关概念(2周)·熟悉基本概念(SQL注入、上传、XSS、、CSRF、一句话木马等)。通过关键字(SOL注入、上传、XSSC......
  • 黑客入门教程(非常详细)从零基础入门到精通,看完这一篇就够了
    想要成为黑客,却苦于没有方向,不知道从何学起,下面这篇黑客入门教程可以帮你实现自己的黑客梦想,如果想学,可以继续看下去,文章有点长,希望你可以耐心看到最后 1、Web安全相关概念(2周)·熟悉基本概念(SQL注入、上传、XSS、、CSRF、一句话木马等)。通过关键字(SOL注入、上传、XSSC......