这个答案说:
......最后,
Run Code Online (Sandbox Code Playgroud)typedef struct { ... } Foo;声明一个匿名结构并为其创建一个typedef.因此,使用此构造,它在标记名称空间中没有名称,只有typedef名称空间中的名称.这意味着它也无法向前宣布.如果要进行前向声明,则必须在标记名称空间中为其指定名称.
什么是前瞻性声明?
我不确定我是否正确地提出了这个问题,但让我解释一下.
首先,我读了这篇解释声明和定义之间差异的文章:http: //www.cprogramming.com/declare_vs_define.html
其次,我从之前的研究中了解到,在头文件中定义变量和函数是不好的做法,因为在链接阶段,您可能有多个同名的定义会引发错误.
但是,为什么课不会发生这种情况呢?根据另一个SO答案( 定义和声明之间有什么区别?),以下是一个类定义:
class MyClass {
private:
public:
};
Run Code Online (Sandbox Code Playgroud)
如果上面的定义是在头文件中.然后,据推测,您可以有多个.cpp文件#include该标头.这意味着在多个.o文件中编译后,类被多次定义,但似乎没有引起太多问题......
另一方面,如果它是在头文件中定义的函数,它会明显地引起问题...从我的理解... mayb?
那么类定义有什么特别之处呢?
在下面的代码中,为什么多个声明(和一个定义)适用于全局变量x,而不适用y于main()函数内部的局部变量?它显示以下2个错误:
1)没有联系的'y'重新声明
2)之前的'y'声明就在这里
为什么它显示局部变量但不是全局变量的错误?不仅是我的书,而且本论坛的以下2个链接清楚地表明我们可以多次声明一个变量(尽管只定义一次).
并且请注意解释第一个错误"没有链接"的部分是什么,"没有连接的'y'的重新声明"是什么意思?什么联系和谁?将局部变量链接到哪里?
#include<stdio.h>
int x;
int x;
int x=303;
int main(void)
{
int y;
int y;
int y=776; //Works fine if above 2 declarations are removed!!
printf("The value of x is %d,and of y is %d",x,y);
}
Run Code Online (Sandbox Code Playgroud) 我正在运行以下代码编译为: gcc A.c B.c -o combined
计划A:
#include<stdio.h>
int a=1;
int b;
int main()
{
extern int a,b;
fun();
printf("%d %d\n",a,b);
}
Run Code Online (Sandbox Code Playgroud)
方案B:
int a;
int b=2;
int fun()
{
printf("%d %d\n",a,b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在运行"组合"程序时,输出为:
1 2
1 2
Run Code Online (Sandbox Code Playgroud)
现在,我对这个问题有些疑惑:
为什么不输出:
0 2
1 0
是不是a和b定义了两次?
请清楚地解释一下,我在了解外部时遇到了很多问题,而且很少有这些疑虑不时出现.
提前致谢.
当我编译下面的代码时
#include<stdio.h>
int main()
{
int a;
int a = 10;
printf("a is %d \n",a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
test3.c: In function ‘main’:
test3.c:6:5: error: redeclaration of ‘a’ with no linkage
test3.c:5:5: note: previous declaration of ‘a’ was here
Run Code Online (Sandbox Code Playgroud)
但是,如果我将变量设为全局,那么它可以正常工作.
#include<stdio.h>
int a;
int a = 10;
int main()
{
printf("a is %d \n",a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么两次声明相同的全局变量而不是错误,但对局部变量这样做是错误的?
假设我们有以下内容:
void print()
{
int a; // declaration
a = 9;
cout << a << endl;
}
int main ()
{
print();
}
Run Code Online (Sandbox Code Playgroud)
是否在函数print中分配的变量a的存储是在main中调用还是在执行到达函数内部的声明时?
我有一些C代码,我必须移植到C++.代码有一个结构
struct A {
...
struct A * myPtr;
}
Run Code Online (Sandbox Code Playgroud)
现在声明和初始化两个全局数组,如下所示:
//Forward declaration of Unit
struct A Unit[10];
struct A* ptrUnit[2] = { Unit, Unit+7 };
struct A Unit[10] = { { .., &ptrUnit[0] },
... };
Run Code Online (Sandbox Code Playgroud)
现在虽然这在C中运行良好,但它在C++中给出了一个错误(变量重新声明).是不是允许变量在C++中进行前向声明?
所以我知道在C++常量中,默认情况下获得的变量与变量不同.这就是我不能放的原因
int foo;
Run Code Online (Sandbox Code Playgroud)
在一些标题中 - 链接器会正确地抱怨多个定义.OTOH,我可以写
const int bar = 42;
Run Code Online (Sandbox Code Playgroud)
在标题中,编译器确保只有一个定义bar.
使用积分常量,很容易看出编译器如何处理这个 - 至少只要没有人获取地址bar或做一些其他有趣的事情,需要它为它分配存储).但是,如果有人怎么办?如果它不是一个整体但需要在运行时执行的代码呢?假设我将其放入标题中:
const std::string baz = "h2g2";
Run Code Online (Sandbox Code Playgroud)
假设没有小的字符串优化,这需要在运行时分配动态内存,因此需要执行代码,地址需要存储在某处,等等.
我假设我最终会得到baz每个翻译单元的一个定义,只是编译器为其分配内部链接以防止链接器抱怨?或者我错过了什么?
注意:我对constexpr普通的旧C++常量不感兴趣,因为它们自80年代以来就存在并且在C++ 98中编纂.(但是,如果一个全面的答案将包括这一切如何融合在一起constexpr,我不会抱怨.)
我偶尔会看到一些问题,例如"声明和定义之间有什么区别":
定义和声明之间有什么区别? 区别很重要,在理智上它实现了两个重要的事情:
那么为什么C typedef声明不被称为typedef定义?
首先,它显然是一个定义.它定义了一个别名.新名称将被视为指现有的东西.但它确实将对特定参照物的引用联系在一起,毫无疑问是一个定义的陈述.
其次,typedec如果是宣言,它不会被称为a 吗?
第三,它不会避免人们在尝试使用typedef进行前瞻性声明时所提出的所有令人困惑的问题吗?
c++ ×6
c ×5
declaration ×2
definition ×2
arrays ×1
c++98 ×1
constants ×1
extern ×1
header-files ×1
linkage ×1
linker ×1
output ×1
redefinition ×1
standards ×1
struct ×1
typedef ×1