本文共 4255 字,大约阅读时间需要 14 分钟。
(1)从变量的定义位置分,可分为全局变量与局部变量。其中,局部变量定义在函数或复合语句中,供函数或复合语句中使用。
(2)变量的存储类型分为auto,extern,register, static。当声明一个静态(static)变量,它既具有局部变量的性质,又具有全局变量的性质。
(3)C++程序的内存分为4个区:全局数据区,代码区,栈区,堆区。全局变量,静态变量,字符串常量存放在全局数据区,所有在函数和代码存放在代码区,为运行函数而分配的函数参数,局部变量、返回地址存放在栈区。动态分配的内存在堆区。
(4)全局变量,静态变量具有静态生存期;局部变量生存期为动态。
(5)函数原型中形参标识符的作用域为为函数原型,函数的形参与
函数体作用域为块作用域;函数,全局变量与常量有文件作用域。
( 6)C++源程序中以#开头,以换行符结尾的行称为预处理命令。预处理命令编译前由预处理器执行。
( 7)可以通过3种方法使用名字空间,个别使用声明方式,全局声明方式,全局声明个成员。
2.
(1)在C++中,函数默认的存储类别为:auto。
(2)函数的形式参数是局部变量,在一个函数体内定义的变量只在本函数范围内有效, 在函数的复合语句中定义的变量只在此复合语句中有效 。
( 3) # define PI 3.14 预处理命令必须以 #开头,凡是以 #开头的都是
预处理命令行,在程序执行前执行预处理命令。
( 4)动态分配的内存要用 delete释放,局部 auto变量分配的内存在
函数调用结束时释放,全局变量的内存在程序结束时释放。
memset问题
memset初始化函数:将某一块内存中的内容全部设置为指定的值,即做初始化工作。
memset原型:
【答案】
作初始化函数,将某一块内存中的内容全部设置为指定的值。
参数:s是需要初始化的变量,ch是替换s首n个字节的值,n是n个字节。
char *s=”Golden Global View”;
memset(s,’G’,6);
【答案】
是错误的。因为s已指向一个常量字符串。所以无法用memset函数来对此s进行修改值。
memcpy(buffer,”123”,3)
【答案】
错误。因为buffer没有被初始化,也就是没有值,如果直接使用memcpy函数的话,就会打印出后面的值是乱码的。
应该修改为:
char buffer[20];memset(buffer,0,sizeof(char)*20);
memcpy(buffer,”123”,3);
【答案】
char data[10];memset(data,0,sizeof(data));//0memset(data,-1,sizeof(data));//-1memset(data,1,sizeof(data));//1
一般memset设置值的范围为0—255.这是因为后八位才是有效的值,后八位的前面位数无论设置多少的值,一律都按后八位的值来计算。比如说:0100 0000 0110 0001,就算设置了这个值,处理结果仍然按照后八位0110 0001来输出。如果data是char类型,输出结果范围为-128到127。
那么在int ,float,double类型方面就不同了,结果有效值只为0或-1,不能设置为1,否则,输出结果就会是随机数。
如果是bool类型,则结果有效值为0到255。
如果是其他对象:
structdata data;memset(&data,0,sizeof(structdata));
struct Data{int *p;};Data data;data.p=new int[10];memset(data,0,sizeof(data));
【答案】
不正确。虽然编译通过,但是当解引用结构体内的p指向的内容会使程序崩溃。因为memset函数只是初始化该结构体,但是对p指向的堆内存并没有进行初始化,并且调用该函数时,p将会设置值为0,即空指针。这也会造成内存泄漏的问题,导致无法获知地址并无法释放掉此堆内存。
malloc问题
【答案】
说明你用的是C++编译器而不是C编译器。
【答案】
多数malloc/free的实现并不把释放的内存返回操作系统,而是留着供同一程序的后续malloc()使用。
malloc/free的实现会在分配的时候记下每一块的大小,所以在释放的时候就不必再考虑它的的大小了。(通常,这个大小就记录在分配的内存块旁边,因此,对超出分配内存块边界的内存哪怕是轻微的改写,也会导致严重的后果。)
【答案】
sizeof操作符并不知道你使用了malloc为指针分配内存,sizeof只能得到指针本身的大小。没有什么可移植的办法得到malloc分配的内存块的大小。
【答案】
calloc(m,n)本质上等价于
p=malloc(m*n);
memset(p,,m*n);
除了参数个数不同和用零填充之外,这两个函数并无其他重要的区别。
【答案】
段错误通常发生在访问非法内存地址的时候,比如使用野指针,或者试图修改字符串常量的内容
【答案】(答案摘自某博文)
1、new分配内存按照数据类型进行分配,malloc分配内存按照指定的大小分配;
2、new返回的是指定对象的指针,而malloc返回的是void*,因此malloc的返回值一般都需要进行类型转化。
3、new不仅分配一段内存,而且会调用构造函数,malloc不会。
4、new分配的内存要用delete销毁,malloc要用free来销毁;delete销毁的时候会调用对象的析构函数,而free则不会。
5、new是一个操作符可以重载,malloc是一个库函数。
6、malloc分配的内存不够的时候,可以用realloc扩容。扩容的原理?new没用这样操作。
7、new如果分配失败了会抛出bad_malloc的异常,而malloc失败了会返回NULL。
8、申请数组时: new[]一次分配所有内存,多次调用构造函数,搭配使用delete[],delete[]多次调用析构函数,销毁数组中的每个对象。而malloc则只能sizeof(int) * n。
【答案】
1)A *a:a是一个局部变量,类型为指针,故而操作系统在程序栈区开辟4/8(在32位机器下,为4个字节)字节的空间(0x000m),分配给指针a。
2)new A:通过new动态的在堆区申请类A大小的空间(0x000n)。
3)a = new A:将指针a的内存区域填入栈中类A申请到的地址的地址。即*(0x000m)=0x000n。
4)a->i:先找到指针a的地址0x000m,通过a的值0x000n和i在类a中偏移offset,得到a->i的地址0x000n + offset,进行*(0x000n + offset) = 10的赋值操作,即内存0x000n + offset的值是10。
【答案】
virtual修饰符
如果一个类是局部变量则该类数据存储在栈区,如果一个类是通过new/malloc动态申请的,则该类数据存储在堆区。
如果该类是virutal继承而来的子类,则该类的虚函数表指针和该类其他成员一起存储。虚函数表指针指向只读数据段中的类虚函数表,虚函数表中存放着一个个函数指针,函数指针指向代码段中的具体函数。
如果类中成员是virtual属性,会隐藏父类对应的属性。
【答案】
静态变量中的数据段和BSS段,在执行代码之前初始化,也属于编译器初始化。但对于静态对象来说,当对象首次创建,则就会对这些对象进行构造并初始化,直至程序退出才会销毁内存。
【答案】
没有回收垃圾资源。
【答案】
可以,在不同的C 文件中以static形式来声明同名全局变量。可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。
【答案】
可以用引用头文件的方式,也可以用extern 关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变量写错了,那么在编译期间会报错,如果你用extern 方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。
【答案】
static的全局变量,表明这个变量仅在本模块中有意义,不会影响其他模块。
他们都放在静态数据区,但是编译器对他们的命名是不同的。如果要使变量在其他模块也有意义的话,需要使用extern 关键字。
该函数被C 编译器编译后在库中的名字为_foo,而C++ 编译器则会产生像_foo_int_int之类的名字。 C++提供了C 连接交换指定符号extern“C”来解决名字匹配问题。
转载地址:http://cwwab.baihongyu.com/