C语言:函数原型声明时的参数列表

张开发
2026/4/10 12:58:06 15 分钟阅读

分享文章

C语言:函数原型声明时的参数列表
相关阅读C语言专栏https://blog.csdn.net/weixin_45791458/category_12423166.html参数列表的不同形式在C语言中函数在使用之前要么已经完成了定义要么至少已经做过声明。很多初学者一开始会把“函数声明”和“函数原型声明”混为一谈但实际上这两个概念并不完全等价。函数声明的范围更大只要告诉编译器“有这么一个函数”就属于声明而函数原型声明则要求把参数的类型和数量也明确写出来这样编译器才能在函数调用处检查实参是否匹配。现代C中最常见、也是最推荐的写法就是下面这种带参数类型列表的函数原型声明void show(char ch,int num);这里的参数列表不仅告诉编译器这个函数有两个参数而且还告诉编译器第一个参数是char类型第二个参数是int类型。这样一来当后面出现函数调用时编译器就能根据这份原型检查参数个数和参数类型是否正确。函数原型中参数名其实不是必须的因为编译器在声明阶段真正关心的是参数类型和参数顺序而不是这些形参在函数体里具体叫什么名字。因此也可以写成下面这样void show(char,int);这两种写法在语义上是等价的。保留参数名的好处主要是可读性更好尤其是在头文件中读者一眼就能看出每个参数的大致含义省略参数名的写法则更简洁常见于一些只强调接口类型、不强调参数意义的场景。如果一个函数确实不接收任何参数那么最规范、最推荐的写法是显式写出voidvoid show(void);但是在一些老代码里经常还能看到下面这种形式void show(); // 这是不推荐的过时写法很多人会直觉地把它理解成“show函数没有参数”但在C语言里这种理解其实是不准确的。void show();表示的是声明了一个返回值类型为void的函数show但这条声明没有提供参数信息。也就是说它没有告诉编译器show到底有几个参数、参数分别是什么类型因此它不是一个真正意义上的函数原型声明。更准确地说这种写法只是一个“参数未指定”的函数声明。这一点非常关键因为它直接决定了编译器在函数调用处能不能做参数检查。只要调用点看到的是void show(int,int);或者void show(void);这样的原型声明编译器就可以检查参数而如果调用点看到的只是void show();那么编译器就无法根据这条声明检查参数数量和参数类型。这里顺便补充一个和C有关的区别。在C中下面两种写法是等价的void show(); void show(void);它们都表示show函数没有参数。但在C语言中这两种写法的含义并不一样show(void);明确表示无参数而void show();表示参数未指定。这也是很多同时写C和C的人容易混淆的地方。空的参数列表带来的问题空的参数列表表示函数原型对函数是否有参数不关心如果此时函数定义的位置和函数调用的文件不同且出现了参数数量不匹配的问题编译、汇编和链接时是不会出错的这是一个运行时的未定义行为。下面给出的一些例子说明了函数原型声明的不同情况而例5是一个未定义的行为。// 例1————编译时会报错参数数量不匹配 // 文件: test.c #include stdio.h void my_function(); int main() { my_function(10); // 调用时只传递一个参数 return 0; } void my_function(int a, int b) // 函数定义接收两个参数 { printf(a %d, b %d\n, a, b); }// 例2————编译时会报错参数数量不匹配 // 文件: test.c #include stdio.h void my_function(int a, int b); int main() { my_function(10); // 调用时只传递一个参数 return 0; } void my_function(int a, int b) // 函数定义接收两个参数 { printf(a %d, b %d\n, a, b); }// 例3————编译时会报错参数数量不匹配 // 文件: test.c #include stdio.h void my_function(int a, int b) // 函数定义接收两个参数 { printf(a %d, b %d\n, a, b); } int main() { my_function(10); // 调用时只传递一个参数 return 0; }// 例4————编译时会报错参数数量不匹配 // 文件1: test1.c #include stdio.h void my_function(int a, int b); int main() { my_function(10); // 调用时只传递一个参数 return 0; } // 文件2: test2.c void my_function(int a, int b) // 函数定义接收两个参数 { printf(a %d, b %d\n, a, b); }// 例5————编译时不会报错运行结果是未定义的 // 文件1: test1.c #include stdio.h void my_function(); int main() { my_function(10); // 调用时只传递一个参数 return 0; } // 文件2: test2.c void my_function(int a, int b) // 函数定义接收两个参数 { printf(a %d, b %d\n, a, b); } // 输出为a 10, b 6820736且b的值每次运行都不一样

更多文章