关于C++变量初始化的总结(转载+自己总结)
来源:互联网 发布:交换机更换网络 编辑:程序博客网 时间:2024/04/30 07:34
当定义没有初始化的变量时,系统有可能会为我们进行隐式的初始化,至于系统是否帮我们隐式初始化变量,以及为变量赋予一个怎么的初始值,这要取决于该变量的类型以及变量的定义域。
1.内置类型变量的初始化
内置变量是否自动初始化,取决于该变量的定义域。
①在全局范围内的内置类型变量均被编译器自动初始化为0值
#include<iostream>using namespace std;//全局范围内的部分内部变量int gi; //被自动初始化为0float gf; //被自动初始化为0.0double gd; //被自动初始化为0.0char gc; //被自动初始化为'\0'int main(int argc, char **argv){ return EXIT_SUCCESS;}②在函数体内定义的内置类型变量值随机(有的编译器可能会为你初始化为0,但千万别依赖于这种可能行为,因为它会给你的程序带来未定义的行为)
#include<iostream>using namespace std;int main(int argc, char **argv){ //局部范围内的部分内部变量 int i; //不被自动初始化,值随机(有可能是0,依编译器实现而定) float f; //不被自动初始化,值随机(有可能是0,依编译器实现而定) double d; //不被自动初始化,值随机(有可能是0,依编译器实现而定) char c; //不被自动初始化,值随机(有可能是0,依编译器实现而定) return EXIT_SUCCESS;}③内置类型数组的初始化规则同上
#include<iostream>using namespace std;//全局范围内的内置类型数组int gIntArr[5]; //5个元素都被初始化为0int main(int argc, char **argv){ //局部范围内的内置类型数组 int intArr[5]; //未被初始化 return EXIT_SUCCESS;}这里需要特别强调一点,数组初始化如下:
char str[10];//没初始化的for(int idx=0;idx<10;idx++){std::cout<<(int)str[idx]<<' ';}std::cout<<std::endl;memset(str,0,sizeof(str)); //初始化后的for(int idx=0;idx<10;idx++){std::cout<<(int)str[idx]<<' ';}std::cout<<std::endl;char str1[10] = "";char str2[10] = {};//VC++6.0下报错,不支持这种语法char str3[10] = {0};for(int idx=0;idx<10;idx++){std::cout<<(int)str1[idx]<<' ';}std::cout<<std::endl;for(int idx=0;idx<10;idx++){std::cout<<(int)str2[idx]<<' ';}std::cout<<std::endl;for(int idx=0;idx<10;idx++){std::cout<<(int)str3[idx]<<' ';}std::cout<<std::endl;system("pause");输出结果
-52 -52 -52 -52 -52 -52 -52 -52 -52 -520 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0Press any key to continue . . .char buffer[260]="";char buffer[260]={0};memset( buffer, 0, sizeof(buffer)/sizeof(char));所以以上三种是等效的,个人比较习惯memset,这种是直接操作内存的,而其他方法大多数都是依赖系统或者编译器的。
CString初始化 CString str; str = ""; 如果是多字节str = _T(""); 清空str.Empty();
值得注意的是:
char buffer[4];memset(buffer,0,sizeof(char)*4);strcpy(buffer,"123");//"123"中最后隐藏的'\0'占一位,总长4位。这里的memset是多余的. 因为这块内存马上就被全部覆盖,清零没有意义.另:以下情况并不多余,因某些编译器分配空间时,内存中默认值并不为0:char buffer[20];memset(buffer,0,sizeof(char)*20);memcpy(buffer,"123",3);//这一条的memset并不多余,memcpy并没把buffer全部覆盖,如果没有memset,//用printf打印buffer会有乱码甚至会出现段错误。//如果此处是strcpy(buffer,"123");便不用memset,//strcpy虽然不会覆盖buffer但是会拷贝字符串结束符这种情况如果没有memset将buffer初始化为0的话,copy过后的buffer肯定会有乱码
memset可以方便的清空一个结构类型的变量或数组。如:
struct sample_struct { char csName[16]; int iSeq; int iType; };对于变量
struct sample_strcut stTest;
一般情况下,清空stTest的方法:
stTest.csName[0]='/0';
stTest.iSeq=0;
stTest.iType=0;
用memset就非常方便:
memset(&stTest,0,sizeof(struct sample_struct));
如果是数组:
struct sample_struct TEST[10];
则
memset(TEST,0,sizeof(struct sample_struct)*10);
memset()的深刻内涵:用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为‘memset(a, '/0', sizeof(a));memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。
strcpy就只能拷贝字符串了,它遇到'/0'就结束拷贝;例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个‘/0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。
2.类类型变量的初始化
类类型变量是通过构造函数进行初始化的,不论类类型变量在哪里(全局或者局部)定义,该类类型变量的构造函数(默认构造函数或者指针的参数构造函数)总会被调用。
想要知道构造函数在各种情况下如何初始化类中数据成员的,我们必须首先了解构造函数的初始化发生在何时?
//构造函数中的初始化发生在构造函数的初始化列表中//而非构造函数体中class Foo{ public: Foo(int i):_integer(i) //初始化列表中进行的是初始化 { //这里是构造函数的函数体 //在这里进行的是赋值操作,而不是初始化 _integer = i; } private: int _integer;};既然构造函数的初始化是发生在初始化列表中的,那么,对于初始化列表中没有显示进行初始化的内置类型变量来说,其初始化规则就与上述内置变量的规则相同了。
#include<iostream>using namespace std;class Foo{ public: Foo(void):_explicitInit(1024){} private: int _explicitInit; //在构造函数初始化列表中 //显式初始化的内置类型变量 int _implicitInit; //没有在构造函数中显式初始 //化的内置类型变量};Foo gF; //全局范围内的类类型变量,_explicitInit被 //显式初始化为1024,_implicitInit被自动初始 //化为0int main(int argc, char **argv){ Foo f; //局部范围的类类型变量,_explicitInit被 //显式初始化为1024,_implicitInit不会被 //自动初始化,值随机 return EXIT_SUCCESS;}C++的类中内置类型的成员变量的初始化:
//test.hclass test{ private:int a;//普通成员const int b;//常量成员static int c;//静态成员static const int d;//静态常量成员int &e;//引用类型成员};成员变量的初始化有且仅有两种:
1)用“=”赋值
2)用成员初始化列表
记住一点:只能用成员初始化列表有两类:常量成员(注意没有静态常量成员)和引用类型成员。
再记住一点:静态成员和静态常量成员由于是类共有的,不是属于某一个对象的,因此不能再构造函数中初始化。
最后记住一点:静态成员(这里不包括静态常量成员)必须在类外初始化。
最后的最后记住一点:引用变量必须初始化后才能使用。
class test{//int a=1;//错误:对象没有构造,尚未分配内存空间int a;const int b;//static int c=1;//错误:不可以在声明时初始化static int c;const static int d=1;//唯有该类型可以这样int &e;//引用类型必须用成员初始化列表public:test(int _e):b(1),e(_e)/*引用初始化必须为左值*/{}};int test::c=1;const int test::d=1;//也可以这样初始化//test.hclass test{public: test(); test(int _e); ~test();private:int a;//普通成员const int b;//常量成员static int c;//静态成员static const int d;//静态常量成员int &e;//引用类型成员};//test.cpp//静态成员变量以及const静态成员变量int test::c = 1;const int test::d = 1;test::test(){}test::test(int _e) :a(1),e(_e) //引用初始化必须为左值{}test::~test(){}
- 关于C++变量初始化的总结(转载+自己总结)
- 变量的初始化总结
- mysql数据库优化总结(转载加自己的总结)
- 关于初始化数据的总结
- 关于初始化列表的总结
- java - 变量初始化总结
- Java 变量初始化总结
- 总结一些转载的 初始化列表
- 各类型变量的自动初始化总结
- 类的成员变量初始化总结
- C++变量及初始化的总结
- C++中成员变量的初始化总结
- C++ 成员变量的初始化方法总结
- C\C++编译器关于变量的内存分配顺序总结
- C\C++编译器关于变量的内存分配顺序总结
- C\C++编译器关于变量的内存分配顺序总结
- 转载-关于CString的总结
- 转载-关于CString的总结
- Java中类与方法的学习笔记(一):
- Objective-C Runtime 运行时之三:方法与消息
- js日期格式化
- RARF:基于响应式抽象资源流的深度RESTful实践(不知道是不是坐井观天)
- 二叉树的操作
- 关于C++变量初始化的总结(转载+自己总结)
- po/mo互相转换工具
- Android开发探索第一章 Activity生命周期及启动模式总结(三)
- 视图
- Problem Joseph。。。lzl==sz
- mysql字段类型
- Java日期处理
- 注解式框架Butterknife的用法
- EditPlus批量更改文件编码