c语言变量或函数的声明与定义(有实验)

lizj3624 2011-01-11 02:59:43
在c语言中,变量和函数的声明:只是声明了一下,没有分配内存,声明可以多次。变量和函数的定义:给变量和函数分配了内存,定义只能是一次。有的资料介绍:int i;既可以是声明也可以是定义。extern int i;就只是声明。函数的声明与定义比较好区分
int func(int a, int b); 一般为函数的声明
int func(int a, int b) 一般为函数的定义
{
/*函数体*/
}
自己针对变量的声明和定义做如下实验:
如果int i既可以是声明也可以是定义,一个文件中有多个int i就报错。
实验(1)
源文件myext1.c
1 #include "my1.h"
2 #include "my2.h"
3 #include <stdio.h>
4 int main()
5 {
6 printf("i = %d\n", i);
7
8 return 1;
9 }
一个头文件 my1.h
int i;

一个头文件 my2.h
int i;

gcc编译
gcc -Wall myext1.c -o myext1
执行结果为: i = 0

myext1.c包含了两个头文件,就有两个int i;问什么没有报错呢?
是不是两个int i中,有一个是声明,有一个是定义,同时有对i进行了初始化,这样理解对吗?

实验(2)
将头文件my2.h修改为 int i = 2;其他的文件不变。
源文件myext1.c
1 #include "my1.h"
2 #include "my2.h"
3 #include <stdio.h>
4 int main()
5 {
6 printf("i = %d\n", i);
7
8 return 1;
9 }
一个头文件 my1.h
int i;

一个头文件 my2.h
int i = 2;

gcc编译
gcc -Wall myext1.c -o myext1
执行结果为: i = 2

是不是my2.h中int i = 2是既是声明有时定义,my1.h中的只是声明?

实验(3)
将头文件全部赋值
源文件myext1.c
1 #include "my1.h"
2 #include "my2.h"
3 #include <stdio.h>
4 int main()
5 {
6 printf("i = %d\n", i);
7
8 return 1;
9 }
一个头文件 my1.h
int i = 5;

一个头文件 my2.h
int i = 2;

gcc编译
gcc -Wall myext1.c -o myext1就报错
In file included from myext1.c:2:
my2.h:1: redefinition of `i'
my1.h:1: `i' previously defined here

在两个头文件中都做了定义所以报错,可以这样理解吗?
请问有关变量声明与定义的详细介绍。


c编译器在定义变量时,对变量初始化吗?
实验(4)
源文件myext1.c
1 #include "my1.h"
3 #include <stdio.h>
4 int main()
5 {
6 printf("i = %d\n", i);
7
8 return 1;
9 }
一个头文件 my1.h
int i;

gcc编译
gcc -Wall myext1.c -o myext1
执行结果为 i = 0

好像被初始化为0了。

实验(5)
源文件mydec.c
1 #include <stdio.h>
2
3 int main()
4 {
5 int i;
6 printf("i = %d\n", i);
7
8 return 1;
9 }
gcc编译
gcc -Wall mydec.c -o mydec
执行结果i = 11029664

好像没有被初始化为0呀。

实验(6)在源文件增加浮点型
1 #include <stdio.h>
2
3 int main()
4 {
5 int i;
6 float d;
7
8 printf("i = %d\n", i);
9 printf("d = %f\n", d);
10
11 return 1;
12 }

gcc编译
gcc -Wall mydec1.c -o mydec1
执行结果
i = 11029664
d = 0.000000

i好像没有被初始化为0
d被初始化为0了

为什么实验(4)i被初始化为0了,实验(5)没有被初始化为0,全局变量一般可以被初始化为0,但是局部变量没有被初始化为0,而是随机赋值?
实验(6)中,float d 被初始化为0,而int i没有,难道int i一般不被初始化?

请问有关c初始化详细的介绍。
...全文
619 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
明月书君 2013-06-15
  • 打赏
  • 举报
