指针的进阶(C语言)(上)

目录

前言

1、字符指针

2、指针数组

3、数组指针

3.1数组指针的定义

3.2 数组名VS&数组名

3.3数组指针的运用


前言

        对于指针,我们已经有了初步认识(可以看我写的指针详解那一篇文章)。

简单总结一下基本概念:

        1、指针就是一个变量,用来存放地址,地址唯一标识一块空间。

        2、指针的大小是4/8个字节(32位平台为4字节,64位平台为8字节)

        3、指针是有类型的,指针的类型决定了指针的+-的步长以及指针解引用操作时候计算机如何看待指针所指向的内容。

        4、指针的运算(指针+-常数;指针-指针;指针与指针的比较)

        对于基本概念了解后,现在我们进行指针进阶,对指针进行进一步的深入分析。

1、字符指针

        举例两种用法:

        第一种,指向字符变量,可以操作字符变量。

#include
int main()
{
	char ch = "w";
	char* pc = &ch;
	*pc = 'b';
	printf("%c\n", ch);
	return 0;
}

        还有一种,指向字符串。

#include 
int main()
{
	const char* p = "abcdef";
	printf("%s\n", p);
	return 0;
}

        第二种用指针指向字符串,实际上是把字符串首元素的地址传给了指针变量。而对于常量符串来说,其内容不可被更改,因此用const'修饰*p表示*p的无法更改。

        看一个例子:

        指针的进阶(C语言)(上)_第1张图片

        原因:对于常量字符串,放在内存的只读数据区里面,这个空间只能读不能写,只能用不能改变其内容,对于同样的常量字符串,会放在同一个地址,因此p1和p2指向同一个地址,因此p1==p2。

        但是对于arr1和arr2来说,它们是被创建的两个数组,自然会在内存中开辟不同的地址,“abcdef”只不过是对其的初始化而已。所以这两个数组的首元素地址是不同的。

2、指针数组

        是数组,是用来存放指针的数组。

int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,4,5,6,7 };

	int* parr[3] = { arr1,arr2,arr3 };

	int i = 0;
	int j = 0;
	for (i = 0;i < 3;i++)
	{
		for (j = 0;j < 5;j++)
		{
			printf("%d ", *(parr[i] + j));
		}
		printf("\n");
	}

	return 0;
}

        parr就是一个指针数组,它的内部存放了三个地址。

指针的进阶(C语言)(上)_第2张图片

        对每个地址进行访问,就能打印出所有元素的值。其实对于指针数组来讲,它其实是模拟了一个二维数组。访问时可以直接用parr[i][j];效果完全相同。

3、数组指针

        是指针,是指向数组的指针。

3.1数组指针的定义

        int* p1[10];                       p1是指针数组

        int (*p2)[10];                    p2是数组指针

       p2数组指针可以指向一个数组,该数组有10个元素,每个元素是int类型

        要将明白数组指针,必须要先弄懂数组名的概念。

3.2 数组名VS&数组名

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

        1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。

        2.&数组名,这里的数组名表示的依然是整个数组,所以&数组名取出的是整个数组的地址

指针的进阶(C语言)(上)_第3张图片

        &数组名从值上来看,和数组名是一样的,都表示了数组首元素的地址,但是,他们的区别是什么?我们都加一看看。

  、指针的进阶(C语言)(上)_第4张图片

        我们发现,arr加1加了4,而&arr加1加了40。由此我们知道,&数组名之后,它会表示整个数组的地址,+1直接跳过整个数组。

        那么想&arr这样的数据,如果我们想用变量去存放它,我们该用什么变量去存放它呢。答案就是数组指针。“数组指针就是指向数组的指针”,这样我们便理解了这句话。

int(*p2)[10] = &arr;

        这样去定义就能存放&arr,不加括号p2会优先和[]结合成为数组,因此需要用括号将*和p2括起来,确保其是一个指针,后面[]中放的数是arr的元素个数。int指的是arr元素的类型。

3.3数组指针的运用

         指针的进阶(C语言)(上)_第5张图片

        这是一个运用的例子,有几个要注意的点。1、在定义数组指针时,[]中必须指明数组的元素个数。2、在输出时,一定要将*p用()括起来,不然p会优先和[]结合,变成野指针。

        但是我们一般不这么使用,因为用指针访问数组只需要用*p指向arr就好了。

        数组指针不是应用在这种情况的,数组指针一般运用在二维及以上的数组处理。

指针的进阶(C语言)(上)_第6张图片

        这个例子告诉我们,当函数传参时二维数组时,形参可以用数组指针去接收。这样去使用数组指针是最舒适的。

        到此,指针进阶(一)结束,后面还有两篇进行讲解,还包括的内容有函数传参如何用指针接收、函数指针、函数指针数组、指向函数指针数组的指针、回调函数。

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