下边的代码分别是什么含义?int a;int a=0;static int a;static int a = 0;extern int a;extern int a = 0;//ERROR1.变量声明和定义的区别?变量可以有多次声明,但只能有一次定义。声明只是说我有这个变量,也有可能这个变量不是在我这个文件中开辟的内存空间,所以声明可以有多次。定义只能有一次,如果一个变量有多次定义,则链接时就会困惑不知道是该链接哪一个,访问变量时也不能确定访问的是哪个。
将C语言梳理一下,分布在以下10个章节中:- Linux-C成长之路(一):Linux下C编程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
- Linux-C成长之路(二):基本数据类型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
- Linux-C成长之路(三):基本IO函数操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
- Linux-C成长之路(四):运算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
- Linux-C成长之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
- Linux-C成长之路(六):函数要义 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
- Linux-C成长之路(七):数组与指针 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
- Linux-C成长之路(八):存储类,动态内存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
- Linux-C成长之路(九):复合数据类型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
- Linux-C成长之路(十):其他高级议题
C++ Primer Plus 第6版 中文版 清晰有书签PDF+源代码 http://www.linuxidc.com/Linux/2014-05/101227.htmC++11中正则表达式测试 http://www.linuxidc.com/Linux/2012-08/69086.htmint a;是声明还是定义?********************************************
| 12345 | int a;int main(){a = 0; } |
********************************************如果此时我们单纯的认为int a;就是定义了一个变量,那么我们在int a;下再加一句int a;如下:
int a;int a;int main(){a = 0;
}编译是否通过?结果会让我们大吃一惊。如果按照上述结论int a是定义的话,现在就应该会报重定义的错了,可是编译器并没有报错,为什么呢?
这就说明:不能简单凭借有没有赋初值来判断变量是声明还是定义。赋了值的一定是定义,没有赋值的可以是声明也可以是定义,要根据语境来判断。例子中int a;可能是声明也可能是定义。如果代码中出现多次int a;编译器则会把其中一个当成定义,其他都会看成声明。也就是说像int a;这样没有给它赋初值的语句可以是声明也可以是定义。 ******************************************
int a=1;int a;int main(){a = 0;
}没有错,第一句是定义,第二句是声明******************************************但是像下边这样
int a=1; //给a开辟了一块内存
int a=1; //给a开辟了一块内存
int main(){a = 0;
}就会报重定义的错了。因为这相当于每条语句都为a开辟了一块内存,在链接的时候就不知道a到底是那块内存了****************************************** 在单个c源文件中很清楚,关于变量的错误主要是在多个相互联系的源文件中。====a.h============int a;===================***b.c*************
#include"a.h" int main(){a = 0;
}***********************c.c**************
#include"a.h" int main(){a = 0;
}******************这个时候在b.c中 c.c中都有一个int a; 编译程序gcc b.c c.c 没问题,因为这个时候其中一个是定义,另一个是声明。2.extern的含义?上面的例子如果将a.h中 int a;改为 int a = 0;则编译器就会报a被多次定义的错了。对应上边所说的赋了值的一定是定义。没赋值的可以是声明也可以定义。int a比较明显。有的可能会在头文件中写成const char* item[]={"aa","bb"};这时编译也会报错。这和int a=0;没有区别。所以在头文件中我们应该避免给变量赋初值。头文件里只对变量进行声明这个时候就应该加上extern关键字 extern int a;这个时候就表示 这个a只在这个头文件中声明,而不是在这里定义的,是在某一个cpp文件中定义,开辟内存的。extern关键字就代表只是声明一个变量,所以文章开头 extern int a=0;是错误的 因为只是声明并没有为它开辟空间是不可以赋值的。这个时候就可以在c.c里 int a=10;为a定义。 在b.c里就可以访问a了。代码如下:====a.h============
extern int a;===================****c.c************include "a.h"int a = 10;******************* ****b.c***********include "a.h" void main(){printf("%d",a); //这个时候多个文件include头文件a.h就可以正常访问变量a了,a实际是在c.c里赋的值}********************3.static 是什么含义?翻译过来就是静态的意思。还是原来的例子。====a.h============
extern int a;===================****c.c************include "a.h"staitc int a = 10;void main(){printf("the a in c.c is %d",a);}******************* ****b.c***********include "a.h"staitc int a = 100;void main(){printf("the a in b.c is %d",a);}*************************这个时候没有报错。static关键字表示 这个a只在自身范围内有效。和外边没有关系。不会和外边去链接,所以没有冲突,b.c和a.c里的a不是同一块内存 是各自的内存。extern 函数也是一样。====a.h============
extern int add(int var1);===================****c.c************include "a.h"staitc int a = 10;int add(int var1){a+=var1;}******************* ****b.c***********include "a.h"staitc int a = 100;void main(){add(15);printf("the a in b.c is %d",a); //结果仍是100}*************************说明 extern的方法改变的a是方法被定义的文件(c.c)里的变量a
本文永久更新链接地址:http://www.linuxidc.com/Linux/2014-06/102600.htm