c++面试---基本概念

来源:互联网 发布:java云计算框架 编辑:程序博客网 时间:2024/06/12 23:29

构造函数

类可以包含多个构造函数,不同的构造函数之间必须在参数数量或参数类型上有所区别。
构造函数是和类名一致,并且没有返回类型,构造函数在定义变量时自动执行。
1.类的构造函数被自动调用执行的情况发生在定义该类的对象时。
2.局部变量和全局变量是可以重名的,而且一般来说在某个函数体内,局部变量是会覆盖全局变量的。
3.inline函数表示编译器一定会将函数体直接插入到调用此函数的地方,这样可以加快程序的运行速度(×)
内联函数与其他普通函数的区别是,内联函数在生成可执行文件时,其代码块是直接嵌入到调用处的,以此减少函数调用的开销提高程序性能,它与宏很类似。内联说明(inline specification)对于编译器来说只是一个建议,编译器可以选择忽略这个建议。也就是说,是否以嵌入式方式存在,是由编译器决定的,并不是一定。
4.class类中成员不显示定义属性时,则默认是private类的,构造函数是私有的话,就限制了创建对象。
6.类外不能访问,私有成员和保护成员。

构造/析构函数性质




存储和分配

1.静态局部变量内存是在运行期分配的,存储在堆栈区(x)
2.malloc申请的是虚拟内存,并不是物理内存。malloc能够申请的空间大小与物理内存的大小没有直接关系,仅与程序的虚拟地址空间相关。
3.free释放的内存不一定直接还给操作系统,可能要到进程结束才释放。
4.内存泄露一般是指程序申请了一块内存,使用完后,没有及时将这块内存释放,从而导致程序占用大量内存。
5.static 静态变量和静态函数都可以在类外直接访问,
   extern 可以用于声明变量,但是函数声明也可以用,只不过默认就是extern而已。
   const也可以修饰函数或者变量。
6.

编程技巧

1.快速二进制转化

x 与 x-1 每次相与操作都会导致 x 二进制中的一减少一个,如果 x 是500,二进制是111110100,则循环6次可以使得 x 变成 0。
如何快速的求得 x 的二进制数字?
http://blog.163.com/kongdelu2009@yeah/blog/static/111995207201037105051259/
                             
500 = 254+254-8 = 1111 1110+1111 1110 -0000 1000 = 1 1111 0100。

2.i++/++i区别

这个程序循环的次数是 4 次。这里想总结下自加的两个区别。
第一点:记住的是:如果不是赋值语句,则 i++ 与++i 没有区别,结果都是 i +1。同理 for 循环中,两个没有区别。
第二点:如果是赋值语句:a = i++ 与 a =++i;则需要记住:i++先输出后加一,++i 则是先加1后输出。

2.1 ++i 举例

void  main(){   int x = 0, y = 5, z = 3;    while(z-->0 && ++x<5)      {         y= y - 1;      }    printf("%d, %d, %d\n", x, y, z);   }
第一次循环: z = 3 > 0 && x = 1 < 5  ;   x =1; y = 4; z = 2
第二次循环: z = 2 >0 && x = 2 < 5 ;  x = 2  y = 3; z = 1; 
第三次循环: z = 1>0 && x = 3 < 5 ;  x = 3  y = 2; z = 0; 
第四次循环: z = 0 >0  ; 不满足条件,退出。此时 z 已经减一。
则结果是:    x = 3  y = 2; z = -1; 

3.c++--传值,传址与引用


输出的结果:10  20 20
fun2函数是传址调用,实参是地址变量,用 & 取地址传递给形参指针 *x。在函数中对指针所指向的值进行处理,实现了 n的值变化。
fun3函数是传引用引用传递就是给实参中的变量起一个别名。引用传递没有自己的单独的内存空间,作为别名,它和实参变量共用一段内存空间,形参用&别名。从而给实参变量起了一个别名,对别名变量进行处理的结果也会影响到实参。
fun1函数是传值调用传值:实参与形参是两个变量,占用了两个不同的内存空间。所以他们传递是单向的,即实参只能把值传给形参。形参修改后不会影响到实参。
注意的是:fun2已经把 n 的值变成 10,而 fun3 把 n 的值变成 20。所以最后的 n 是 20。

4.传递动态内存

 
在 swap 函数中,int * temp 新建一个指针但是没有分配内存。而 *temp = *p 是把 *p 纸箱内存中的值拷贝给 *temp,因为 int *temp 没有分配地址。所以系统给了一个随机的地址来存储数值,分配随机地址是一个意外,并且函数结束后收回,造成内存泄漏。因此无法实现交换。
解决办法:
因为 int * temp 没有分配地址,所以造成内存泄漏,我们可以在初始化时候给 temp 分配一个固定的地址。这样就可以实现交换。
 
2.

int *temp 新建一个指针,temp = p ;就是 temp 指向了 p  指向的地址。在 swap 中实现了 p 和 q 所指向的地址交换。但是在 主函数中并没有实现 a 和 b 交换。
3. swap2 和 swap3 可以实现交换

4.

输出是乱码,因为 在 GetMemory中,char p[]= "Hello world"; 分配是一个局部数组,存储在栈区,函数调用完成后,栈中数据不会保存。
修改方法:char p[]= "Hello world"; 改为:char *p = "Hello world"; 是一个全局数组。
5.指针的“传值”与"传址"


在 GetMemory1 中,p所指向的内存地址发生变化,但是 str 并没有发生改变,并不能正确输出。
我们把指针的地址传进去,就和之前的实参传址一样,在函数 GetMemory1内部对 str 所指的内存进行修改。可以正确输出


6.函数返回值来传递动态内存

7. c/c++读入

cin  遇到空格结束读入。
scanf 函数会以空格,回车,TAB按键作为一次的输入。

8.判断字符的大小

 char ch = '3';     //字符定义 if(ch >='0'&& ch <='9') //字符比较
两个字符相减是,ASC码相减。
 int x; char ch = '3'; x = '9'- ch;
char x;char ch = '3';x = '9'- ch +'0'; // '9'-ch得到的是整形,需要+'0',转化为字符形。
int  ch = '3';printf("%d",ch); //输出是 51,输出是 ch 的ACS码值
char ch = '3';printf("%c",ch) // 输出的是字符 '3'
strlen(测字符串长度) strcpy(字符串复制) strcmp(字符串比较) strcat(字符串连接)。
feof()函数: 如果文件结束,则返回非0值,否则返回0。

8.逗号运算符

逗号表达式的结果是其最右边表达式的值,其运算规则为:从左至右依次计算表达式值,最终只取最后一个表达式的值为返回值 (3+5,6+8)的值为14 (a=3*5,a*4)的值为60 。

9.指针指向字符
char* s1 = "Hello world";s1[2] = 'E';     // 错*(s1 + 2) = 'E';  //错
指针指向字符串时,字符串是常量,存储在常量区,而指针存储在栈区。常量是不能修改的。

参考:
来自牛客网的学习笔记。
原创粉丝点击