C语言:深入理解指针(3)

1. 数组名的理解

上一节中,当我们用指针存放一个数组元素的首地址时,是这样存放的:

复制代码
int a[5] = {1,2,3,4,5};
int* p = &a[0];

我们看一下下图中这个现象;

我们会发现,数组名打印出的结果和数组首元素打印出的结果是一样的。因此,数组名就是数组首元素(第⼀个元素)的地址。

但是有两个例外,sizeof(数组名): sizeof 中单独存放数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节;**&数组名:**这里的数组名代表的是整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的)。其他情况下,任何地方使用数组名都表示数组首元素的地址。

下图解释了 &数组名(例如 &a) 和 **数组名(例如 a)**的区别:

我们会发现 &a[0] 和 a 和 &a 打印是相同的,&a[0]+1 和 a+1 相同但与 &a+1 不同,&a+1 与他们相比相差一个十六进制的 14,十进制也就是 20,这刚好是这个数组的长度20字节(一个int 是四个字节)。因为 &a 是这个数组的地址,+1 后就直接跳过了这个数组。

2.使用指针访问数组

例如我们将十个整数存到数组中并将它们打印在屏幕上,通过指针就可以这样写;

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

3.一维数组传参的本质

一维数组传参的本质其实就是传递了数组首元素的地址,因此我们在写形参时可以写成数组的形式,也可以写成指针的形式。

4.冒泡排序

下面来介绍一种排序算法:冒泡排序。其核心思想就是将相邻两两元素进行比较,最终得到一串升序或者降序的数。下面就是具体的代码;

5.二级指针

二级指针,简单来说就是存放指针变量的地址的指针。

复制代码
#include<stdio.h>
int main()
{
    int x = 5;
    int* p = &x;
    int** pp = *p;
    return 0;
}

上图中 pp 就是一个二级执政,其中 int** 中右边的 * 表示 pp 是一个指针变量,左边的 int* 说明 pp 指向的对象的类型是 int* 类型。这样通过 pp 解引用两次就能找到 x 了。

6.指针数组

首先我们要知道,指针数组是数组,而不是指针,这个数组中存放的数据都是指针(也就是地址),即指针数组中每个元素的类型都是指针类型。假设有三个数组 a[5]、b[5]、c[5] ,怎么把它们联系起来和一个三行五列的二维数组一样呢?这时候我们就可以通过指针数组来实现,假设有一个指针数组 parr[3] ,三个位置分别放数组 a,b,c 的首元素地址,这样我们就能够通过指针数组将他们联系起来了。

相关推荐
WalterJau11 分钟前
C 内存分区
c语言
xuxie9941 分钟前
N11 ARM-irq
java·开发语言
wefly20171 小时前
从使用到原理,深度解析m3u8live.cn—— 基于 HLS.js 的 M3U8 在线播放器实现
java·开发语言·前端·javascript·ecmascript·php·m3u8
luanma1509802 小时前
PHP vs C++:编程语言终极对决
开发语言·c++·php
寂静or沉默2 小时前
2026最新Java岗位从P5-P7的成长面试进阶资源分享!
java·开发语言·面试
csdn_aspnet2 小时前
C/C++ 两个凸多边形之间的切线(Tangents between two Convex Polygons)
c语言·c++·算法
kyriewen112 小时前
给浏览器画个圈:CSS contain 如何让页面从“卡成PPT”变“丝滑如德芙”
开发语言·前端·javascript·css·chrome·typescript·ecmascript
娇娇yyyyyy3 小时前
QT编程(18): Qt QItemSelectionModel介绍
开发语言·qt
豆豆的java之旅3 小时前
软考中级软件设计师 数据结构详细知识点(含真题+练习题,可直接复习)
java·开发语言·数据结构
sthnyph3 小时前
QT开发:事件循环与处理机制的概念和流程概括性总结
开发语言·qt