news 2026/1/11 4:18:06

C语言指针讲解(2)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C语言指针讲解(2)

目录

1.数组名的理解

2. 使用指针访问数组

3.一维数组传参的实质

4.二级指针

5.指针数组


1.数组名的理解

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() { int a[] = { 1,2,3,4,5 }; int* p = &a[0]; return 0; }

我们看上面的代码我们p指针拿到的就是数组a的第一个元素的地址.

但是现在我告诉你数组名就是数组的第一个元素的地址,下面我将用下面的代码来验证.

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() { int a[] = { 1,2,3,4,5 }; int* p = a; printf("%d", *p); return 0; }

运行结果如图所示

很明显我们p就是第一个元素的地址

下面我们看这个有关字符串的代码:

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() { char a[] = "hello"; printf("%s", a); return 0; }

这样我们就知道了为什么输出字符串时用字符串的名字就可以了;

下面我们看一个特例:

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() { int a[] = { 1,2,3,4,5,6 }; printf("%zd", sizeof(a)); return 0; }

如果像上面所说的数组名就是第一个元素的地址的话那么这个将会输出一个int的字节

但是事实真的是这样吗?

我们可以看到运行结果并没有输出4,而是输出了24.

我们来思考一下数组总共有六个元素每个占4个字节 为什么这里的数组名代替的是整个数组呢?

其实数组名就是数组⾸元素(第⼀个元素)的地址是对的,但是有两个例外:

• sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩, 单位是字节

• &数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素 的地址是有区别的)

除此之外,任何地⽅使⽤数组名,数组名都表⽰⾸元素的地址。

下面我们看下面的代码:

#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; printf("&arr[0] = %p\n", &arr[0]); printf("&arr[0]+1 = %p\n", &arr[0] + 1); printf("arr = %p\n", arr); printf("arr+1 = %p\n", arr + 1); printf("&arr = %p\n", &arr); printf("&arr+1 = %p\n", &arr + 1); return 0; }

运行结果如图所示:

我们可以看到&arr[0]和&arr[0]+1相差4个字节,arr和arr+1相差4个字节,是因为&arr[0]和arr都是 ⾸元素的地址,+1就是跳过⼀个元素。

但是&arr和&arr+1相差40个字节,这就是因为&arr是数组的地址,+1操作是跳过整个数组的。

到这⾥⼤家应该搞清楚数组名的意义了吧。 数组名是数组⾸元素的地址,但是有2个例外。

2. 使用指针访问数组

在理解了上面的内容后我们就可以用指针来访问数组了

举个例子:

#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { int a[10] = { 0 }; int* p = a; for (int i = 0; i < 10; i++) { scanf("%d", p + i); } for (int i = 0; i < 10; i++) { printf("%d ", *(a + i)); } return 0; }

在这里p[i]是和(p+i)是等效的

同理arr[i]应该等价于*(arr+i),数组元素的访问在编译器处理的时候,也是转换成⾸元素的地址+偏移 量求出元素的地址,然后解引⽤来访问的。

3.一维数组传参的实质

数组我们学过了,之前也讲了,数组是可以传递给函数的,这个⼩节我们讨论⼀下数组传参的本质。

⾸先从⼀个问题开始,我们之前都是在函数外部计算数组的元素个数,那我们可以把函数传给⼀个函 数后,函数内部求数组的元素个数吗?

我们来实践一下:

#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> void text(int a[]) { int n = sizeof(a) / sizeof(a[0]); printf("%d\n", n); } int main() { int a[10] = { 0 }; /*int* p = a; for (int i = 0; i < 10; i++) { scanf("%d", p + i); } for (int i = 0; i < 10; i++) { printf("%d ", *(a + i)); }*/ text(a); /*int *p = a; printf("%zd", sizeof(p));*/ return 0; }

运行结果如图所示:

我们发现在函数内部是没有正确获得数组的元素个数。

这就要学习数组传参的本质了,上个⼩节我们学习了:数组名是数组⾸元素的地址;那么在数组传参 的时候,传递的是数组名,也就是说本质上数组传参本质上传递的是数组⾸元素的地址。

