61

什么是未声明的标识符错误?什么是常见的原因,我该如何解决?

错误文本示例:

  • 对于 Visual Studio 编译器:error C2065: 'cout' : undeclared identifier
  • 对于 GCC 编译器:'cout' undeclared (first use in this function)
4

13 回答 13

94

它们最常见的原因是忘记包含包含函数声明的头文件,例如,该程序将给出“未声明的标识符”错误:

缺少标题

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首次使用前未声明。要修复它,请移动gbefore的定义f

void g() { }
void f() { g(); }

或添加gbefore声明f

void g(); // declaration
void f() { g(); }
void g() { } // definition

stdafx.h 不在顶部(特定于 VS)

这是特定于 Visual Studio 的。在 VS 中,您需要#include "stdafx.h"在任何代码之前添加。编译器忽略之前的代码,所以如果你有这个:

#include <iostream>
#include "stdafx.h"

#include <iostream>被忽略。您需要将其移至下方:

#include "stdafx.h"
#include <iostream>

随意编辑这个答案。

于 2014-03-05T11:55:54.320 回答
20

在谈话中考虑类似的情况。想象一下,你的朋友对你说,“鲍勃要过来吃晚饭”,而你不知道鲍勃是谁。你会很困惑,对吧?你的朋友应该说:“我有一个同事叫鲍勃。鲍勃要过来吃晚饭。” 现在 Bob 已经被宣布了,你知道你的朋友在说谁了。

当您尝试使用某个标识符(函数、变量、类等的名称)并且编译器没有看到它的声明时,编译器会发出“未声明的标识符”错误。也就是说,编译器不知道您指的是什么,因为它以前没有见过它。

如果你在 C 或 C++ 中遇到这样的错误,这意味着你没有告诉编译器你正在尝试使用的东西。声明经常出现在头文件中,因此这可能意味着您没有包含适当的头文件。当然,也可能是您根本不记得声明实体。

一些编译器会根据上下文给出更具体的错误。例如,试图在没有用 clang 声明X x;类型的地方编译会告诉你“未知类型名称”。这更有用,因为您知道它试图解释为一种类型。但是,如果您有, where尚未声明,它会告诉您“使用未声明的标识符”,因为对于可能代表的确切含义存在一些歧义。XXXint x = y;yyy

于 2014-03-05T12:07:27.423 回答
7

在 C 和 C++ 中,所有名称都必须在使用前声明。如果您尝试使用尚未声明的变量或函数的名称,您将收到“未声明的标识符”错误。

但是,函数是 C 中的一种特殊情况(并且仅在 C 中),因为您不必先声明它们。C 编译器将假设函数存在,并且参数的数量和类型与调用中一样。如果实际的函数定义不匹配,您将收到另一个错误。这种函数的特殊情况在 C++ 中不存在。

您可以通过确保在使用函数和变量之前声明它们来修复此类错误。如果printf您需要包含头文件<stdio.h>(或<cstdio>在 C++ 中)。

对于标准功能,我建议您查看此参考站点,然后搜索您要使用的功能。每个函数的文档都会告诉您需要什么头文件。

于 2014-03-05T12:02:05.287 回答
6

我在命名空间中定义的自定义类也遇到了同样的问题。我尝试使用没有命名空间的类,导致编译器错误"identifier "MyClass" is undefined"。添加

using namespace <MyNamespace>

或使用类

MyNamespace::MyClass myClass;

解决了这个问题。

于 2017-01-30T17:52:57.153 回答
3

这些错误信息

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 的声明printHelloPrintHello并且printHello是两个不同的名称,其中一个已声明,另一个未声明但在 main 主体中使用

于 2014-03-05T12:10:56.927 回答
3

当 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中的更多信息

于 2020-01-09T07:31:20.977 回答
2

C++ 标识符是用于标识变量、函数、类、模块或任何其他用户定义项的名称。在 C++ 中,所有名称都必须在使用前声明。如果您尝试使用尚未声明的此类名称,您将收到“未声明的标识符”编译错误。

根据文档,在使用该函数之前,您必须包含它printf()的声明。cstdio

于 2018-07-23T02:38:58.867 回答
1

可能发生此问题的另一种情况,

if(a==b)
double c;
getValue(c);

在这里,值在条件中声明,然后在条件之外使用。

于 2019-12-18T11:05:25.043 回答
1

另一种可能的情况:访问模板类中的父(模板类)成员。

修复方法:使用父类成员的全名(通过前缀this->parentClassName::成员名称)。

请参阅:模板:父类成员变量在继承类中不可见

于 2018-10-24T08:29:58.047 回答
0

这就像使用函数而不声明它。头文件将包含函数 printf()。在程序中包含头文件,这是解决方案。一些用户定义的函数在使用前未声明也可能会出错。如果它在全球范围内使用,则没有问题。

于 2014-03-05T12:03:42.333 回答
0

c 错误中的每个未声明变量都是因为编译器无法在项目中找到它。可以包括定义变量的库的外部(头)文件。因此,在您的问题中,您需要<stdio.h>一个标准输入输出文件,它描述了 printf() 功能。

根据文档, fprintf() 的声明在即您必须在使用该函数之前包含它。

于 2014-03-05T12:06:50.293 回答
0

大多数情况下,如果您非常确定是否导入了相关库,Visual Studio 将引导您使用 IntelliSense。

这对我有用:

确保#include "stdafx.h"首先声明它,即在所有包含的顶部。

于 2018-07-23T02:25:26.057 回答
-1

检查您是否在 .m 和 .h 中导入相同的包 给出的示例:我在 init 方法中遇到了这个问题,它是由于缺少 .m 文件上的“#import”引起的

于 2016-10-17T16:09:45.267 回答