Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中的函数内声明函数_C - Fatal编程技术网

在C中的函数内声明函数

在C中的函数内声明函数,c,C,我正在读KR C的书,我面对一个我不理解的函数定义。这是第87页的qsort()函数。它在qsort()函数中声明swap()函数: void qsort(args) { ... void swap(arguments); ... swap(a,b); } void swap(arguments){ ... } swap()函数不应该在函数之外声明吗?为什么要在qsort()函数中声明它?我想您正在阅读K&R C编程语言,也许还有ANSI C的第二版?在第87页有一个PDF,上面讨论

我正在读KR C的书,我面对一个我不理解的函数定义。这是第87页的
qsort()
函数。它在
qsort()函数中声明
swap()
函数:

void qsort(args)
{
 ...
 void swap(arguments);
 ...
 swap(a,b);
}

void swap(arguments){
...
}

swap()
函数不应该在函数之外声明吗?为什么要在
qsort()
函数中声明它?

我想您正在阅读K&R C编程语言,也许还有ANSI C的第二版?在第87页有一个PDF,上面讨论了使用快速排序算法的递归

请参阅此Wikipedia主题,比较和对比各种C标准

K&R C图书为旧式C,第二版版权为1988年。那里有很多很好的材料,但是需要从旧样式的角度来阅读,而且C标准自ANSI C以来已经发生了变化。主要的事情是更好地说明编译器应该声明哪些错误和警告。在ANSIC中有一些东西是完全可以接受的,但在现代C标准中已经不可接受了。通过收紧C编程语言规范并提供一些额外的关键字和语法,大量工作已经投入到试图通过编译器提供更好的静态检查上

swap()
应该有一个转发声明,或者函数的定义及其源代码应该在函数实际使用之前出现。这允许C编译器根据函数的声明或定义检查函数的使用情况,以检查可能的使用错误

但是,对于C编程语言,如果在定义或声明函数之前使用该函数,通常会从Visual Studio 2013
warning C4013中得到一条警告,如此警告:“swap”未定义;假设外部程序返回int

一些编译器(最近版本的
clang
gcc
以及Visual Studio 2015)已经开始实现C11。某些编译器提供了其他选项来改进警告和/或将某些类型的警告转化为错误

例如,如果我在testit.c文件中有以下源代码(注意c源代码的.c文件扩展名),并使用Visual Studio 2013使用4级警告进行编译,我将得到一组警告,但没有错误。VisualStudio使用C的标准和规则编译C源,这比C++的更为松散,即使是相同的语法。

我编译了这个源代码的两个不同版本,一个在第2行注释掉了forward声明,另一个未注释。从警告中注意到,VisualStudio的C编译器允许在不使用前向声明的情况下使用函数

请注意,在第二次运行中,当第2行上的前向声明未注释时,会出现一条关于为函数范围内的函数提出前向声明的警告:
警告C4210:使用了非标准扩展名:函数给定文件范围

还请注意,通过在第二次运行中提供转发声明,编译器能够识别可能的使用错误并发出警告,在一种情况下发出实际错误

请注意,参数的数量在第一次和第二次编译中都有所不同,但只有在前向声明未注释且可供编译器使用的第二次编译中,我们才会看到有关额外参数的警告

int func1() {                        // line 1
//  int swap(int a, int b);          // line 2, forward declaration for function swap

    int j = swap(1, 2);

    return 0;
}

int func2() {                         // line 9
    struct {
        int a;
        int b;
        int c;
    } mm = { 0 };

    int k = swap(4, 5, 8);             // line 16

    float ff = swap(4.0, 5.0, 8.0);    // line 18

    int k2 = swap(mm, 2, 3);           // line 20

    return 1;
}

int swap(int a, int b) {               // line 25
    return a + b;
}
警告如下:

1>------ Build started: Project: ConsoleApplication3, Configuration: Debug Win32 ------
1>  testit.c
1>c:\users\projects\consoleapplication3\testit.c(4): warning C4013: 'swap' undefined; assuming extern returning int
1>c:\users\projects\consoleapplication3\testit.c(4): warning C4189: 'j' : local variable is initialized but not referenced
1>c:\users\projects\consoleapplication3\testit.c(18): warning C4244: 'initializing' : conversion from 'int' to 'float', possible loss of data
1>c:\users\projects\consoleapplication3\testit.c(16): warning C4189: 'k' : local variable is initialized but not referenced
1>c:\users\projects\consoleapplication3\testit.c(20): warning C4189: 'k2' : local variable is initialized but not referenced
1>c:\users\projects\consoleapplication3\testit.c(18): warning C4189: 'ff' : local variable is initialized but not referenced
1>  ConsoleApplication3.vcxproj -> C:\Users\Projects\Debug\ConsoleApplication3.exe
如果随后取消对函数
swap()
的正向声明的注释,我将看到以下编译器输出的警告和错误:

