易截截图软件、单文件、免安装、纯绿色、仅160KB

C/C++ 的全局变量初始化与不初始化的区别

在C语言里,全局变量如果不初始化的话,默认为0,也就是说在全局空间里:
int x =0; 跟 int x; 的效果看起来是一样的。但其实这里面的差别很大,强烈建议大家所有的全局变量都要初始化,他们的主要差别如下:
编译器在编译的时候针对这两种情况会产生两种符号放在目标文件的符号表中,对于初始化的,叫强符号,未初始化的,叫弱符号。
连接器在连接目标文件的时候,如果遇到两个重名符号,会有以下处理规则:
1、如果有多个重名的强符号,则报错。
2、如果有一个强符号,多个弱符号,则以强符号为准。
3、如果没有强符号,但有多个重名的弱符号,则任选一个弱符号。
基于以上规则看下面的程序:(编译器为gcc 3.4.6, VC下结果不一样)
main.cpp
int x;
void foo();
int main(int argc, char* argv[])
{
printf("x1:%d\n", x);
foo();
printf("x2:%d\n", x);
return 0;

var.cpp
int x;
void foo()
{
x = 2;

因为两个文件里面的x都被初始化了,所以编译出来的两个目标文件里x都是强符号,连接的时候会报错:
multiple definition of `x' 
符合规则1。
把var.cpp里面的int x = 0;改成 int x; 不做初始化,编译、连接无任何警告,运行结果为:
x:1
x:2
说明连接的时候以main.cpp中的x为准,foo函数修改的是main.cpp中定义的x。符合规则2。
把main.cpp中的初始化也去掉,改成 int x; 编译、连接仍然很顺利,运行结果为:
x:1
x:2
说明main函数和foo函数修改的是同一个x,连接器自己选择了一个x,符合规则3.
大部分情况下,我们不希望连接器为我们做决定,所以我不是很认同后两个规则,至少应该给个警告,而不应该安静地通过。
也许写var.cpp的人根本不知道main.cpp里面也有一个x呢,foo函数的本意也许并不是要修改main.cpp中的x。因为这种问题引起的bug会很难查。
所以我们要尽量把全局变量初始化,对于不想给别的文件引用的变量,也尽量用static修饰。
除了连接时的表现不一样外,为初始化的符号在目标文件的bss段中,而初始化的符号在data段中。


相关文档:

C若干实用小技巧

Visual C++6.0(5.0)开发工具功能非常强大,但是对于初学者来说,却有很多细节的问题需要注意。作者搜集整理了以下一些实用小技巧,希望对初学者有所帮助。
  1:使用vc开发项目时,常会遇到这种情况:
    即明明只改动了一个文件,却要把整个项目全部重新编译连接一次。刚刚连接好,一运行,又提示 ......

C/C++中的函数参数传递机制(转载)

 一、 函数参数传递机制的基本理论   函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进行通信的方法问题。基本的参数传递机制有两种:值传递和引用传递。以下讨论称调用其他函数的函数为主调函数,被调用的函数为被调函数。  值传递(passl-by-value)过程中,被调函数的形式参 ......

C/C++语言中Static的作用详述

在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条。
(1)先来介绍它的第一条也是最重要的一条:隐藏。
当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。为理解这句话,我举例来说明。我们要同时编译两个源文件,一个是a.c,另一个是main.c。
下面是a.c的内容
ch ......

一道C笔试题

Author: Scurffybear Date: 2009.09.08
最近在招新人,下面是一道C的面试题,面试的印度人中,没有一个人做对,我粗看了一下题,在没有看答案前,我自己也做错了,嗯,是的,没啥不好意思的,我觉得这个题目很容易使人产生误解,又或者择C有深厚功底的人能躲过这一个障眼法?
以下是题目,
main()
{
char * ......

《编程珠玑》问题的C实现——2:向量旋转

 #include <stdio.h>
#include <stdlib.h>
#define SIZE 17
void reverse(int start, int end);
int data[SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
int main(void)
{
int i = 5;
reverse(0, i - 1);
reverse(i, SIZE-1);
reverse(0, SIZE-1);
return ......
© 2009 ej38.com All Rights Reserved. 关于E健网联系我们 | 站点地图 | 赣ICP备09004571号