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

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

相关文章

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

poj2576(二维背包)

题意:n个人分成两组,两组人数只差小于1 , 并且体重只差最小 对于人数要求恰好装满,对于体重要求尽量多,一开始没做出来,看了下解题,按照自己的感觉写,然后a了 状态转移方程:dp[i][j] = max(dp[i][j],dp[i-1][j-c[k]]+c[k]);其中i表示人数,j表示背包容量,k表示输入的体重的 代码如下: #include<iostream>#include<

hdu2159(二维背包)

这是我的第一道二维背包题,没想到自己一下子就A了,但是代码写的比较乱,下面的代码是我有重新修改的 状态转移:dp[i][j] = max(dp[i][j], dp[i-1][j-c[z]]+v[z]); 其中dp[i][j]表示,打了i个怪物,消耗j的耐力值,所得到的最大经验值 代码如下: #include<iostream>#include<algorithm>#include<

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

uva 575 Skew Binary(位运算)

求第一个以(2^(k+1)-1)为进制的数。 数据不大,可以直接搞。 代码: #include <stdio.h>#include <string.h>const int maxn = 100 + 5;int main(){char num[maxn];while (scanf("%s", num) == 1){if (num[0] == '0')break;int len =