学习脚印

也许我走得很慢,但是我一直在往前。

C++:学习过程中,易错知识点

1. 在全局域定义enum,输出x是0,但是在局部域定义enum,输出x是随机数。

2. 32位机器上,任何指针变量都只占4个字节。 64位机器则是8个字节。每个字节占8位。

3. 全局变量作用域大于静态局部变量(只用于声明它的函数中)。析构函数的调用与构造函数的调用顺序刚好相反。

4.在类中,如果什么都没有,则类占用1个字节,一旦类中有其他的占用空间成员,则这1个字节就不在计算之内,如一个类只有一个int则占用4字节而不是5字节。如果只有成员函数,则还是只占用1个字节,因为类函数不占用空间。如果有虚函数,需要建立一个虚函数表,需要4个字节;数据成员对象如果为指针则为4字节,注意有字节对齐,如果为13字节,则进位到16字节空间。

5.字符串算空间时包含'\0', 但是计算长度时不包含'\0'  (strlen时不算,sizeof算)。

6.口诀:左定值,右定向。即 const在*的左边不能改变字符串常量的值;const在*的右边不能改变指针的指向;字符串是存储在字符常量区,不能直接修改其值。

7. 基类析构函数未加virtual,因此不会调用子类析构。

8. 首先对编译器来说没有数组这一概念,数组都被看成指针,所以a[ ]就是*a,那么就是**a换成了**pa,pa即是a,换个名字而已,根据数组的++,也就是取a[1][ ]的值,即“at”。

9. void p2 = malloc(10)通不过编译,若是 void * p2 = malloc(10) 则选c ;void*是空指针,可以指向任意类型,不能操作void*所指对象。

10.   负数以补码形式存储 补码 = 源码求反,之后加1。求反是指符号位不变,其余全部变。

11. 引用是直接访问,指针是间接访问;引用是变量的别名,本身不单独分配自己的内存空间,指针有自己的内存空间;引用一旦初始化,不能再引用其他变量。而指针可以!

12. 引用是除指针外另一个可以产生多态效果的手段。这意味着,一个基类的引用可以指向它的派生类实例。Class A; Class B : Class A{...}; B b;A& ref = b。 只不过引用了一下,就产生了多态。但是这有个很不寻常的举动,拷贝构造和引用拷贝完全是两码事,要分清楚。

13. 对于函数指针而言,函数名即函数的起始地址,直接赋值即可。pf=&fun和pf=fun都是正确的。

14. 二进制整数不能寻址,所以C语言不支持二进制表示整数。

15. 基类指针,指向派生类对象,析构函数定义为虚函数时,析构的时候:先调用派生类的析构函数、然后调用基类的析构函数;与构造函数相反。

16. 对于B选项,编译器首先检查关系表达式"==" 左右两边a ,c的类型,如果某个类型是比int的位宽小的类型,就会先进行Integer Promotion,将其提升为int类型,至于提升的方法,是先根据原始类型进行位扩展(如果原始类型为unsigned ,进行零扩展,如果原始类型为signed,进行符号位扩展)至32位,再根据需要进行unsigned to int 形式的转换。

17. "S\065AB"字符串中包含S,\065(八进制数),A,B以及结束符\0,所以用sizeof计算的话,结果为5。

18. 指针相减的值是指针地址的偏移除以指针每次移位的大小;指针会随着数据类型的不同而产生的偏移量不同。

19. 不能使用strcat()函数连接两个指向字符串的指针。p1和p2指向的是常量存储区的字符串常量,没法连接,会有问题。

20. delete[] pa指释放pa指向的全部元素;delete pa指释放pa的首元素。

21. char c = 128;printf("c=%d\n", c);因为char范围-128~+127,所以128保存在c里int值为-128, %d按int输出,为-128。双端取值范围是-N---N-1,这个要注意一下。

22. sizeof是C语言中的一个操作符(operator),不是函数调用,简单的说其作用就是返回一个对象或者类型所占的内存字节数由于结果是无符号整数,因此可以把它看作是无符号整型表达式。

23. 通常静态数据成员在类声明中声明,在包含类方法的文件中初始化. 初始化时使用作用域操作符来指出静态成员所属的类。但如果静态成员是整型或是枚举型const,则可以在类声明中初始化!如果改成有的静态数据成员是可以直接在类中初始化就对了。 

24. 分配内存:

25. 并不是每个可重载的运算符,都既可以重载为友元函数,又可以重载为成员函数,还可以重载为非成员函数。某些运算符必须重载位成员函数,比如  operator new;某些运算符必须重载为非成员函数,比如  operator >>。

26. 在64位机器上,指针占8字节;在32位机器上,指针占4字节。结构体具有字节对齐原则。结构体的总大小为结构体最宽基本类型成员大小的整数倍。如在8字节对齐的情况下,按8个字节为单位分配存储空间,如果不足,会自动补充,本次分配不足以存放下面的变量时,会重新分配空间。示例:struct A{unsigned int a;char b[2];double c;short d;},占用3*8=24个字节。

27. 64位操作系统,不同类型变量对应的字节数为(红色的表示与32位系统不同之处):char:1个字节;char*(即指针变量):8个字节;short int : 2个字节;int:4个字节;unsigned int : 4个字节;float:  4个字节;double:    8个字节;long: 8个字节;long long:  8个字符;unsignedlong:  8个字节 