1>------ Build started: Project: ConsoleApplication3, Configuration: Debug Win32 ------
1>  testit.c
1>c:\users\projects\consoleapplication3\testit.c(2): warning C4210: nonstandard extension used : function given file scope
1>c:\users\projects\consoleapplication3\testit.c(4): warning C4189: 'j' : local variable is initialized but not referenced
1>c:\users\projects\consoleapplication3\testit.c(16): warning C4020: 'swap' : too many actual parameters
1>c:\users\projects\consoleapplication3\testit.c(18): warning C4244: 'function' : conversion from 'double' to 'int', possible loss of data
1>c:\users\projects\consoleapplication3\testit.c(18): warning C4020: 'swap' : too many actual parameters
1>c:\users\projects\consoleapplication3\testit.c(18): warning C4244: 'initializing' : conversion from 'int' to 'float', possible loss of data
1>c:\users\projects\consoleapplication3\testit.c(20): error C2440: 'function' : cannot convert from '' to 'int'
1>c:\users\projects\consoleapplication3\testit.c(20): warning C4024: 'swap' : different types for formal and actual parameter 1
1>c:\users\projects\consoleapplication3\testit.c(20): warning C4020: 'swap' : too many actual parameters
现在C++编程语言不同,不允许这种松散。这就是为什么C++与C共享历史,C++是一种不同的相关语言。 如果我将相同的源代码复制到文件testit2.cpp中,那么编译时会看到不同的错误

首先,将
swap()
的转发声明注释掉

1>  testit2.cpp
1>c:\users\projects\consoleapplication3\testit2.cpp(4): error C3861: 'swap': identifier not found
1>c:\users\projects\consoleapplication3\testit2.cpp(16): error C3861: 'swap': identifier not found
1>c:\users\projects\consoleapplication3\testit2.cpp(18): error C3861: 'swap': identifier not found
1>c:\users\projects\consoleapplication3\testit2.cpp(20): error C3861: 'swap': identifier not found
再次声明未注释的转发

1>  testit2.cpp
1>c:\users\projects\consoleapplication3\testit2.cpp(4): warning C4189: 'j' : local variable is initialized but not referenced
1>c:\users\projects\consoleapplication3\testit2.cpp(16): error C3861: 'swap': identifier not found
1>c:\users\projects\consoleapplication3\testit2.cpp(18): error C3861: 'swap': identifier not found
1>c:\users\projects\consoleapplication3\testit2.cpp(20): error C3861: 'swap': identifier not found
最后,如果我将
swap()
的前向声明从函数
func1()
的作用域移到文件作用域中,使其现在是第1行,那么我将看到以下不同的错误:

1>  testit2.cpp
1>c:\users\projects\consoleapplication3\testit2.cpp(4): warning C4189: 'j' : local variable is initialized but not referenced
1>c:\users\projects\consoleapplication3\testit2.cpp(16): error C2660: 'swap' : function does not take 3 arguments
1>c:\users\projects\consoleapplication3\testit2.cpp(18): error C2660: 'swap' : function does not take 3 arguments
1>c:\users\projects\consoleapplication3\testit2.cpp(20): error C2660: 'swap' : function does not take 3 arguments

我想您正在阅读K&R C编程语言,也许是ANSI C的第二版?在第87页有一个PDF,上面讨论了使用快速排序算法的递归

请参阅此Wikipedia主题,比较和对比各种C标准

K&R C图书为旧式C,第二版版权为1988年。那里有很多很好的材料,但是需要从旧样式的角度来阅读,而且C标准自ANSI C以来已经发生了变化。主要的事情是更好地说明编译器应该声明哪些错误和警告。在ANSIC中有一些东西是完全可以接受的,但在现代C标准中已经不可接受了。通过收紧C编程语言规范并提供一些额外的关键字和语法,大量工作已经投入到试图通过编译器提供更好的静态检查上

swap()
应该有一个转发声明,或者函数的定义及其源代码应该在函数实际使用之前出现。这允许C编译器根据函数的声明或定义检查函数的使用情况,以检查可能的使用错误

但是,对于C编程语言,如果在定义或声明函数之前使用该函数,通常会从Visual Studio 2013
warning C4013中得到一条警告,如此警告:“swap”未定义;假设外部程序返回int

一些编译器(最近版本的
clang
gcc
以及Visual Studio 2015)已经开始实现C11。一些编译器提供了额外的