在这一部分,我们将进一步探讨多维数组和指针的概念,并引入一个新的函数 printf1
,该函数以数组形式的参数来打印二维数组。
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
和两个整数 x
、y
作为参数。通过嵌套循环,它遍历整个数组并使用 printf
函数输出每个元素的值。注释提供了关于循环结构的说明,以及函数参数的含义。
int arr[3][3]
:函数参数 arr
是一个包含3行3列的二维整型数组。int x, int y
:x
和 y
是指定数组维度的整数参数,分别代表数组的行数和列数。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语言中,多维数组的行数通常作为函数参数传递,以便在处理不同大小的数组时保持灵活性。函数体内的循环结构使得该函数适用于不同大小的二维数组。
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 y
:x
和 y
依然是指定数组维度的整数参数,分别代表数组的行数和列数。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];
int arr[5];
:简单的整型数组声明,包含5个元素。int* p1[10];
:数组 p1
包含10个指向整型变量的指针。int(*p2)[10];
:指针 p2
指向一个包含10个整型元素的数组。int(*p3[10])[5];
:数组 p3
包含10个指向包含5个整型元素的数组的指针。//数组指针
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语言中复杂声明的理解。这对于理解涉及指针和数组的更复杂的数据结构是非常有用的。