回复
引用 5 楼 linux_ljm 的回复:
[Quote=引用 2 楼 bdmh 的回复:] 局部变量,如果不认为初始,他的取值是随机的,是所分配的那块内存中数据 [/Quote] ++
编译不能同过吧
sx666777888 2013-06-15
  • 打赏
  • 举报
回复
引用 12 楼 q191201771 的回复:

int i;
int i;
int main()
{
 ...
}

int main()
{
int i;
int i;
...
}
两种都是重定义 不知道你是怎么得到你得到的结果的
我以前在我的机子上试过,完全可以
赵4老师 2011-01-14
  • 打赏
  • 举报
回复
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
就想叫yoko 2011-01-13
  • 打赏
  • 举报
回复

int i;
int i;
int main()
{
...
}

int main()
{
int i;
int i;
...
}

两种都是重定义
不知道你是怎么得到你得到的结果的
taodm 2011-01-13
  • 打赏
  • 举报
回复
我最怕这种不肯查标准,就靠自己试验的。
一个编译器得出的结论,在另外一个编译器下可能就完全失效。
而如果几个编译器下反应相同,经常就自己认为是真理了。
JZY4077 2011-01-13
  • 打赏
  • 举报
回复
在c语言中的int i都应该是定义,定义了当然会为其分配相应的内存空间!而在c语言中的extern int i才是真正的申明!而申明说明在以后的某个时刻要使用这个i的值!申明当然不会去分配内存空间了,因为我个人理解申明就是将别人定义好了的东西拿过来用!!

那么对于函数的定义就是函数体的实现,也就是下面这样一个格式:

类型 function(参数)

函数体代码实现


而函数的申明则是函数原型 ,比如int function(int x) ;这就是一个函数的申明!


在一楼的帖子中提到的那几个问题,我个人认为就是强弱符号的问题!

我们都应该知道在c语言中对于一个函数体中的局部变量只允许定义一个名称!而全局变量则可以定义相同的名称,比如在my1.c中定义一个int类型的变量i ,同样也可以在my2.c中也定义一个int类型的变量i!

在链接的时候又是如何链接的???当然要有一个“规定”!

c语言链接器 1)不允许具有多个强符号,只能够具有一个强符号。
2)如果有一个强符号和几个弱符号的话会选择强符号。
3)如果有多个弱符号的话则会随机选择一个弱符号。

引用:
实验(1)
源文件myext1.c
1 #include "my1.h"
2 #include "my2.h"
3 #include <stdio.h>
4 int main()
5 {
6 printf("i = %d\n", i);
7
8 return 1;
9 }
一个头文件 my1.h
int i;

一个头文件 my2.h
int i;

gcc编译
gcc -Wall myext1.c -o myext1
执行结果为: i = 0

myext1.c包含了两个头文件,就有两个int i;问什么没有报错呢?
是不是两个int i中,有一个是声明,有一个是定义,同时有对i进行了初始化,这样理解对吗?



楼主的这个理解我个人认为是不正确的,这两个都会是定义的,并且这两个符号都是弱符号,它会随机选择一个i来进行操作!!!

引用:

实验(2)
将头文件my2.h修改为 int i = 2;其他的文件不变。
源文件myext1.c
1 #include "my1.h"
2 #include "my2.h"
3 #include <stdio.h>
4 int main()
5 {
6 printf("i = %d\n", i);
7
8 return 1;
9 }
一个头文件 my1.h
int i;

一个头文件 my2.h
int i = 2;

gcc编译
gcc -Wall myext1.c -o myext1
执行结果为: i = 2

是不是my2.h中int i = 2是既是声明有时定义,my1.h中的只是声明?


c语言链接器会去链接my2.h的那个i,因为i被赋初值了,因此它就是一个强符号!


引用:

实验(3)
将头文件全部赋值
源文件myext1.c
1 #include "my1.h"
2 #include "my2.h"
3 #include <stdio.h>
4 int main()
5 {
6 printf("i = %d\n", i);
7
8 return 1;
9 }
一个头文件 my1.h
int i = 5;

