C语言指针进阶之二指针数组与数组指针

                                   C语言指针进阶之二指针数组与数组指针_第1张图片

目录

1.指针知识回顾 

2.指针数组

3.数组指针

3.1数组指针的引入

3.1.1  数组名含义的复习与补充

3.1.2 数组指针的形式 

3.2数组指针的应用场景


1.指针知识回顾 


①.指针就是个变量,用来存放地址,地址唯一标识了一片空间。

  内存会划分成一个个的内存单元,每个内存单元都有一个独立的编号,编号也称为地址,而C语言也把地址叫做指针。地址(指针)需要存储在变量中,这个变量就被称为指针变量。

例如:

int  a = 10;

int * p = &a;

这里的p就是一个指针变量

     

②指针的大小是固定的4/8字节(32位平台、64位平台)

    地址是由物理的电线产生的(高低频的电信号),32位机器对应的就是32根地址线,产生32个0/1序列,32个0/1组成的二进制序列,把这个二进制序列就作为地址,32个bit位才能存储这个地址也就是需要8个字节才能存储,所以在32位机器下,地址的大小就是4个字节。

而对于64位机器来说, 对应的就是32根地址线,产生64个0/1序列,64个0/1组成的二进制序列,把这个二进制序列就作为地址,64个bit位才能存储这个地址也就是需要8个字节才能存储,所以在64位机器下,地址的大小就是8个字节。

③指针是有类型的,指针的类型决定了指针的+-整数的步长,指正解引用操作时候的权限。

列如一个字符类型的数据解引用只可以访问一个字节的内存空间 

2.指针数组

指针数组:是一个存放指针的数组(注意:数组的每一个元素类型都是相同的)

简单理解:就是一个数组中的每一个元素都是一个指针(都是一个地址),,指针数组,重点是数组。看代码举例

C语言指针进阶之二指针数组与数组指针_第2张图片

指针数组在访问元素时遵循数组的规则。附上源码,大家也可以自行研究(特别容易纠缠就是数组元素地址与元素本身,因为指针数组中,每一个元素都是地址,不熟悉在有些题型中会容易混淆,在今天的第二篇文章中,我给大家分享的就是今早我进入的漩涡,蛮有趣就像脑筋急转弯一样,大家也可以从这个链接进入【C语言指针数组的一篇补充 - CSDN App】http://t.csdnimg.cn/brzId,更好的理解指针与指针数组。) 

源码:

int main()
{
	int a = 1;
	int b = 2;
	int c = 3;
	int* arr[] = { &a,&b,&c };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		printf("%d ", *arr[i]);
	}
	printf("\n");
	int* p1 = &a;
	int* p2 = &b;
	int* p3 = &c;
	int* arr2[] = { p1,p2,p3 };
	int j = 0;
	for (j = 0; j < 3; j++)
	{
		printf("%d ", *arr2[j]);
	}
	return 0;
}

3.数组指针

数组指针是一个指针。指向一个数组。

3.1数组指针的引入

我们知道:

①整型指针:int * p,是一个保存整型变量地址的指针变量,指向一个整型数据。

②字符型指针:char * p,保存了一个字符型数据地址的指针变量,指向一个字符型数据的指针。

那么我们的数组也有地址呀,我们也可以通过地址来访问数组或者进行传参,那么就需要一个可以指向数组的指针,也就可以称之为数组指针了。

3.1.1  数组名含义的复习与补充

我们都知道数组名代表了数组首元素的地址,那么我们来看一下接下来的这个代码:

C语言指针进阶之二指针数组与数组指针_第3张图片

说明:

数组名表示数组首元素的地址,但是有两个地方是例外的:

①&数组名:这里的数组名表示整个数组,得到的是整个数组的地址

②sizeof(数组名);这里的数组名表示的是整个数组。得到的是整个数组的大小,单位是字节。

附上源码大家体验:

/*printf("%p\n", arr);
printf("%p\n", &arr);
printf("%p\n", arr+1);
printf("%p\n", (&arr + 1));
printf("%d\n", sizeof(arr[0]));
printf("%d\n", sizeof(arr));*/

3.1.2 数组指针的形式 

现在得到了数组的地址,那么要将这个数组的地址放在一个指针变量里面去,这个变量的类型该如何书写呢?

很多伙伴可能会这样想:

比如我们有一个整形数组int arr[10] = { 0 };

那么直接把地址给一个整型的指针变量
int* p = &arr;

但是接下来我们看看发生什么事:

左边的数据类型和右边的数据类型不相同,没有数组指针以前我们在数组中使用指针是将首元素的地址就是数组名给了一个指针变量进行操作,这里不能混淆。

引入列子:

int *p1[10]

int (*p)[10] 这两个哪个是数组指针呢?

补充:

[]的优先级要高于*号

那么,从运算符解释:第一个表达式p1先和【】结合,说明p1是一个数组,这个数组的类型是int * 【10】,这就是一个指针数组是一个数组。

对于第二个表达式来说,p先和*结合说明P是一个指针,然后是指向一个类型为int  【10】的数组,所以p是一个指针,一个数组指针。

所以我们就得到了数组指针的形式:类型(*)[]. 

3.2数组指针的应用场景

一维数组,极少使用数组指针,只有二维及以上的数组使用数组指针是比较方便的。

补充:二维数组可以理解为一维数组的数组。

大家也可以访问我的这篇文章进行知识补充【C语言基础 -数组 - CSDN App】http://t.csdnimg.cn/Lxht0

我们下面来看一下1数组指针在二维数组中的使用:二维数组的传参,形参是指针的形式

C语言指针进阶之二指针数组与数组指针_第4张图片

对代码的理解:

我们将这个二维数组看做是由三个含有五个整型的一维数组组成的数组,那么我们传参arr,相当于我们传过去的是首元素的地址就可以看做是我们的第一行数据这个数组的地址,那么,应该1数组的地址就可以用一个数组指针来接收。这是关于传参。

那么我们的*(p+i),就可以访问到第一行,第二行,第三行的数据也就三个一维数组的地址 ,*(*(p+i)+j)可以访问到所有元素了。

附上源码,大家可以体验:

void print_l(int(*p)[5], int r, int l)
{
	int i = 0;
	for (i = 0; i < r; i++)
	{
		int j = 0;
		for (j = 0; j < l; j++)
		{
			printf("%d ", *(*(p+i) + j));
		}
		printf("\n");
	}

}
int main()
{
	int arr[3][5] = { 0,1,2,3,4,1,2,3,4,5,2,3,4,5,6};
	print_l(arr, 3, 5);
    return 0;
}

以上就是本期所有内容,欢迎大家指正与讨论互相学习。 

你可能感兴趣的:(c语言,算法,开发语言)