【重拾C语言】七、指针(二)指针与数组(用指针标识数组、多维数组与指针、数组指针与指针数组)

目录

前言

七、指针

7.1~3 指针与变量、指针操作、指向指针的指针

7.4 指针与数组

7.4.1 用指针标识数组

7.4.2 应注意的问题

a. 数组名是指针常量

b. 指针变量的当前值

c. 数组超界

7.4.3 多维数组与指针

7.4.4 指针数组

a. 指针数组

b. 数组指针

c. 对比总结


 

前言

在C语言中,指针和数组之间存在着密切的关系,指针可以用来标识和操作数组元素

  • 数组名是数组的首地址,即a[0]的地址(常量);
  • 指针的值也是一个地址(变量
  • 如果一个指针p指向数组a的首地址(即指向a[0]),则p与a表示的是同一个对象。
    • int a[10]; int *p=a; //int *p=&a[0];
      

 

 

七、指针

7.1~3 指针与变量、指针操作、指向指针的指针

【重拾C语言】七、指针(一)指针与变量、指针操作、指向指针的指针-CSDN博客https://blog.csdn.net/m0_63834988/article/details/133690334?spm=1001.2014.3001.5501

7.4 指针与数组

7.4.1 用指针标识数组

        可以使用指针来标识数组元素。通过将数组名转换为指针,可以通过指针来访问数组中的元素。

  •  数组名是指针(常量),指针也是数组
    • int  a[5];
      int  *p
      p=a;     // 也可写成 p=&a[0]
    • 访问数组a的第i个元素,如下操作等价
      • a[i]
        *(a+i)
        *(p+i) 
        p[i]
        

 

7.4.2 应注意的问题

a. 数组名是指针常量

        数组名实际上是指向数组首元素的指针常量,它存储了数组的起始地址。由于数组名是常量,因此不能对其进行赋值操作。

  • 指针变量可以参与运算
  • 虽然数组名也是指针,但对数组名却不能这样,因为数组名是指针常量
  • 对数组变量a的增1运算“a++”是非法的

 

b. 指针变量的当前值

        指针变量的当前值是指针所指向的内存地址。指针变量存储了一个地址值,该地址指向内存中的某个位置。通过解引用指针,可以访问或修改指针所指向地址处存储的值。

 

c. 数组超界

        数组超界指的是访问数组元素时超过了数组的有效索引范围。当我们访问数组时,应该确保索引值在合法范围内,即大于等于0且小于数组长度。如果超出了数组的有效索引范围,将会导致未定义的行为,可能会访问到未知的内存区域,从而引发错误或崩溃。

#include <stdio.h>int main() {int arr[5] = {1, 2, 3, 4, 5};int *ptr = arr;  // 数组名作为指针常量// 使用指针算术访问数组元素printf("数组元素:\n");for (int i = 0; i < 5; i++) {printf("arr[%d] = %d\n", i, *(ptr + i));  // 指针变量的当前值}// 超出数组界限printf("\n尝试访问数组边界之外的元素:\n");printf("arr[5] = %d\n", *(ptr + 5));  // 访问第6个元素return 0;
}

 

e087a3daa5314ca4b02e815961963e47.png

 

7.4.3 多维数组与指针

        指针可以用于处理多维数组:多维数组在内存中以连续的方式存储,可以通过指针来依次访问数组中的元素。

以 int 类型二维数组为例:

int arr[3][4] = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}
};

        可以使用指针来表示这个二维数组。对于二维数组,我们需要使用指向数组的指针,即指向一维数组的指针。可以定义一个指针变量,并让它指向二维数组的首地址:

int (*ptr)[4];  // 指向一维数组的指针
ptr = arr;      // 指向二维数组的首地址

        使用指针来访问二维数组及其元素。通过逐层解引用指针,我们可以访问每个元素:

// 访问二维数组的元素
int element = ptr[1][2];  // 访问第2行第3列的元素,值为7// 或者使用指针算术运算来访问元素
int element = *(*(ptr + 1) + 2);  // 与上面的访问方式等效,值为7
  • ptr[1][2]表示访问第2行第3列的元素
  • *(ptr + 1) + 2表示访问第2行第3列的元素地址
  • *(*(ptr + 1) + 2)表示访问第2行第3列的元素值

 

7.4.4 指针数组

a. 指针数组

        指针数组是指一个数组,其中的每个元素都是指针类型。换句话说,指针数组是一个存储指针的数组。每个指针可以指向不同的对象或变量。

        指针数组的声明形式为type *arrayName[size],其中type是指针指向的数据类型,arrayName是数组的名称,size是数组的大小。

int *ptrArray[5];  // 声明一个包含5个指针的指针数组

 

b. 数组指针

        数组指针是指一个指针,它指向一个数组。换句话说,数组指针是一个指向数组的指针变量。指向的数组的元素类型是固定的。

        数组指针的声明形式为type (*ptrName)[size],其中type是指针指向的数据类型,ptrName是指针变量的名称,size是数组的大小。如上述int (*ptr)[4]:

int (*ptr)[4];  // 声明一个指向包含4个int类型元素的数组的指针

c. 对比总结

  • 指针数组是一个数组,其中的每个元素都是指针类型
  • 数组指针是一个指针,它指向一个数组
  • 指针数组的元素可以指向不同类型的对象或变量,而数组指针指向的数组的元素类型是固定的。
  • 指针数组的大小是数组的大小,而数组指针指向的数组的大小是指针指向的数组的大小。

 

