什么是未声明的标识符错误?什么是常见的原因,我该如何解决?
错误文本示例:
- 对于 Visual Studio 编译器:
error C2065: 'cout' : undeclared identifier
- 对于 GCC 编译器:
'cout' undeclared (first use in this function)
什么是未声明的标识符错误?什么是常见的原因,我该如何解决?
错误文本示例:
error C2065: 'cout' : undeclared identifier
'cout' undeclared (first use in this function)
它们最常见的原因是忘记包含包含函数声明的头文件,例如,该程序将给出“未声明的标识符”错误:
int main() {
std::cout << "Hello world!" << std::endl;
return 0;
}
要修复它,我们必须包含标题:
#include <iostream>
int main() {
std::cout << "Hello world!" << std::endl;
return 0;
}
如果您编写了标头并正确包含它,则标头可能包含错误的 include guard。
要了解更多信息,请参阅http://msdn.microsoft.com/en-us/library/aa229215(v=vs.60).aspx。
当您拼错一个变量时,另一个常见的初学者错误来源会发生:
int main() {
int aComplicatedName;
AComplicatedName = 1; /* mind the uppercase A */
return 0;
}
例如,此代码会出错,因为您需要使用std::string
:
#include <string>
int main() {
std::string s1 = "Hello"; // Correct.
string s2 = "world"; // WRONG - would give error.
}
void f() { g(); }
void g() { }
g
首次使用前未声明。要修复它,请移动g
before的定义f
:
void g() { }
void f() { g(); }
或添加g
before声明f
:
void g(); // declaration
void f() { g(); }
void g() { } // definition
这是特定于 Visual Studio 的。在 VS 中,您需要#include "stdafx.h"
在任何代码之前添加。编译器忽略之前的代码,所以如果你有这个:
#include <iostream>
#include "stdafx.h"
将#include <iostream>
被忽略。您需要将其移至下方:
#include "stdafx.h"
#include <iostream>
随意编辑这个答案。
在谈话中考虑类似的情况。想象一下,你的朋友对你说,“鲍勃要过来吃晚饭”,而你不知道鲍勃是谁。你会很困惑,对吧?你的朋友应该说:“我有一个同事叫鲍勃。鲍勃要过来吃晚饭。” 现在 Bob 已经被宣布了,你知道你的朋友在说谁了。
当您尝试使用某个标识符(函数、变量、类等的名称)并且编译器没有看到它的声明时,编译器会发出“未声明的标识符”错误。也就是说,编译器不知道您指的是什么,因为它以前没有见过它。
如果你在 C 或 C++ 中遇到这样的错误,这意味着你没有告诉编译器你正在尝试使用的东西。声明经常出现在头文件中,因此这可能意味着您没有包含适当的头文件。当然,也可能是您根本不记得声明实体。
一些编译器会根据上下文给出更具体的错误。例如,试图在没有用 clang 声明X x;
类型的地方编译会告诉你“未知类型名称”。这更有用,因为您知道它试图解释为一种类型。但是,如果您有, where尚未声明,它会告诉您“使用未声明的标识符”,因为对于可能代表的确切含义存在一些歧义。X
X
X
int x = y;
y
y
y
在 C 和 C++ 中,所有名称都必须在使用前声明。如果您尝试使用尚未声明的变量或函数的名称,您将收到“未声明的标识符”错误。
但是,函数是 C 中的一种特殊情况(并且仅在 C 中),因为您不必先声明它们。C 编译器将假设函数存在,并且参数的数量和类型与调用中一样。如果实际的函数定义不匹配,您将收到另一个错误。这种函数的特殊情况在 C++ 中不存在。
您可以通过确保在使用函数和变量之前声明它们来修复此类错误。如果printf
您需要包含头文件<stdio.h>
(或<cstdio>
在 C++ 中)。
对于标准功能,我建议您查看此参考站点,然后搜索您要使用的功能。每个函数的文档都会告诉您需要什么头文件。
我在命名空间中定义的自定义类也遇到了同样的问题。我尝试使用没有命名空间的类,导致编译器错误"identifier "MyClass" is undefined"。添加
using namespace <MyNamespace>
或使用类
MyNamespace::MyClass myClass;
解决了这个问题。
这些错误信息
1.For the Visual Studio compiler: error C2065: 'printf' : undeclared identifier
2.For the GCC compiler: `printf' undeclared (first use in this function)
意味着您使用名称printf
,但编译器看不到名称的声明位置,因此不知道它的含义。
程序中使用的任何名称都应在使用前声明。编译器必须知道名称表示什么。
在这种特殊情况下,编译器看不到 name 的声明printf
。正如我们所知(但不是编译器),它是标准 C 函数的名称,<stdio.h>
在 C 的头文件或<cstdio>
C++ 的头文件中声明并放置在标准(std::
)和全局(::
)(不一定)名称空间中。
所以在使用这个函数之前,我们必须通过包含相应的头文件来向编译器提供它的名称声明。
例如 C:
#include <stdio.h>
int main( void )
{
printf( "Hello World\n" );
}
C++:
#include <cstdio>
int main()
{
std::printf( "Hello World\n" );
// or printf( "Hello World\n" );
// or ::printf( "Hello World\n" );
}
有时这种错误的原因是一个简单的错字。例如,假设您定义了函数PrintHello
void PrintHello()
{
std::printf( "Hello World\n" );
}
但主要是你打错了字,而不是用小写字母“p”PrintHello
输入。printHello
#include <cstdio>
void PrintHello()
{
std::printf( "Hello World\n" );
}
int main()
{
printHello();
}
在这种情况下,编译器会发出这样的错误,因为它没有看到 name 的声明printHello
。 PrintHello
并且printHello
是两个不同的名称,其中一个已声明,另一个未声明但在 main 主体中使用
当 Visual Studio 项目中的自动格式化程序对我的包含进行排序时,我发生了这种情况,之后预编译的标头不再是第一个包含。
换句话说。如果您有以下任何一项:
#include "pch.h"
或者
#include <stdio.h>
或者
#include <iostream>
#include "stdafx.h"
将其放在文件的开头。
如果您的clang 格式化程序正在自动对文件进行排序,请尝试在预编译的标头后输入一个 enter。如果它在IBS_Preserve上,它将分别对每个 #include 块进行排序。
#include "pch.h" // must be first
#include "bar.h" // next block
#include "baz.h"
#include "foo.h"
编译器错误 C2065中的更多信息
C++ 标识符是用于标识变量、函数、类、模块或任何其他用户定义项的名称。在 C++ 中,所有名称都必须在使用前声明。如果您尝试使用尚未声明的此类名称,您将收到“未声明的标识符”编译错误。
根据文档,在使用该函数之前,您必须包含它printf()
的声明。cstdio
可能发生此问题的另一种情况,
if(a==b)
double c;
getValue(c);
在这里,值在条件中声明,然后在条件之外使用。
这就像使用函数而不声明它。头文件将包含函数 printf()。在程序中包含头文件,这是解决方案。一些用户定义的函数在使用前未声明也可能会出错。如果它在全球范围内使用,则没有问题。
c 错误中的每个未声明变量都是因为编译器无法在项目中找到它。可以包括定义变量的库的外部(头)文件。因此,在您的问题中,您需要<stdio.h>
一个标准输入输出文件,它描述了 printf() 功能。
根据文档, fprintf() 的声明在即您必须在使用该函数之前包含它。
大多数情况下,如果您非常确定是否导入了相关库,Visual Studio 将引导您使用 IntelliSense。
这对我有用:
确保#include "stdafx.h"
首先声明它,即在所有包含的顶部。
检查您是否在 .m 和 .h 中导入相同的包 给出的示例:我在 init 方法中遇到了这个问题,它是由于缺少 .m 文件上的“#import”引起的