所以我们这里求得是一个定值也就是一个地址的大小,在我的编译环境中是8个字节

正是因为函 数的参数部分是本质是指针,所以在函数内部是没办法求的数组元素个数的。

4.二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪⾥?

那么我们就需要使用二级指针了;

二级指针的示意图

5.指针数组

指针数组就是存储指针的数组

我们用数组指针来模拟实现二维数组

#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> int main() { int arr1[] = { 1,2,3,4,5 }; int arr2[] = { 2,3,4,5,6 }; int arr3[] = { 3,4,5,6,7 }; //数组名是数组⾸元素的地址,类型是int*的,就可以存放在parr数组中 int* parr[3] = { arr1, arr2, arr3 }; int i = 0; int j = 0; for (i = 0; i < 3; i++) { for (j = 0; j < 5; j++) { printf("%d ", parr[i][j]); } printf("\n"); }

这里的parr[i]先访问每个数组的首元素的地址就相当于访问每个二维数组的每一行,后面的[j]就是访问每个数组的元素也就是二维数组的每一行的每一列.

这次的内容结束了,之后会为大家继续讲解有关指针的知识

谢谢观看!!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/8 21:42:59

wangEditor实现excel数据动态绑定更新

《一个码农的CMS奇幻漂流》 需求评审会&#xff1a;当客户说"很简单"的时候… 各位父老乡亲好啊&#xff01;我是福建厦门一名"资深"前端码农&#xff08;资深加班多&#xff09;。刚接到个CMS官网需求&#xff0c;看完需求文档我直接表演了个闽南式震惊…

作者头像 李华
网站建设 2026/1/9 7:12:41

Data Formulator终极指南:零代码实现AI驱动数据可视化革命

还在为复杂的数据可视化代码而烦恼吗&#xff1f;面对海量数据却不知从何下手&#xff1f;Data Formulator的出现彻底改变了这一局面——通过直观的拖拽操作和AI智能辅助&#xff0c;任何人都能在几分钟内创建专业级数据可视化报告。 【免费下载链接】data-formulator &#x1…

作者头像 李华
网站建设 2026/1/7 18:39:14

LLM训练算力优化终极指南:多后端引擎完整教程

LLM训练算力优化终极指南&#xff1a;多后端引擎完整教程 【免费下载链接】verl verl: Volcano Engine Reinforcement Learning for LLMs 项目地址: https://gitcode.com/GitHub_Trending/ve/verl 你是否在为大规模语言模型训练时的算力瓶颈而苦恼&#xff1f;面对70B以…

作者头像 李华
网站建设 2026/1/8 10:41:22

队列从数据结构到统计分析的理论与实践研究

队列&#xff1a;从数据结构到统计分析的理论与实践研究摘要队列作为一种基础数据结构与重要统计研究方法&#xff0c;在计算机科学数据处理与统计学因果推断中均具有不可替代的作用。本文系统梳理队列的数学定义与核心特性&#xff0c;深入剖析数据结构中队列的实现原理、算法…

作者头像 李华
网站建设 2026/1/10 5:55:45

YOLOv5联邦学习完整部署指南:多设备协同训练实战

YOLOv5联邦学习完整部署指南&#xff1a;多设备协同训练实战 【免费下载链接】yolov5 yolov5 - Ultralytics YOLOv8的前身&#xff0c;是一个用于目标检测、图像分割和图像分类任务的先进模型。 项目地址: https://gitcode.com/GitHub_Trending/yo/yolov5 在当今数据隐私…

作者头像 李华
网站建设 2025/12/13 19:24:03

谷城县竟有售后超有保障的家电门店,究竟是哪家?

谷城县竟有售后超有保障的家电门店&#xff0c;究竟是哪家&#xff1f;在谷城县&#xff0c;家电市场的选择日益丰富&#xff0c;消费者在购买家电时&#xff0c;除了关注产品本身的品质&#xff0c;售后保障也成为了重要的考量因素。那么&#xff0c;谷城县哪家家电门店的售后…

作者头像 李华