ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C语言 - 二重指针,二维数组

2021-07-15 09:01:53  阅读:171  来源: 互联网

标签:p1 指向 int 二重 C语言 二维 数组 指针


1.二重指针

(1)二重指针与普通一重指针的区别

->本质上来说,二重指针和一重指针的本质都是指针变量,指针变量的本质就是变量。

->一重指针变量和二重指针变量本身都占4字节内存空间。

(2)二重指针的本质

->二重指针本质上也是指针变量,和普通指针的差别就是它指向的变量类型必须是个一重指针

(3)二重指针的用法: 

二重指针指向一重指针的地址.:

	char a;
	char **p1;		// 二重指针
	char *p2;		// 一重指针
	
	printf("sizeof(p1) = %d.\n", sizeof(p1));    //4
	printf("sizeof(p2) = %d.\n", sizeof(p2));     //4
	
	p2 = &a;
	//p1 = &a;		// p1是char **类型,&a是char *类型。
					// char **类型就是指针指向的变量是char *类型
					// char *类型表示指针指向的变量是char类型。
	p1 = &p2;		// p2本身是char *类型,再取地址变成char **类型,和p1兼容。

二重指针指向指针数组:

int *p1[5];	
int **p3;
p3 = p1;		// p1是指针数组名,本质上是数组名,数组名做右值表示数组首元素
				// 首地址。数组的元素就是int *类型,所以p1做右值就表示一个int *
				// 类型变量的地址,所以p1就是一个int类型变量的指针的指针,所以
				// 它就是一个二重指针int **;

实践编程中有时在函数传参时为了通过函数内部改变外部的一个指针变量,会传这个指针变量的地址(也就是二重指针)进去

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,但是这个地址是不
								// 允许访问的,因此会段错误。
	return 0;
}


2.二维数组

(1)二维数组的内存映像:

 

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]

->一维数组在内存中是连续分布的多个内存单元组成的,而二维数组在内存中也是连续分布的多个内存单元组成的。

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

->二维数组a和一维数组b在内存使用效率、访问效率上是完全一样的(或者说差异是忽略不计的)。

->在某种情况下用二维数组而不用一维数组,原因在于二维数组好理解、代码好写、利于组织(比如图片的显示)。

(2)哪个是第一维哪个是第二维:

->二维数组int a[2][5]中,2是第一维,5是第二维。

->二维数组的第一维是最外部的那一层第一维本身是个数组,这个数组中存储的元素也是个一维数组二维数组的第二维是里面的那一层,第二维本身是个一维数组,数组中存的元素是普通元素,第二维这个一维数组本身作为元素存储在第一维的二维数组中。

(3)二维数组的下标式访问和指针式访问 

->回顾:一维数组的两种访问方式:

以int b[10]为例, int *p = b;。
b[0] 等同于 *(p+0);   b[9] 等同于 *(p+9);  b[i] 等同于 *(p+i)

->二维数组的两种访问方式:

以int a[2][5]为例,(合适类型的)p = a;
a[0][0]等同于*(*(p+0)+0); 	a[i][j]等同于 *(*(p+i)+j)

(4)指针指向二维数组的数组名

->二维数组的数组名表示二维数组的第一维数组中首元素(也就是第二维的数组)的首地址,即为数组指针(数组的地址)

->二维数组的数组名a等同于&a[0],这个和一维数组的符号含义是相符的。

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

->用int *p来指向二维数组的第一维a[i],就是一个一维的指针。

(6)指针指向二维数组的第二维

#include <stdio.h>

int main(void)
{
	int a[2][5] = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}};
	
	printf("a[1][3] = %d.\n", a[1][3]);       //9
	printf("a[1][3] = %d.\n", *(*(a+1)+3));   //9
	
	//int *p1 = a;		// 类型不匹配
	//int **p2 = a;		// 类型不匹配,会报警告
	
	// 指针指向二维数组的数组名
	int (*p3)[5];		// 数组指针,指针指向一个数组,数组有5个int类型元素
	p3 = a;				// a是二维数组的数组名,作为右值表示二维数组第一维的数组
						// 的首元素首地址,等同于&a[0]
	p3 = &a[0];
	
	printf("a[0][3] = %d.\n", *(*(p3+0)+3));      //4
	printf("a[1][4] = %d.\n", *(*(p3+1)+4));      //10
	
	// 指针指向二维数组的第一维
	//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));     //5

	// 指向二维数组的第二维
	int *p6 = a[1];
	printf("a[1][1] = %d.\n", *(p6+1));     //7

	return 0;
}

标签:p1,指向,int,二重,C语言,二维,数组,指针
来源: https://blog.csdn.net/weixin_49303682/article/details/118741026

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有