C语言中的多维数组与指针解析

引言:

在这一部分,我们将进一步探讨多维数组和指针的概念,并引入一个新的函数 printf1,该函数以数组形式的参数来打印二维数组。

函数1:printf1

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

这个函数接受一个二维数组 arr 和两个整数 xy 作为参数。通过嵌套循环,它遍历整个数组并使用 printf 函数输出每个元素的值。注释提供了关于循环结构的说明,以及函数参数的含义。

解析:

  • int arr[3][3]:函数参数 arr 是一个包含3行3列的二维整型数组。
  • int x, int yxy 是指定数组维度的整数参数,分别代表数组的行数和列数。
  • for (int i = 0; i < x; i++):外层循环遍历数组的每一行,i 是行索引。
  • for (int j = 0; j < y; j++):内层循环遍历当前行的每一列,j 是列索引。
  • printf("%d ", arr[i][j]);:输出当前行列的元素值。
  • printf("\n");:在每行结束后输出换行符,实现格式化输出。

通过这种方式,printf1 函数能够灵活地处理不同维度的二维数组,提供了一种通用的打印函数。

在C语言中,多维数组的行数通常作为函数参数传递,以便在处理不同大小的数组时保持灵活性。函数体内的循环结构使得该函数适用于不同大小的二维数组。

函数2:printf2 - 使用指针形式的参数

在前面的代码中,我们已经演示了如何使用数组形式的参数打印二维数组。现在,我们将引入另一个函数 printf2,该函数使用指针形式的参数。

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

解析:

  • int(*p)[3]:函数参数 p 是一个指向包含3个整数的数组的指针。
  • int x, int yxy 依然是指定数组维度的整数参数,分别代表数组的行数和列数。
  • for (int i = 0; i < x; i++):外层循环遍历数组的每一行,i 是行索引。
  • for (int j = 0; j < y; j++):内层循环遍历当前行的每一列,j 是列索引。
  • printf("%d ", p[i][j]);:通过指针形式访问数组元素的值并输出。
  • printf("\n");:在每行结束后输出换行符,实现格式化输出。

函数 printf2 中使用的是指针形式的参数,使得我们可以通过不同的方式来访问二维数组的元素。这里提供了三种等价的写法,分别是指针算术和数组下标的不同表示方式。

这两个函数展示了C语言中对于多维数组的不同参数传递方式,以及如何通过指针来处理数组元素。这对于理解C语言中的数组和指针的交互至关重要。

演示数组和指针的等价性

int main() {
    int arr[5] = { 1,2,3,4,5 };
    int* p = &arr;

    for (int i = 0; i < 5; i++) {
        // 等价写法
        printf("%d ", *(p + i));
        printf("%d ", p[i]);
        printf("%d ", *(arr + i));
        printf("%d ", arr[i]);
    }

    return 0;
}

解析:

  • int arr[5]:定义了一个包含5个整型元素的数组 arr
  • int* p = &arr;:定义了一个指针 p,指向数组 arr 的首元素。
  • for (int i = 0; i < 5; i++):循环遍历数组元素。
  • printf("%d ", *(p + i));:使用指针算术访问数组元素并输出。
  • printf("%d ", p[i]);:使用数组下标访问数组元素并输出。
  • printf("%d ", *(arr + i));:使用指针算术访问数组元素并输出。
  • printf("%d ", arr[i]);:使用数组下标访问数组元素并输出。

通过这个示例,我们展示了通过指针和数组下标两种方式来访问数组元素的等价性。在C语言中,数组名本身就是一个指针,可以通过指针的方式进行访问。

知识扩展:指针和数组的声明

int arr[5];
int* p1[10];
int(*p2)[10];
int(*p3[10])[5];

解析:

  1. int arr[5];:简单的整型数组声明,包含5个元素。
  2. int* p1[10];:数组 p1 包含10个指向整型变量的指针。
  3. int(*p2)[10];:指针 p2 指向一个包含10个整型元素的数组。
  4. int(*p3[10])[5];:数组 p3 包含10个指向包含5个整型元素的数组的指针。
p3[0]    p3[1]    p3[2]    p3[3]    p3[4]    p3[5]    p3[6]    p3[7]    p3[8]    p3[9]
  ↓        ↓        ↓        ↓        ↓        ↓        ↓        ↓        ↓        ↓
