深入理解指针(1)

      指针,一般是代指针变量,指针是C语言中至关重要的一部分。由于内容较多,且较难,所以我们掰开了揉碎了慢慢讲,今天我们开始先讲解字符指针,指针数组,数组指针。

   一、字符指针

指针与数据类型相同,有多种分类

int a = 0;
int* pd = &a; // 取a的地址,并将其存入指针变量pd中

double b = 5.20;
double* pb = &b; // 取b的地址

float c = 13.14;
float* pc = &c; // 取c的地址

char ch = 'w';
char* ph = &ch; // 取ch的地址 

这些常见的指针变量我们很好理解,但是请看下列代码,并思考一下存在指针变量中的是什么

char* ph = “Hello bit!” // 思考一下,存在ph中的是什么呢?

存的是一个字符串吗?存的是整个字符串的地址吗?还是字符' H '?

我们写一段代码来看一下

#include
int main()
{
	char* ph = "Hello bit";
	printf("%p ",ph);
	return 0;
}

深入理解指针(1)_第1张图片

我们不难发现,存入其中的还是地址,大家猜猜,存的是谁的地址呢?没错其实存的就是第一个字符的地址,当把一个常量字符串传给一个指针变量的时候,存入指针变量的就是常量字符串的第一个字符的地址。

怎么证明呢?我们可以尝试打印一下整个字符串

int main()
{
	char* ph = "Hello bit";
	printf("%p \n",ph);
	printf("%s ",ph);
	return 0;
}

深入理解指针(1)_第2张图片

打印字符串的规律,是从第一个字符开始,当遇到\0时停止打印,从这里就可以看出来指针变量ph中存放的就是常量字符的第一个字符的地址。

这里我们放一道经典面试题

	// 一个经典面试题
	char str1[] = "Hello world!";
	char str2[] = "Hello world!";
	if (str1 == str2)// 数组的名字就是数组第一个元素的地址
		             // 创建两个数组就是开辟了两块内存空间,所以两个数组的地址不同
	{
		printf("str1 is the same as str2\n");
		printf("str1 的地址是%p\n", str1);
		printf("str2 的地址是%p\n", str2);
	}
	else
	{
		printf("str1 is not the same as str2\n");
		printf("str1 的地址是%p\n", str1);
		printf("str2 的地址是%p\n", str2);
	}


	const char* str3 = "Hello world!";
	const char* str4 = "Hello world!";
	if (str3 == str4) // 常量字符不可以改变,所以一般会共同使用一个常量字符
	{
		printf("str3 is the same as str4\n");
		printf("str3 的地址是%p\n", str3);
		printf("str4 的地址是%p\n", str4);
	}
	else
	{
		printf("str3 is not the same as str4\n");
		printf("str1 的地址是%p\n", str3);
		printf("str2 的地址是%p\n", str4);
	}
	return 0;
}

大家先不要看后面解释,自己考虑一下答案

深入理解指针(1)_第3张图片 

观看上面打印结果和代码的注释,我相信你们一定可以理解上面的题。

二、指针数组

指针数组,数组数组,顾名思义是一个数组,这个数组是专门存放指针的

int main()
{
	char* arr[4] = {"How are you?", "I'm fine", "Thank you", "And you?"};
	int i = 0;
	for (i = 0; i < 4; i++)
	{
		printf("%s 的第一个字符的地址是%p \n",arr[i],arr[i]); 
	}
	return 0;
}

这里我们客串一下上面讲的字符指针,在学完上面的一节,我们知道在cahr* arr[4]这一个指针数组存放的是每一个字符串的第一个的字符的地址,我们打印出来观察结果

深入理解指针(1)_第4张图片为了更好的理解指针数组,我选择了用一维数组模拟二维数组这一个例子来演示

int arr1[3] = { 1, 2, 3 };
int arr2[3] = { 4, 5, 6 };
int arr3[3] = { 7, 8, 9 };
int* arr_num[3] = { arr1,arr2,arr3 };
int k = 0;
for (k = 0; k < 3; k++)
{
	int j = 0;
	for (j = 0; j < 3; j++)
	{
		printf("%d ",arr_num[k][j]);
	}
	printf("\n");
}

 

 在上述代码,我们把arr1,arr2,arr3 的首元素的地址存放在指针数组int* arr_num[3]中,我们可以通过使用二维数组的方式使用它,运行结果如下

深入理解指针(1)_第5张图片

在这里我值得注意的是,arr_num[k][j]可以改写成 *(arr_num[k]+j)

arr_num[k] + j 代表的数组中每一个元素的地址*(arr_num[k] + j)则是解引用,即是数组中的每一个元素。

三、数组指针

看到这里的朋友们可能会产生疑问了,数组指针~指针数组,他们两个有什么关系吗?

实际上是,一点关系也没有,数组指针,则是指向数组的一种指针。请看代码

int main()
{
	 数字类型的指针有 int* double* float*
	//int a = 0;
	//int* num = &a;



	 字符的指针是char*
	//char ch = 'W';
	//char* pch = &ch;
	


	 指针数组,存放指针变量的数组
	//int arr1[3] = {1 ,2 ,3 };
	//int arr2[3] = {4 ,5 ,6 };
	//int* arr_num[2] = {arr1, arr2};



	// 数组指针,指向数组地址的指针
	int num[3] = {1,2,3};
	int(*arr_num)[10] = #
	printf("%p \n",arr_num);       // 打印结果明显与下面不同啊,下面打印首元素的地址,加1只是 
                                   // 加4个字节(int)
	printf("%p \n", arr_num + 1);  // 而这个的加多少取决于数组的字节大小(int 4 * 3 = 12)
	                               // &数组名 -- 是数组的地址; 数组名 -- 数组首元素的地址
								   // 数组的地址与数组首元素的地址在数值上是相同的, 但意义上 
                                   // 不同
	                               

	printf("%p \n",&num[0]);
	printf("%p \n", &num[0] + 1);


	printf("%p \n",num);
	printf("%p \n", num + 1);
	return 0;
}

这里是指针变量的使用

void Print_1(int arr[3][4],int x, int y)
{
	int i = 0;
	for (i = 0; i < x; i++)
	{
		int j = 0;
		for (j = 0; j < y; j++)
		{
			printf("%d ",arr[i][j]);
		}
		printf("\n");
	}

}


void Print_2(int (*pt)[4], int x, int y)
{
	int i = 0;
	for (i = 0; i < x; i++)
	{
		int j = 0;
		for (j = 0; j < y; j++)
		{
			printf("%d ", (*(pt + i))[j]);// 二维数组名代表的二维数组第一行的地址
			                              // 数组指针 +1 代表跳过一行数组
			                              // 所以 pt + i 是第i行数组
		}
		printf("\n");
	}
}





int main()
{
	int arr_num[3][4] = { {1, 2, 3, 4},{4, 5, 6, 7},{7, 8, 9, 0}};
	Print_1(arr_num,3 ,4);
	Print_2(arr_num,3 ,4);
	return 0;
}

 

今天的分享就到这里咯,喜欢的伙伴们记得评论点赞奥。

 

 

 

 

 

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