#include <stdio.h>int main() {int arr[3] = {1, 2, 3};int* ptr_arr[3];  // 指针数组,每个元素是一个指向整数的指针int (*ptr)[3];    // 数组指针,指向一个包含3个整数的数组for (int i = 0; i < 3; i++) {ptr_arr[i] = &arr[i];  // 指针数组中的每个元素指向数组arr的对应元素}ptr = &arr;  // 数组指针指向数组arr的起始地址// 通过指针数组访问数组元素for (int i = 0; i < 3; i++) {printf("%p ", ptr_arr[i]);printf("%d\n", *ptr_arr[i]);}printf("\n");// 通过数组指针访问数组元素for (int i = 0; i < 3; i++) {printf("%p ", ptr[i]);      // 指针的地址值printf("%d ", (*ptr)[i]);printf("%p\n", &(*ptr)[i]); // 第i个元素的地址}printf("\n");return 0;
}

 

b8eb28810c694d49a76313cf44f99d65.png

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/130370.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UUID和雪花(Snowflake)算法该如何选择?

博主简介&#xff1a;不写代码没饭吃&#xff0c;一名全栈领域的创作者&#xff0c;专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构&#xff0c;分享一些项目实战经验以及前沿技术的见解。关注我们的主页&#xff0c;探索全栈开发&#xff0c;期待与您一起在移…

Android之App跳转其他软件

文章目录 前言一、效果图二、实现步骤1.弹框xml(自己替换图标)2.弹框utils3.两个弹框动画4.封装方便调用5.调用6.长按事件方法7.跳转步骤8.复制utils 总结 前言 最近遇到一个需求&#xff0c;就是App内大面积需要长按复制并跳转指定App&#xff0c;没办法&#xff0c;只能埋头…

4.02 用户中心-上传头像功能开发

详细内容请看下面地址&#xff1a; 地址&#xff1a;http://www.gxcode.top/code

FreeRTOS学习笔记(一)

一、基础知识思维导图 vtaskdelay函数会开启中断&#xff0c;所以在临界区不能用vtaskdelay 二、任务的创建与删除 2.1、任务的动态创建与删除 ........#define START_TASK_PRIO 1 #define START_TASK_STACK_SIZE 128 TaskHandle_t start_task_handler; void …

leetcode:190. 颠倒二进制位

一、题目&#xff1a; 函数原型&#xff1a; uint32_t reverseBits(uint32_t n) 解释&#xff1a;uint32是无符号int或short的别称&#xff0c;传入的参数是一个32位二进制串&#xff0c;返回值是该32位二进制串逆序后的十进制值 二、思路&#xff1a; 实际上并不需要真的去逆…

秒验:可以自定义UI的一键登录服务

一键登录如今成为越来越多移动应用的首选&#xff0c;但千篇一律的登陆界面在引发用户担忧其安全性的同时&#xff0c;也容易让用户在不同APP切换时产生误解。因此&#xff0c;由国内知名移动应用开发服务商MobTech打造的一键登录工具——秒验&#xff0c;通过允许开发者自定义…

【Linux】 vi / vim 使用

天天用vim 或者vi 。看着大佬用的很6 。我们却用的很少。今天咱们一起系统学习一下。 vi / vim 发展史 vi 是一款由加州大学伯克利分校&#xff0c;Bill Joy研究开发的文本编辑器。 vim Vim是一个类似于Vi的高度可定制的文本编辑器&#xff0c;在Vi的基础上改进和增加了很多…

ThinkPHP团购拼购商城源码/带分销团购商城网站源码/完美版

ThinkPHP团购拼购商城源码&#xff0c;带分销团购商城网站源码&#xff0c;很完美的一套基于ThinkPHP开发的团购分销商城源码&#xff0c;界面也很大气&#xff0c;站长亲测。有需要的可以借鉴一下。 下载地址&#xff1a;https://bbs.csdn.net/topics/613231434

JDBC-day03(BLOB类型字段,批量插入)

四&#xff1a;操作BLOB类型字段 1.MySQL BLOB类型 在MySQL中&#xff0c;BLOB是一个二进制大型对象&#xff0c;是一个可以存储大量数据的容器&#xff0c;它能容纳不同大小的数据。可以用来存储图片&#xff0c;视频等 插入BLOB类型的数据必须使用PreparedStatement&#x…

IDEA的使用(三)Debug(断点调试)(IntelliJ IDEA 2022.1.3版本)

编程过程中如果出现错误&#xff0c;需要查找和定位错误时&#xff0c;借助程序调试可以快速查找错误。 编写好程序后&#xff0c;可能出现的情况&#xff1a; 1.没有bug。 使用Debug的情况&#xff1a; 2.运行后&#xff0c;出现错误或者异常信息&#xff0c;但是通过日志文件…

Hadoop----Azkaban的使用与一些报错问题的解决

1.因为官方只放出源码&#xff0c;并没有放出其tar包&#xff0c;所以需要我们自己编译&#xff0c;通过查阅资料我们可以使用gradlew对其进行编译&#xff0c;还是比较简单&#xff0c;然后将里面需要用到的服务文件夹进行拷贝&#xff0c;完善其文件夹结构&#xff0c;通常会…