+---+    +---+    +---+    +---+    +---+    +---+    +---+    +---+    +---+    +---+
|   |    |   |    |   |    |   |    |   |    |   |    |   |    |   |    |   |    |   |
+---+    +---+    +---+    +---+    +---+    +---+    +---+    +---+    +---+    +---+
  ↑        ↑        ↑        ↑        ↑        ↑        ↑        ↑        ↑        ↑
  |        |        |        |        |        |        |        |        |        |
  ↓        ↓        ↓        ↓        ↓        ↓        ↓        ↓        ↓        ↓
+---+    +---+    +---+    +---+    +---+    +---+    +---+    +---+    +---+    +---+
|   |    |   |    |   |    |   |    |   |    |   |    |   |    |   |    |   |    |   |
+---+    +---+    +---+    +---+    +---+    +---+    +---+    +---+    +---+    +---+
 ^        ^        ^        ^        ^        ^        ^        ^        ^        ^
 |        |        |        |        |        |        |        |        |        |
 +--------+--------+--------+--------+--------+--------+--------+--------+--------+

代码展示:

//数组指针
int main() {
	int* p = NULL;//p是整形指针-指向整形的指针 - 可以存整形地址
	char* pp = NULL;//pp是字符指针-指向字符的指针 - 可以存字符地址
					//数组指针 - 指向数组的指针 - 可以存数组地址

	int arr[10] = { 0 };
	//arr - 首元素地址
	//arr[0] - 首元素地址
	//&arr - 数组地址

	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
	int (*p)[10] = &arr;//()提升优先级 -- (*p)表示指针变量
	return 0;
}




int main() {
	int arr[10];
	int(*pp)[10] = &arr;

	char* arr[5];
	char* (*pa)[5] = &arr;
	//pa--指针变量名
	//* -- 指针
	//[5] -- pa指向的数组是5个元素
	//char* -- pa指向数组元素类型

	return 0;
}






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

	int(*pa)[5] = &arr;
	for (int i = 0; i < 5; i++)
	{
		//printf("%d\t", (*pa)[i]);//打印pa指向的i个元素
		//printf("%d\t", *(*pa + i));//*pa+i   == arr+i
	}

	int arr[5] = { 1,2,3,4,5 };
	int* p = arr;
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", *(p + i));
	}
}



//数组形式的参数
void printf1(int arr[3][3], int x, int y) {
	for (int i = 0; i < x; i++)
	{
		for (int j = 0; j < y; j++) {
		
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	} 
 }

//指针形式参数
void printf2(int(*p)[3], int x, int y) {
	//把二维数组想象成一维数字
	//p -- arr是第一行的第一个元素的地址
	for (int i = 0; i < x; i++)
	{
		for (int j = 0; j < y; j++) {

			//第一种
			//printf("%d ", *(*(p + i) + j));//*(p + 1)--每行的首元素   +j--打印每行的的每个元素
			
			//第二种
			//printf("%d ", (*(p + i))[j
			
			//第三种
			printf("%d ", p[i][j]);
		}
		printf("\n");
	}
}
int main() {
	int arr[3][3] = { {1,1,1},{2,2,2},{3,3,3} };
	printf1(arr, 3, 3);
	printf2(arr, 3, 3);
	return 0;
}




int main() {
	int arr[5] = { 1,2,3,4,5 };
	int* p = &arr;
	//arr[i] == *(arr+1) == *(p + i) = p[i]
	for (int i = 0; i < 5; i++)
	{
		//等价
		printf("%d ", *(p + i));
		
		printf("%d ", p[i]);
	
		printf("%d ", *(arr + i));

		printf("%d ", arr[i]);
	}

	return 0;
}


int arr[5];:简单的整型数组声明,包含5个元素。
int* p1[10];:数组 p1 包含10个指向整型变量的指针。
int(*p2)[10];:指针 p2 指向一个包含10个整型元素的数组。
int(*p3[10])[5];:数组 p3 包含10个指向包含5个整型元素的数组的指针。

这些声明展示了指针和数组在声明时的不同形式,加深了对C语言中复杂声明的理解。这对于理解涉及指针和数组的更复杂的数据结构是非常有用的。

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