28. 由于类的构造次序是由基类到派生类,所以在构造函数中调用虚函数,这个虚函数不会呈现出多态; 相反,类的析构是从派生类到基类,当调用继承层次中某一层次的类的析构函数时往往意味着其派生类部分已经析构掉,所以也不会呈现出多态;静态函数不可以是虚函数;虚函数可以声明为inline。

29. C语言是一个函数语言,C语言的主体就是一个主函数,然后有库函数和用户自定义的函数来配合主函数完成一系列的任务,所以说,C语言的基本单位是函数

30. 双端取值范围是-N---N-1,这个要注意一下。如:0 00000到0 11111是0到31,而从1 00001 到1 11111为负1到负31,中间有一个1 00000本意表示负零,,但是负零和正零都表示零,重复了。所以计算机规定把1 00000表示-32;所以范围为-32~31。

31.定义数组时可以对第一维的长度不指定,但第二维的长度不能省去。

32.C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于类对象数组,只能用 delete[]。所以一个简单的使用原则就是:new 和 delete、new[] 和 delete[] 对应使用。

33.静态成员函数属于整个类所拥有,没有this指针;友员函数不是这个类的成员,没有this指针;类的非静态成员函数,有this指针。友元函数里不含有this指针,所以调用时,需要加对象名。

34.c++中,声明const int i,是在编译阶段做到 i只可读的。源代码到可执行文件的过程:源代码-->预处理-->编译-->优化-->汇编-->链接-->可执行文件。因为const说明变量是常量,常量存储在常量区,在编译时就直接将其替换成相应的引用。

35.sizeof返回数组所占的字节数;strlen返回字符串的长度,以遇到'\0'结束符为准,中间有'\0'也结束。

36.若有定义语句: char a ='\82'; 则变量a,包含1个字符。解析:有一个‘\’,那么首先想到的是转义字符常量,‘\ddd’  是用八进制数的ASCII码表示一个字符,但是本题中'\82',有一个8,显然已经不是八进制,那么这个时候实际上就'\82'中包含3个字符,分别是‘\’,'8','2',赋值时是将字符'2'给了a,实际上这个题和 char a = 'fdz'变量a的值是‘z’是一个道理,只是\具有迷惑作用而已,可以试验把‘\82’换成‘\zz’,则a的值为z,因此这道题选择包含一个字符。

37.在类定义时,无法使用构造函数,因而无法完成对象的初始化。

38.以下字符中不是转义字符的是'\c'。

39.常函数只能被常量对象调用,如果想改变类成员,可加mutable关键字。

40.   源码 ->(扫描)-> 标记 ->(语法分析)-> 语法树 ->(语义分析)-> 标识语义后的语法树 ->(源码优化)-> 中间代码 ->(代码生成)-> 目标机器代码 ->(目标代码优化)-> 最终目标代码。

41.   源代码-->预处理-->编译-->优化-->汇编-->链接-->可执行文件。汇编阶段把汇编语言代码/中间代码翻译成目标机器指令。对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。(代码生成阶段)

42.   char(& p)[10] ;sizeof(p): p相当于char[10]的引用,故1*10 = 10;sizeof(char&):对引用类型执行sizeof运算得到被引用对象所占空间的大小。

43.   组合是在新类中以原有类的对象作为数据成员,继承是在不改变现有的类的基础上,采用现有类的形式并在其中添加新代码,组合一般用于在新类中使用现有类的功能而不是他的接口的情况,就是新类用户看到的只是为新类所定义的接口。而继承则是用于在新类需要向基类转化的情况(多态),这也是组合和继承使用的最清晰的判断方法。优先使用对象组合,而不是继承”是面向对象设计的第二原则。组合也叫“对象持有”,就是在类中定义另一类型的成员,继承会破坏类的独立性,增加系统的复杂性,一般系统的继承层次不超过3层。组合拥有良好的扩展性,支持动态组合,因此请优先考虑组合方法。

44.   若只在主函数中对函数f进行说明,则只能在主函数中正确调用函数f----错误,因为在f函数定义的后面,其它的函数也是可以调用f函数的。另外,在C语言中变量或函数可以重复声明,但是不能重复定义。

45.   cin>>该操作符是根据后面变量的类型读取数据。输入结束条件 :遇到Enter、Space、Tab键。对结束符的处理 :丢弃缓冲区中使得输入结束的结束符(Enter、Space、Tab)。

46.    类继承的访问情况

47.   vector是STL中最常见的容器,它是一种顺序容器,支持随机访问。vector是一块连续分配的内存,从数据安排的角度来讲,和数组极其相似,不同的地方就是:数组是静态分配空间,一旦分配了空间的大小,就不可再改变了;而vector是动态分配空间,随着元素的不断插入,它会按照自身的一套机制不断扩充自身的容量。vector的扩充机制:按照容器现在容量的一倍进行增长。vector容器分配的是一块连续的内存空间,每次容器的增长,并不是在原有连续的内存空间后再进行简单的叠加,而是重新申请一块更大的新内存,并把现有容器中的元素逐个复制过去,然后销毁旧的内存。这时原有指向旧内存空间的迭代器已经失效,所以当操作容器时,迭代器要及时更新。

48.   栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将 提示overflow。因此,能从栈获得的空间较小。   

49.    堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小  受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。


持续更新中...

阅读更多
上一篇SQL:常见空间与属性数据库的操作
下一篇OpenSceneGraph:学习笔记
想对作者说点什么? 我来说一句

自己总结的c&c++语法知识点

2016年03月23日 38KB 下载

没有更多推荐了,返回首页

关闭
关闭