CS基础复习

来源:互联网 发布:知乎年度吐槽精选(十) 编辑:程序博客网 时间:2024/06/10 01:15

最近重新复习,把看到的point都在这里写写。

 反汇编: 最方便的方法是DEBUG的时候用快捷键CTRL+F11查看汇编代码。

 http://topic.csdn.net/u/20101103/18/458701ee-5761-48e7-8539-cea0b263cf39.html

 

类型转换:

http://linux-c-programming.jubaoren.com/ch15s03.html

long 与 int的区别: 64位机上两者没有区别,都是两个字长,printf输出时long型用ld; 32位机上long为两个字长,int为一个字长; int f = -4; f = unsigned(f) >> 1; unsigned 右移时高位填充0,signed右移时填充1;

 

螺旋队列: http://blog.csdn.net/yhmhappy2006/archive/2008/09/16/2934435.aspx

 

typedef用法小结:

下面的代码中编译器会报一个错误,你知道是哪个语句错了吗?

 typedef char * pStr;

 char string[4] = "abc";

 const char *p1 = string;

 const pStr p2 = string;

 p1++; p2++;

 是 p2++出错了。这个问题再一次提醒我们:typedef和#define不同,它不是简单的文本替换。上述代码中const pStr p2并不等于const char * p2。const pStr p2和const long x本质上没有区别,都是对变量进行只读限制,只不过此处变量p2的数据类型是我们自己定义的而不是系统固有类型而已。因此,const pStr p2的含义是:限定数据类型为char *的变量p2为只读,因此p2++错误。 http://hi.baidu.com/linuxwingis/blog/item/5cf89dfae9cc1216a9d3117a.html

http://hi.baidu.com/laven1314/blog/item/001ba9948486c409d21b70e4.html

 

 extern "C" http://www.cppblog.com/Macaulish/archive/2008/06/17/53689.html

 

static, const, define,inline, virtual function 辨析

#define inline 内联函数和宏的区别在于,宏是由预处理器对宏进行替代,而内联函数是 通过编译器控制来实现的。而且内联函数是真正的函数,要做参数类型检查,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。 内联函数和普通函数相比可以加快程序的运行速度,但它是以增加程序存储空间维代价的,由于不需要中断调用,在编译内联函数的时候内联函数可以直接被嵌入目标代码中。

#define const const来源,是C++中设计代替宏的 C中,const总是占用内存,且它的名字是全局符,C编译器不能把const看成一个编译期间的常量。在C中,const是外部链接的,C++则是内部链接

http://www.kuqin.com/effectivec2e/ch00b.htm

http://blog.sina.com.cn/s/blog_4af62c070100dpo5.html

 

 内存管理

Static静态变量存储在全局数据区;

sizeof只能计算栈中分配的大小; 怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则 1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。 2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.) 3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐. http://blog.csdn.net/hairetz/archive/2009/04/16/4084088.aspx

字节对齐有助于加快计算机的取数速度,否则就得多花指令周期。 sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小数据的数据类型,如未知存储大小的数组类型,未知内容的结构或联合类型,void类型 sizeof在C++中的小结 如果有一个或多个虚函数,编译器在这个结构中插入一个指针( V P T R)。 而在虚继承时,会多一个虚表指针; http://blog.csdn.net/zhouxqwh/archive/2008/09/01/2859339.aspx

http://hi.baidu.com/hehui1500/blog/item/65b04af5b9df32e37609d7f7.html

 

 #include <cstdio> VS #include <stdio.h>

在新的C++标准中,生成新头文件的方法仅仅是将现有C++头文件名中的.h去掉。例如,变成了< iostream>,变成了,等等。对于C头文件,采用同样的方法,但在每个名字前还要添加一个c。所以C的变成了,变成了< cstdio>,等等。 标准C头文件如继续被支持。头文件的内容不在std中。 具有C库功能的新C++头文件具有如这样的名字。它们提供的内容和相应的旧C头文件相同,只是内容在std中。

http://topic.csdn.net/u/20081112/13/bb735fd5-71a4-4b5d-8412-54021533ecda.html

 

空指针 VS 迷途指针

当delete一个指针是,编译器释放内存,但是指针本身仍然存心在,为迷途指针;

将迷途指针赋值为零,则为空指针;

两者的使用都是非法的,要将迷途指针转换为空指针;

 

malloc /free VS new/ delete

malloc /free为C++/C标准库函数,new/delete是C++的运算符;因此对于非内部数据类型的对象,malloc/free 不在编译器控制权限之内,不能够执行构造函数和析构函数,无法满足动态对象的要求。

new能完成动态内存分配和初始化工作,delete 能清理和释放内存。

 

