指针与数组的关系(指针数组、数组指针),附常见的数组的笔试题

紧接着上一篇指针的讲解,我们再来谈谈指针与数组的关系
首先,我们都知道数组在内存中是连续存放的,所以只要我们找到这个数组的首元素地址,是不是就可以找到整个数组呢?

答案是肯定的

//对于这个整形数组,它的首元素地址则是&arr[0]
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
printf("%p\n", arr);
printf("%p\n", &arr[0]);

数组名与首元素地址相同,可以得出结论:数组名表示的是数组首元素的地址

那么我们就可以这样写代码了 int *p = arr; //p存放的是数组首元素的地址

指针和数组

既然可以把数组名当作地址存放在一个指针里,那我们就可以使用指针来访问这个数组

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	int *p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < sz; i++)
	{
		printf("&arr[%d] = %p  <==> p + %d = %p\n", i, &arr[i], i, p + i);
	}
	return 0;
}

指针与数组的关系(指针数组、数组指针),附常见的数组的笔试题_第1张图片
我们可以从上面的例子看出来, p+i 计算的是数组 arr 下标为i的地址
那么我们就可以通过指针去访问数组

for (int i = 0; i < sz; i++)
{	
	printf("%d ", *(p + i));
}
  • 指针数组

首先,你得知道指针数组是一个数组还是指针?
答案是数组,是一个存放指针的数组
指针与数组的关系(指针数组、数组指针),附常见的数组的笔试题_第2张图片
我的上一篇讲指针的博客,就有提到,要理解指针要从四个方面理解,指针的类型、指针指向的类型、指针所指向的内存区、指针本身所占据的内存区。 我们重点看一下类型

这里
指针的类型:int* [6]
指针指向的类型:int*

arr是一个数组,有六个元素,每一个元素里是一个整形指针

  • 数组指针

既然指针数组,是数组,那数组指针毋庸置疑,肯定是指针了
能够指向数组的指针

[ ]优先级比*高

int (*arr)[6]
//arr先与*结合,说明arr是一个指针变量,指向一个大小为6个整型的数组
//所以arr是一个指针,指向一个数组,叫做指针数组

刚刚有提到过arr数组名表示的意义是首元素的地址,那&arr的意义是什么呢?

int main()
{ 
	int arr[10] = { 0 };
	printf("arr = %p\n", arr);
	printf("&arr= %p\n", &arr);
	printf("arr+1 = %p\n", arr + 1);
	printf("&arr+1= %p\n", &arr + 1);
	return 0;
}

可以从上面的例子看出来,&arr 表示的是数组的地址,而不是数组首元素的地址。数组的地址+1,跳过整个数组的大小,对于&arr来说,与&arr+1的差值为40。

数组指针的使用
void print_arr1(int arr[3][5], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}
//需要接受二维数组的地址,用一个数组指针
//把二维数组想象成一维数组
//arr相当于一维数组的首元素(每一行有三个元素)
void print_arr2(int(*arr)[5], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		//arr+0 --->第一行   arr+1 --->第二行 ...   
		//arr+i 第i行的地址   *(arr+i) 第i行的元素 
 		for (int j = 0; j < col; j++)
		{
		//*(arr+i)+j  第i行下标为j的地址    *(*(arr+i)+j)  访问第i行下标为j的元素
			printf("%d ", *(*(arr + i) + j));
		}
		printf("\n");
	}
}

int main()
{
	int arr[3][5] = { 1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10 };
	print_arr1(arr, 3, 5);
	print_arr2(arr, 3, 5);
	return 0;
}
数组笔试题及解析
//一维数组
int a[] = {1,2,3,4}; 
printf("%d\n",sizeof(a)); 
printf("%d\n",sizeof(a+0)); 
printf("%d\n",sizeof(*a)); 
printf("%d\n",sizeof(a+1)); 
printf("%d\n",sizeof(a[1])); 
printf("%d\n",sizeof(&a)); 
printf("%d\n",sizeof(*&a));
printf("%d\n",sizeof(&a+1)); 
printf("%d\n",sizeof(&a[0])); 
printf("%d\n",sizeof(&a[0]+1));



//字符数组
char arr[] = {'a','b','c','d','e','f'}; 
printf("%d\n", sizeof(arr)); 
printf("%d\n", sizeof(arr+0)); 
printf("%d\n", sizeof(*arr)); 
printf("%d\n", sizeof(arr[1])); 
printf("%d\n", sizeof(&arr)); 
printf("%d\n", sizeof(&arr+1));
printf("%d\n", sizeof(&arr[0]+1));

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



char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr+0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr+1));
printf("%d\n", sizeof(&arr[0]+1));

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



char *p = "abcdef";
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(p+1));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p+1));
printf("%d\n", sizeof(&p[0]+1));

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



//二维数组
int a[3][4] = {0}; 
printf("%d\n",sizeof(a)); 
printf("%d\n",sizeof(a[0][0])); 
printf("%d\n",sizeof(a[0])); 
printf("%d\n",sizeof(a[0]+1)); 
printf("%d\n",sizeof(*(a[0]+1))); 
printf("%d\n",sizeof(a+1)); 
printf("%d\n",sizeof(*(a+1)));
printf("%d\n",sizeof(&a[0]+1));
printf("%d\n",sizeof(*(&a[0]+1)));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(a[3]));

总结: 数组名的意义:

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址

你可能感兴趣的:(C,指针与数组)