一个头文件 my2.h
int i = 2;

gcc编译
gcc -Wall myext1.c -o myext1就报错
In file included from myext1.c:2:
my2.h:1: redefinition of `i'
my1.h:1: `i' previously defined here


在这里就出现了两个强符号,因此会报错!!!


至于楼主问的为什么全局变量会初始化而局部变量为什么没有进行初始化,我个人的理解就是:因为全局变量在程序运行之前就具有了内存地址空间,而会调用c运行时库中的inti()函数进行初始化(好像是这个函数吧,我记不太清楚了!),而局部变量则是在程序运行的时候才会去分配内存空间(堆栈内存),因此就不会进行一个初始化了!!!

以上只是我个人的理解,如果有什么错误欢迎指正!

NowDoIT 2011-01-13
  • 打赏
  • 举报
回复
lz细心,赞一个.可是结贴不足,汗一个.

我理解的是两个头文件中的int i; 这个是定义,而不是声明; 不管有无初始化;

全局变量,可以定义多次,但是只能初始化一次,就是说 int i = 1;int i = 2;在两个头文件中,是错误的.

全局变量和局部变量存在的位置不同,局部变量是在堆里,而全局变量有可能存储在寄存器里面.造成了二者的默认初始化不同吧!而且,全局变量初始化0,这个应该是编译器的缘故.

浮点数被初始化0,也是和编译器有关吧,这个应该有单独的寄存器.

个人意见,仅供参考!
appx 2011-01-13
  • 打赏
  • 举报
回复
对于int i;是声明还是定义:有这样一种说法,当使用这个变量时就到前面区寻找,如果找不到任何地方有对其的定义就把其当作定义,为其分配空间,一旦当这里分配空间后其他地方就被当作声明了。对于int i=5;之类的用法却只能是定义,因为这种操作存在内存空间的分配。(根据是否需要对其进行内存分配原则来判断是声明还是定义就是最好的判断方法了)
lizj3624 2011-01-13
  • 打赏
  • 举报
回复
自己有做了实验:
c语言int, short, long, float, double类型初始化
mydec1.c源文件
2 #include <stdio.h>
3
4 int main()
5 {
6 int i;
7 short j;
8 long k;
9 float d;
10 double l;
11
12 printf("i = %d\n", i);
13 printf("d = %f\n", d);
14 printf("j = %d\n", j);
15 printf("l = %f\n", l);
16 printf("k = %d\n", k);
17
18 return 1;
19 }
编译后执行结果
i = 11029664
d = 0.000000
j = 0
l = 0.000000
k = 12632052

引入同文件,全局变量
1 #include "my1.h"
2 #include <stdio.h>
3
4 int main()
5 {
6 /* int i;
7 short j;
8 long k;
9 float d;
10 double l;
11 */
12 printf("i = %d\n", i);
13 printf("d = %f\n", d);
14 printf("j = %d\n", j);
15 printf("l = %f\n", l);
16 printf("k = %d\n", k);
17
18 return 1;
19 }

执行结果是
i = 0
d = 0.000000
j = 0
l = 0.000000
k = 0

总结:short, float, double在局部变变量还是全局变量时,都会被初始化,int, long只有在全局变量时才会被初始化。
linux_ljm 2011-01-11
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 bdmh 的回复:]

局部变量,如果不认为初始,他的取值是随机的,是所分配的那块内存中数据
[/Quote]

++
proghua 2011-01-11
  • 打赏
  • 举报
回复
全局变量如果不进行初始化,编译器会将其初始化为0,局部变量如果不进行初始化,局部变量不会进行初始化
無_1024 2011-01-11
  • 打赏
  • 举报
回复
i的值是随机的 要注意初始化的问题
bdmh 2011-01-11
  • 打赏
  • 举报
回复
局部变量,如果不认为初始,他的取值是随机的,是所分配的那块内存中数据
awsqsh 2011-01-11
  • 打赏
  • 举报
回复
全局变量一般可以被初始化为0,但是局部变量没有被初始化为0

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