保留现场
1 |
|
声明了一个长度为 3 的vector
数组,编译是会报这个错误。
探究原因
编译器可能无法区分这是一个成员函数声明还是一个成员变量声明,也就是产生歧义。
解决方法
方法 1:
1 |
|
方法 2:默认构造函数里面进行成员变量的初始化
1 |
|
方法 3:列表初始化
1 |
|
1 |
|
声明了一个长度为 3 的vector
数组,编译是会报这个错误。
编译器可能无法区分这是一个成员函数声明还是一个成员变量声明,也就是产生歧义。
方法 1:
1 |
|
方法 2:默认构造函数里面进行成员变量的初始化
1 |
|
方法 3:列表初始化
1 |
|
学习过程中查看了printf()
源码,遇到了这样的函数定义,
1 |
|
参数中的三个点号,就是 C 语言中可变参数的标识。这样的函数称为可变参数函数。这种函数需要固定数量的强制参数(mandatory argument),后面是数量可变的可选参数(optional argument)。
这种函数必须至少有一个强制参数。可选参数的类型可以变化。可选参数的数量由强制参数的值决定,或由用来定义可选参数列表的特殊值决定。
C 语言中最常用的可变参数函数例子是printf()
和 scanf()
。这两个函数都有一个强制参数,即格式化字符串。格式化字符串中的转换修饰符决定了可选参数的数量和类型。
可变参数函数要获取可选参数时,必须通过一个类型为 va_list
的对象,它包含了参数信息。这种类型的对象也称为参数指针(argument pointer),它包含了栈中至少一个参数的位置。可以使用这个参数指针从一个可选参数移动到下一个可选参数,由此,函数就可以获取所有的可选参数。va_list
类型被定义在头文件 stdarg.h
中。
当编写支持参数数量可变的函数时,必须用 va_list
类型定义参数指针,以获取可选参数。在下面的讨论中,va_list
对象被命名为 argptr
。可以用 4
个宏来处理该参数指针,这些宏都定义在头文件 stdarg.h
中:
宏 va_start
使用第一个可选参数的位置来初始化 argptr
参数指针。该宏的第二个参数必须是该函数最后一个有名称参数的名称。必须先调用该宏,才可以开始使用可选参数。
1 |
|
展开宏 va_arg
会得到当前 argptr
所引用的可选参数,也会将 argptr
移动到列表中的下一个参数。宏 va_arg
的第二个参数是刚刚被读入的参数的类型。
1 |
|
当不再需要使用参数指针时,必须调用宏 va_end
。如果想使用宏 va_start
或者宏 va_copy
来重新初始化一个之前用过的参数指针,也必须先调用宏 va_end
。va_end
被定义为空。它只是为实现与 va_start 配对 (实现代码对称和”代码自注释”(根据代码就能知道功能,不需要额外注释) 功能)
1 |
|
宏 va_copy
使用当前的src
值来初始化参数指针 dest
。然后就可以使用 dest
中的备份获取可选参数列表,从src
所引用的位置开始。
1 |
|
1 |
|
简易printf
函数
1 |
|
这是最典型最常见的情况。比如新添加了一个模块fun.h fun.c
两个文件,其他文件中使用了这个模块里的函数,如果编译时忘记加上这两个文件,调用fun
模块函数的地方,就会报undefined reference
错误。
这个问题在编辑器中一般不容易发现,因为头文件包含是正确的,编辑器能够找到相关的函数及其实现,所以在编写代码时不会报错。
这个原因和上一条类似,我们在调用静态库中的函数时,编译时如果没有将静态库一起编译,就会报同样的错误。
在使用第三方库时,一定要在编译中加入第三方库的路径。
在链接命令中给出所依赖的库时,需要注意库之间的依赖顺序,依赖其他库的库一定要放到被依赖库的前面,这样才能真正避免 undefined reference 的错误,完成编译链接。
这个原因也比较典型,注意排查声明与实现的参数是否一致,返回值是否一致。
在C++
代码中,调用了C
语言库的函数,因此链接的时候找不到,解决方法是在相关文件添加一个extern "C"
的声明即可。
顾名思义,这个错误就是未定义你使用的内容导致的。所以要排查使用的内容是否能够被正确“找到”。使用的时候有没有声明,有没有定义,声明与定义是否一致,编译时能否正确链接等等。
‘
具体实例可以参考Marc Pony
C 语言中,全局变量用结构体封装,设计函数时,将参数以结构体指针形式传入。
定义一个函数以get/set
全局变量,利用static
变量,将全局变量作用域限定于该函数,将全局变量隐藏起来。
static
把全局变量定义在某一个 .c 文件中,并定义为 static 类型,然后定义一系列操作这个变量的函数,头文件里面只有操作函数,没有变量的声明
Update your browser to view this website correctly. Update my browser now