常成员函数

<类型说明符>   <函数名>   (<参数表>)   const;   
其中,const是加在函数说明后面的类型修饰符,它是函数类型的一个组成部分,因此,在函数实现部分也要带const关键字。

用const结尾的成员函数只能调用其他const结尾的成员函数。因为其他函数并不能保证同样不修改类的成员变量
const成员函数表示,这个函数不会修改类成员,除非成员加了修改mutable或者你在函数中主动使用了const_cast

 

 

 

为什么static成员一定要在类外初始化?

避免重复定义,可以写作“static   const   int   n   =   9; ”
因为被static声明的类静态数据成员,其实体远在main()函数开始之前就已经在全局数据段中诞生了(见《Inside   The   C++   Object   Model》page247)!其生命期和类对象是异步的,(而且静态语意说明即使没有类实体的存在,其静态数据成员的实体也是存的)

http://topic.csdn.net/u/20070807/15/db67e83c-a3d8-4b84-80e4-af657a730d79.html

 

类中的常量成员变量必须在构造函数中定义或加static,在类外初始化;

 

静态成员函数

静态成员函数的作用基本上相当于一个带有命名空间的全局函数。

1、你不需要生成一个对象的实例就可以直接使用该函数。如,Cxxx::MyStaticFunc();
2、窗口回调函数需使用静态成员函数或全局函数。
3、线程调用需使用静态成员函数或全局函数。

在不生成对象的情况下,提供某项功能。比如,访问静态数据成员。可以用于SingleTon模式,和多线程中的线程函数。

 

函数指针(可用静态模板类替代)

异步操作的回调和其他需要匿名回调的结构。另外线程的执行和事件的处理,需要函数指针的支持。

 

链表实现

http://www.cublog.cn/u/22617/showart.php?id=1353877

 

 

 

virtual 虚函数

虚函数保证多态下,析构不会造成内存泄露。

它采用了虚调用,即允许在只有部分信息的情况下工作的机制,特别是支持调用一个只知道接口而不知道其准确对象类型的函数。

每个虚函数的对象都必须维护一个虚函数表。

 

深拷贝和浅拷贝

引用对象的浅拷贝原理

引用对象之间的赋值之所以执行的是浅拷贝动作,与引用对象的特性有关,一个引用对象一般来说由两个部分组成

1)一个具名的Handle,也就是我们所说的声明(如变量)

2)一个内部(不具名)的对象,也就是具名Handle的内部对象。它在Manged Heap(托管堆)中分配,一般由新增s引用对象的New方法是进行创建

       如果这个内部对象已被创建,那么具名的Handle就指向这个内部对象在Manged Heap中的地址,否则就是null(从某个方面来讲,如果这个具名的handle可以被赋值为null,说明这是一个引用对象,当然不是绝对)。两个引用对象如果进行赋值,它们仅仅是复制这个内部对象的地址,内部对象仍然是同一个,因此,源对象或拷贝对象的修改都会影响对方。这也就是浅拷贝

 

一些需要注意的东西

       1):String字符串对象是引用对象,但是很特殊,它表现的如值对象一样,即对它进行赋值,分割,合并,并不是对原有的字符串进行操作,而是返回一个新的字符串对象

       2):Array数组对象是引用对象,在进行赋值的时候,实际上返回的是源对象的另一份引用而已;因此如果要对数组对象进行真正的复制(深拷贝),那么需要新建一份数组对象,然后将源数组的值逐一拷贝到目的对象中

 

 

 float double类型数据的存储

http://hi.baidu.com/andrew_tfy/blog/item/239a4e496d2815fc83025c40.html

 

const_cast dynamic_cast reinterpret_cast static_cast用法

http://blog.csdn.net/public/archive/2009/12/05/4944505.aspx

纯基类、ADT和纯虚函数

http://www.miti2000.com/post/161.html

拷贝构造函数

http://cpp-circle.group.iteye.com/group/wiki/811-C++%E6%8B%B7%E8%B4%9D%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E7%9A%84%E5%87%A0%E4%B8%AA%E7%BB%86%E8%8A%82

内存分配

C++中内存的分配:
    1.栈:是用来存放像一般变量和函数参数等的一块内存。系统会在变量生存期结束时自动释放内存,即把内存从栈中弹出。
    2.堆:用来存放动态变量,如指针。要通过设计者自己管理变量,自行进行创建和清理工作。(利用new和delete) 。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
    3.自由存储区:就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
    4.全局/静态存储区:全局变量和静态变量被分配到同一块内存。
    5.常量存储区:用来存储常量,即不能被修改的变量。

http://www.ibiancheng.cn/Article/CArticle/200712/93.html