首页 > 代码库 > C++查缺补漏之变量

C++查缺补漏之变量

什么是变量?

我们在日常编程中经常会有int a=10;,那么这个a就是变量。变量提供了程序可以操作的有名字的存储区,要是在汇编时代,我们是直接操作寄存器和内存地址的,那么现在就把底层的寄存器和内存地址抽象出来,取了一个别名,通过这个别名也可以操作这块内存。

C++中每一个两边都要有一个特定的类型,该类型决定了变量的大小和布局,能够存储于该内存中的值的取值范围,以及可以在该变量上进行的一些操作。C++中经常把变量称为“变量”或“对象”。


什么是对象?

什么是对象?一般而言,对象就是内存中具有类型的区域,也就是计算左值表达式就会产生对象。


定义对象

1.变量初始化


在C++中变量的初始化一般分为直接初始化复制初始化:

  • 直接初始化:用‘()‘号来实现:int a(10);
  • 复制初始化:用‘=‘号来实现:int a =10;

注意事项:在C++里面初始化并非赋值,首先初始化是值创建变量并赋值,而赋值指的是变量之前就存在,只不过是擦除当前对象的值并赋予新值。

比如下面的:

int a=10;//复制初始化<span style="font-family:Comic Sans MS;">//+++++++++++++++++++++++</span><span style="font-family:Comic Sans MS;">int b;b=10;//赋值,并非初始化</span>
分清这两者的区别对于C++编程尤为重要!


2.初始化多个变量

我们首先来看一个简单的C++赋值语句:

int number = number;

这个语句是正确还是错误呢?

当一个定义中定义了两个以上的变量的时候,每个变量都可能有自己的初始化式,对象的名字立即变为可见,所以可以用同一个定义中前面已定义的变量初始化后面的变量:

int number1=10,number2=number1;

那么如果是int number = number这样的式子呢?我们前面讲过复制初始化分为两步,第一步就是创建一个变量,第二步才是赋予新的值,我们首先创建了number这个变量,那么number变量马上可见,然后再用可见的number来初始化自己(虽然这样做毫无意义,最终还是没有初始化)。所以这个式子编译器是不会报错的。


变量的初始化规则

变量的初始化可以分为两种:

  • 内置类型变量的初始化:内置类型变量是否自动初始化取决于变量定义的位置:1.函数体外定义的变量自动初始化为0。2.函数体内定义的变量补自动初始化,除了用作左值来进行赋值,为初始化的变量用作其他用途都是未定义的。注意:建议每个内置类型的对象都进行初始化,虽然这样做不是必须的,但是会增加程序的安全性。
  • 类类型变量的初始化:如果定义某个类时没有提供初始化式,这个类也可以自动调用默认构造函数(没有任何初始化式,那么就调用缺省构造函数)来对其进行初始化,比如std::string类,如果没有初始化式(std::string str;),那么就自动调用缺省构造函数来初始化str为空串。注意:如果用户没有定义任何构造函数,那么为了满足编译的需要,编译器会自动为你生成一个默认构造函数,这个默认构造函数没有任何初始化效果,仅仅是为了满足编译的需要,如果用户定义了一个或者多个构造函数,那么系统将不会再自动生成默认构造函数,所以在你自定义构造函数的时候,最好也自定义一个缺省构造函数(默认构造函数)。减少在没有初始化式定义时(数组,动态数组,容器,作为一个类成员等等)的编译出错。(缺省构造函数详见:http://blog.csdn.net/wuliming_sc/article/details/3855270)

定义和声明

分清变量的定义和变量的声明在后续的编程中也是尤为重要的

变量的定义:用于为变量分配内存空间,还可以为变量指定初始值。在一个程序中,变量有且只有一个定义

变量的声明:用于向程序表明变量的类型和名字。定义也是声明:在定义变量时我们定义了它的类型和名字。我们可以使用extern关键字来表明是在声明而不是在定义。

如:

extern int a ;//声明
int a ;//定义
extern不分配存储空间,只能说明变量定义在程序的其他地方,比如在其他的C文件里面:

<span style="font-size:18px;">//example.cint a=10;//++++++++++++++++++//main.cextern int a;main(){    int b=a;//b=10;}</span>
编译结果为:

gcc -c main.c -o main.o
cc    -c -o example.o example.c
gcc main.o example.o

没有任何问题。


如果在声明时有初始化式子,那么它就可以被当做是定义!

<span style="font-family:Comic Sans MS;font-size:18px;">//example.c
int a=10;
//++++++++++++++++++
//main.c
extern int a=11;//错误,在链接两个example.o 和 main.o的时候a就重定义了
main(){
    int b=a;//b=10;
}</span>
gcc -c main.c -o main.o
main.c:4:12: warning: ‘a’ initialized and declared ‘extern’ [enabled by default]
 extern int a=11 ;
            ^
cc    -c -o example.o example.c
gcc main.o example.o
example.o:(.data+0x0): `a‘被多次定义
main.o:(.data+0x0):第一次在此定义
collect2: error: ld returned 1 exit status
make: *** [main] 错误 1







C++查缺补漏之变量