我从一本关于暂定定义的书中读到,
暂定定义是没有的任何外部数据声明 存储类说明符,没有初始化程序。暂定的定义 如果翻译单元的结尾是,则成为完整定义 达到并没有出现定义初始化器的定义 标识符
请解释上述声明的含义。 还有,声明和定义之间的区别?由于这个原因我混淆了。 :( 为什么这个程序不会出错:
#include <stdio.h>
int a; //Tentative definition
int a; //similarly this declaration too.
int main() //not getting any error with this code why its so?
{
printf("hi");
}
此外,此代码有什么问题:
#include<stdio.h>
printf("Hi");
int main(void){
return 0;
}
答案 0 :(得分:59)
变量声明表示,“程序中有一个具有以下名称和类型的变量”。
变量定义表示,“亲爱的编译先生,请为具有以下名称和类型的变量分配内存。”
因此,同一个变量可以有多个声明,但应该只有一个定义。
在C中,纯声明(也不是定义)前面有关键字extern
。因此,由于您的第一个示例中没有此关键字,因此您拥有两个定义。从表面上看,这似乎是一个问题(实际上是C ++中的一个错误),但C有一个特殊的“暂定”定义规则,它允许同一个变量的多个定义,只要它们都匹配,最多只有一个有一个初始化程序。幕后的C编译器将所有暂定定义组合成一个定义。
您是否尝试初始化两个定义,如下所示:
int a = 1;
int a = 2;
然后你会遇到错误。
你的第二个问题更直截了当。在C中,您根本无法在函数体外部使用可执行语句。这是不允许的。想一想:如果允许的话,你什么时候会期望它运行?
答案 1 :(得分:11)
第一个有效,因为您对a
的定义都是暂定的,可以根据您的需要随时复制。在翻译单元的末尾,没有看到非暂定定义,因此您为属性指定的内容与默认值组合以给出a
的最终定义,因此它将具有外部链接,静态存储持续时间,并初始化为0.
第二个问题与暂定定义无关。你的printf("Hi");
需要在函数内部工作 - 它不是声明或定义(暂定或其他);它不允许在那里。