小芳前几天问了我一个问题,是关于指针初始化的。她当时给一个未初始化的字符串指针赋值,结果当然是错的(其实这句话是值得商量的)。虽然当时我发现了她的错误,但是我自己也不明白这为什么是错的。很是惭愧啊,辜负了小芳的期望。当天晚上我欧洲杯都没看,整晚上都在翻看C++Primer,总算是弄明白啦。
快期末啦,这几天都比较忙,就一直没有时间给小芳讲。也是今天不想背马哲了才有空写这篇日志,事隔几天才把没完成的任务补上。希望小芳看完之后能明白当时错的原因,也作为自己的学习笔记留着以后总结用。
C++ Primer中有关于变量的初始化问题的解释:
变量定义指定了变量的类型和标识符,也可以为对象提供初始值。定义时指定了初始值的对象被认为是已初始化的。C++支持两种初始化变量的形式:复制初始化和直接初始化。
复制初始化语法用等号(=),直接初始化则是把初始化式放在括号中:
intival(1024);// direct-initialization
int ival =1024; //copy-initialization
这两种情形中,ival 都被初始化为 1024。
虽然在本书到目前为止还没有清楚说明,但是在 C++中理解“初始化不是赋值”是必要的。初初化指创建变量并给它赋初始值,而赋值则是擦除对象的当前值并用新值代替。
我们通过对变量的显式初始化确保我们用它们的时候程序不会崩溃。但是当我们不显式初始化变量时:
内置类型变量是否自动初始化取决于变量定义的位置。在函数体外定义的变量都初始化成0,在函数体里定义的内置类型变量不进行自动初始化。除了用作赋值操作符的左操作数,未初始化变量用作任何其他用途都是没有定义的。
string类型的变量会被默认初始化为空字符串,因为string是一个类,它会调用默认构造函数将未显式初始化的变量初始化为空字符串。
大神就是大神,看过之后果然有恍然大悟的感觉。但是这讲的是普通变量的初始化,并不是指针变量的的初始化。
int *ival(1024);//invalid conversion from 'int' to 'int*'
int * ival =1024;//invalid conversion from 'int' to 'int*'
这两种情形中,ival 都不能被正确的初始化。
指针的初始化一般形式(其实还有把指针初始化为 0的情况,这个自己百度吧):
int ival = 1024;
int *pi2 = & ival; // pi2initialized to address of ivalpi =pi2;// pi and pi2 address the same object, e.g. ival
给未初始化的指针赋值(其实在这儿我们也可以用另外一种方式使用未初始化指针):
char*name;// not initialized这会导致程序意外终止,编译器一般是不会发现这个错误的(但是VC++2010告诉我name未初始化,哈哈),所以应该初始化指针变量。char *pname ="LOVE";//initialized
strcpy(name,pname);//uninitialized local variable 'name' used
使用未初始化的指针往往会带来问题:
就像使用其他没有初始化的变量一样,使用未初始化的指针时的行为C++标准中并没有定义使用未初始化的指针,它几乎总会导致运行时崩溃。然而,导致崩溃的这一原因很难发现。
对大多数的编译器来说,如果使用未初始化的指针,会将指针中存放的不确定值视为地址,然后操纵该内存地址中存放的位内容。使用未初始化的指针相当于操纵这个不确定地址中存储的基础数据。因此,在对未初始化的指针进行解引用时,通常会导致程序崩溃。
那我们要怎么做呢?
char *name;
char *pname = "LOVE";
name = new char[strlen(pname)+1];
strcpy(name, pname);
虽然name没有初始化,但是我们给它申请了空间,它所指向的空间就是确定的了。对这个空间的引动不会出现问题。当然,我们可以直接初始化name指针,就像char *name = "I";但是这样也不能省略为 name 申请新空间的语句。申请新空间是为了保证 name 与 pname的空间大小一致。
当然,如果你用的是 string* 而不是 char*的话不申请新空间也是可以的,但最好不要那么做。
其实我们还可以这么做:
char *pname = "LOVE";
char *name = pname;
或者
char * pname = "LOVE";
char *name;
name = pname;
好吧,其实这些都是浮云,最好还是老老实实初始化你的每一个指针,别的小技巧只会给你带来意外的麻烦。
尽量初始化你所要用的变量,我好多次都是因为这样程序怎么都编译不通过,或是提示你编译器遇到不可知的错误,然后就崩溃啦。
关于变量的初始化,还要说一下道静态变量和全局变量。静态变量和全局变量会在编译阶段初始化为 0。