c语言笔记 函数参数的等价(下)
为什么这三种写法是等价的?
这三种写法是等价的,数组在作为函数参数的时候会变成指针,数组的大小会被系统编译器自动忽略
所以char *(argv[argc]) 等价于 char *(argv[])
*和[]是可以相互转换的所以char *(argv[])等价 char *(*argv)
作为命令行:这里我们需要的是一个指针数组,其实上面的理解都可以理解成一个指针数组,因为指针数组
与char型的二维数组好搭配
int *p[5] = {指针,指针,指针...} 变量的类型 int *[5] 数组的元素类型:int * --->指针
char *(argv[argc]) char *(argv[]) char *(*argv)
上面三种写法只有在作为函数参数的时候是等价的,如果是在函数内定义的那么它们就是不一样的
-
char *(argv[argc])
-
这种写法声明
argv
是一个数组,其大小为argc
,每个元素是一个指向char
的指针。 -
在函数参数中,数组的大小
argc
实际上会被编译器忽略,因为数组作为参数传递时会退化为指针。
-
-
char *(argv[])
-
这种写法声明
argv
是一个数组,但没有指定数组的大小。 -
在函数参数中,未指定大小的数组会被编译器视为一个指针。
-
-
char **argv
-
这种写法直接声明
argv
是一个指向char *
的指针,即二级指针。
-
在C语言中,当数组作为函数参数传递时,它会退化为指向其首元素的指针。这意味着,无论你如何声明数组参数(无论是指定大小还是不指定大小),编译器最终都会将其视为一个指针。因此,char *(argv[argc])
和char *(argv[])
在语义上等价于char **argv
。
代码示例
以下是一个简单的示例,展示这三种声明方式的等价性:
#include <stdio.h>
// 使用 char *(argv[argc])
void printArguments(int argc, char *(argv[argc])) {
for (int i = 0; i < argc; i++) {
printf("Argument %d: %s\n", i, argv[i]);
}
}
// 使用 char *(argv[])
void printArguments2(int argc, char *(argv[])) {
for (int i = 0; i < argc; i++) {
printf("Argument %d: %s\n", i, argv[i]);
}
}
// 使用 char **argv
void printArguments3(int argc, char **argv) {
for (int i = 0; i < argc; i++) {
printf("Argument %d: %s\n", i, argv[i]);
}
}
int main() {
char *arguments[] = {"arg0", "arg1", "arg2"};
int argCount = sizeof(arguments) / sizeof(arguments[0]);
printArguments(argCount, arguments);
printArguments2(argCount, arguments);
printArguments3(argCount, arguments);
return 0;
}
在这段代码中,printArguments
、printArguments2
和printArguments3
三个函数的参数声明方式不同,但它们的功能和行为完全相同。
总结
-
数组参数的退化:数组作为函数参数时会退化为指向其首元素的指针。
-
解引用和下标操作的等价性:在C语言中,
*(ptr + i)
和ptr[i]
是等价的。 -
数组大小在参数声明中被忽略:在函数参数中声明数组时,数组的大小会被编译器忽略。