二重指针、二维数组、二维数组和指针的运算

2023-12-12 10:08

本文主要是介绍二重指针、二维数组、二维数组和指针的运算,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

(1)二重指针

(1)本质上来说,二重指针和一重指针的本质都是指针变量,指针变量的本质就是变量。
(2)一重指针变量和二重指针变量本身都占8字节内存空间(64位)

二重指针的简单应用:

	int a = 10;int *p = NULL;int **p1 = NULL;p = &a;p1 = &p;printf("*p=%d\n",*p);printf("**p1 = %d\n",**p1);

二重指针和指针数组结合

#include <stdio.h>int main()
{
int *a[10];
int **p1 = NULL;
p1 = a;
//a是数组名,相当于首元素首地址,首元素是指针,a也就相当于地址的地址。和int** 匹配}

二重指针充当函数形参

#include<stdio.h>void func(int **p)
{*p = (int *)0x12345678;
}int main(void)
{
int a = 4;
int *p = &a;				// p指向a
printf("p = %p.\n", p);		// p打印出来就是a的内存地址
func(&p);					// 在func内部将p指向了别的地方
printf("p = %p.\n", p);		// p已经不指向a了,所以打印出来不是a的地址
*p = 23;					// 因为此时p指向0x12345678,但是这个地址是不允许访问的,因此会段错误。

(2)二维数组

(1)从内存角度来看,一维数组和二维数组没有本质差别。
(2)二维数组int a[2][5]和一维数组int b[10]其实没有任何本质差别。我们可以把两者的同一单元的对应关系写下来。

a[0][0]	 a[0][1]   a[0][4]	 a[1][0]	a[1][1]	  a[1][4]	
b[0]	 b[1]	   b[4]	     b[5]	    b[6]	  b[9]

(3)第一维和第二维
3.1 int a[2][3]中的2是第一维,3是第二维。
3.2 结合内存映像来理解二维数组的第一维和第二维的意义。首先第一维是最外面一层的数组,所以int a[2][3]这个数组有2个元素;其中每一个元素又是一个含有3个元素的一维数组(这个数组就是第二维)。
在这里插入图片描述
(4)二维数组的定义:

int a[2][5] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
//int a[2][5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

二维数组下标访问

int a[2][5] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
//int a[2][5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int *p = a;		// 类型不匹配
//应该是 int (*p)[5] = a;//a相当于&a[0]	
printf("a[1][3] = %d.\n", a[1][3]);    // 9
printf("a[1][3] = %d.\n", *(*(a+1)+3)); // 9

史上最详细分析:
(1)a等同于&a[0],&a[0]是在第一维中的首元素首地址,a[0]表示第一维中的首元素
(2)a+1相当于&a[1],是第一维的数组中的第二个数组元素的首地址
(3)a,表示第一维数组中的首元素,该元素也是第二维的数组的数组名,就是第二维的一维数组的首元素首地址。
(4)
(a+1),表示第一维数组中的第二个元素,该元素也是第二维的数组的数组名,就是第二维的一维数组的首元素首地址。
(5)(a+1)+3,表示,表示第一维数组中的第二个元素,该元素也是第二维的数组的数组名,+3后表示从第二维的一维数组的首元素首地址偏移了3位之后的地址
(6)
(*(a+1)+3),对(5)里面的地址进行解引用,得到值 9;

二维数组的运算和指针(a和a[0])

(1)数组中各个符号的意义

先定义个二维数组

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

a[0]= &a[0][0] ,二维数组的第一维的第一个元素,相当于是第二维的第一个整体数组的数组名。数组名又表示数组首元素首地址,因此a[0]等同于&a[0][0]

int a[2][5] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
int *p4 = a[0];	//不报错,int * 类型和第二维的一维数组是匹配的。
int *p5 = &a[0][0];	//和上面一样

(2)指针指向二维数组的第一维


//int *p4 = &a[0];		// 不可以int *p4 = a[0];			// a[0]表示二维数组的第一维的第一个元素,相当于是第二维的整体数组的数组名。数组名又表示数组首元素首地址,因此a[0]等同于&a[0][0];int *p5 = &a[0][0];	
printf("a[0][4] = %d.\n", *(p4+4));//访问a[0][4]
int *p6 = a[1];
printf("a[1][1] = %d.\n", *(p6+1));//访问a[1][1]

指针指向二维数组的数组名
(1)a是二维数组的数组名,作为右值表示二维数组第一维的数组的首元素首地址,等同于&a[0],所以想要设置一个指针指向a,必须是数组指针p

p指向第一维的数组

	
int (*p3)[5];// 数组指针,指针指向一个数组,数组有5个int类型元素,p3+1就直接跑到第一维的下一个数组去
p3 = a;// a是二维数组的数组名,作为右值表示二维数组第一维的数组的首元素首地址,等同于&a[0]
p3 = &a[0];//同上printf("a[0][3] = %d.\n", *(*(p3+0)+3));
printf("a[1][4] = %d.\n", *(*(p3+1)+4));

总结:

小了,小了,a[0]比a的格局小了。

这篇关于二重指针、二维数组、二维数组和指针的运算的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/484216

相关文章

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

Java空指针异常NullPointerException的原因与解决方案

《Java空指针异常NullPointerException的原因与解决方案》在Java开发中,NullPointerException(空指针异常)是最常见的运行时异常之一,通常发生在程序尝试访问或... 目录一、空指针异常产生的原因1. 变量未初始化2. 对象引用被显式置为null3. 方法返回null

C/C++中OpenCV 矩阵运算的实现

《C/C++中OpenCV矩阵运算的实现》本文主要介绍了C/C++中OpenCV矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下... 目录矩阵的创建与初始化创建矩阵访问矩阵元素基本的算术运算 ➕➖✖️➗矩阵与标量运算矩阵与矩阵运算 (逐元

JAVA数组中五种常见排序方法整理汇总

《JAVA数组中五种常见排序方法整理汇总》本文给大家分享五种常用的Java数组排序方法整理,每种方法结合示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录前言:法一:Arrays.sort()法二:冒泡排序法三:选择排序法四:反转排序法五:直接插入排序前言:几种常用的Java数组排序

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代

go 指针接收者和值接收者的区别小结

《go指针接收者和值接收者的区别小结》在Go语言中,值接收者和指针接收者是方法定义中的两种接收者类型,本文主要介绍了go指针接收者和值接收者的区别小结,文中通过示例代码介绍的非常详细,需要的朋友们下... 目录go 指针接收者和值接收者的区别易错点辨析go 指针接收者和值接收者的区别指针接收者和值接收者的

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

Java Optional避免空指针异常的实现

《JavaOptional避免空指针异常的实现》空指针异常一直是困扰开发者的常见问题之一,本文主要介绍了JavaOptional避免空指针异常的实现,帮助开发者编写更健壮、可读性更高的代码,减少因... 目录一、Optional 概述二、Optional 的创建三、Optional 的常用方法四、Optio