l 为了使程序能在数据段运行,还必须为程序提供所需要的空间。在数据段声明的变 量和对象,我们称为全局变量。它的初始值为0或我们自己定义的任何值。
l 首行缩进时最好使用制表符而不使用空格,制表符占用一个字节,四个空格占用四个字节,可以提高文件存储速度;编译器编译时也会快3倍的
l 变量V对象:变量是一种基本的类型,它只包含信息的值或者状态,不包含值的分配,而在VC中定义的对象则包含如何赋值和改变值
l Function((12,14)) 和Function(12,14)是有区别的,后者是有两个参数的函数,前者可以当作一个参数14,当作一个参数。函数有一个参数时 编译器就不会报错。
l 同一个变量在子模块中可以再次被定义。C++里是合法的。内部用内部定义,外部是外部。
l 程序流在行与行之间是顺序执行的,但在行内就不一定了。
l 程序员可以使用关键字typedef,可以从基本类和构造类中定义新的数据类型。
l 与处理器通过完成宏转换,读入头文件和计算编译语句的条件,为编译准备源文件。
l 预处理伪指令的后面,不能有表示结束的分号
l #define 用于定义 #define identifier token—sequence
l #define 用于宏定义
l #line 设置正在处理的内部行的编号。出于诊断的目的,预处理器会包含一个行计数器,以及当前文件的名字。#line constant 或者#line constant “file-name”
l #error 编译器输出诊断信息。VC++该伪指令导致编译的结束
l #pragm 引导处理器完成实现所规定的动作
l #——空指令 无意义
l _LINE_(源代码行号,十进制) _FILE_(文件名字字符串) _DATA_(日期 MM DD YYYY) _TIME_(时间 HH:MM:SS) _STDC_(设置1时,表示标准C的代码正在被编译,必须按照标C规则实现) _cplusplus_(设置1时,C++,和_SDC_不能同时使用)-------这几个指令不能被处理器重新定义,因为是处理器使用的
l 预处理器使用的特殊运算符:
/ 连接下行
#(replacement) 如果遇到的是#,就引用相应的参数,并把它插入到#的位置 如#define PRINT(val)print(#val “=%d”,val)接着下面写int x=2,y=4;PRINT(x+y);x+y的值还没有计算出来就被#val替换,并用双引号括起来,宏的扩展是: printf(“x+y” “=”, 6);如果两个字符串之间没有操作符,编译器就把他们当作一个字符串对待.即printf(“x+y=”, 6);
## (Concatenation)在宏定义中该运算符和所有的空格都将从指令中删除,用来连接两个标志符以产生新的标志符.
l 结构只能有自己的指针类型.
l C/C++的结构和联合的区别: C++中结构可以包含构造函数和析构函数, C中结构不能包含函数,尽管它可以包含一个外部函数的指针;
l 在C++中一旦我们定义了一个结构或联合,就可以通过使用定义中的名字简单地生明了它的变量了. 而在C中, 就必须使用struct 或 union 关键字,除非为结构或联合特别typedef 了一个标志符. 在C中,编译器使用的命名空间来存放结构的类称名;而在C++中, 标志符是同程序代码一起包含在相同的命名空间中.
l 定义一个对象或数据类型不用保留存储空间,这一部分的操作留待操作来完成.声明就是要特别告诉编译器要创建一个特定数据类型的对象,编译器就会增加代码来为该对象保留空间.. 在哪里声明就决定了在哪里分配存储空间
l 函数参数的变量类型匹配,就会在堆栈中留出空间,并复制变量的内容到该空间. 参数是个表达式时,就计算表达式的值,并把表达式的值结果保存存储空间,传递给函数的参数的变量通常都是自动变量,而且不能是寄存器变量的子类. 当一个参数使用或修改一个参数变量, 他使用的实际是原变量的副本,任何修改不会影响到原变量.
l #define CIRCUM(float Diameter) (2.0*PI*Diameter)下面CIRCUM(8.0)就可以使用
l 寄存器变量是自动变量的一个子类,虽然存储速度快了,但是我们不能得到一个寄存器变量的地址(C中不可,C++可以). 只有函数参数和本地变量可以在寄存器存储类中被声明.
l C和C++的连续数据存储是在静态存储类中实现的,数据类型前加static,初始值是0函数参数不能静态声明,但是在函数调用时可以使用静态变量. 把它转化为auto类型,存储类型自动转化, 参数的改变不会影响到静态变量的值.
l 引用的地址和变量的地址是一样的,C++不允许获得一个引用的地址
l 数组的存储区域不能被任何数据分割.除了void类型可以把数组声明为任何一种类型的.也可以声明为函数指针或者是引用.
l #include 头文件,<>中,选择/I编译器的运行选项中规定的路径进行查找,然后再在由INCLUDE环境变量中定义的路径进行查找;; ” ”中,现在包含#include中进行查找,然后是/I, 最后是INCLUDE; 也可以包含完整绝对路径
l TCHAR可以代替char, LPTSTR可以代替char*, 而LPCTSTR可以代替const char* 使用_T或者_TEXT宏我们可以定义并声明字符串
l /n 它的解释依赖于操作系统, 而且它可以是回车或换页,也可以两者兼俱, VC++把它解释为回车和换行的结合.
l /后三位是八进制,不够的话要补0,后跟小写x和两位十六进制的可以用来输入十六进制的字符值.
l fprintf()的第一个参数是文件,sprintf()的第一个参数是字符串,其他的和printf()一样的。
l NULL在一些操作系统上不一定是0,也许指向内存中某个安全的地方,对他的偶然读或写不会影响到系统。
l 地址操作符只适用于内存中的对象。不可能得到一个表达式或者一个常量的地址。
l 异或:所有位都为1 的与一个数异或,结果是初始值的补码(补码 运算符)。都是0参与异或,结果仍是这个数
l int x=y=z=0; x +=y +=z +=1; 结果是x=1,y=1,z=1也是可以的。
l for 循环中,第二个变量,若要判断两个条件的值,则如(y>0)||(x<10),否则只计算右边一个值,逗号运算符。
l 定义函数 void Func(int x=0,int y=0);使用int x=1,y=2; 调用Func((x,y)),效果是调用Func(2, 0); 双括号导致的,第二个参数使用默认值0
l 若作为类的成员,引用变量不需要在声明时被初始化,但是它必须在所有的构造函数中被初始化。
l Switch语句必须是整型,否则只能用if-elseif-else
l 在C++中可以在case中声明变量,而在C中是不行的。但是在声明语句当中不能对其初始化,可以分开两行书写。当然加个{}块域是可以的。
l 结构可以用一个结构赋给另一个对象,但C中需要memcpy(),
l C把结构类型、联合类型和枚举类型的名字放在一个独立的命名空间,而C++把他们看作用户定义的类型,放在相同的名字空间中。因此一个类或者结构已经被定义,它的名字就成为一个用户定义的数据类型,可以和其他数据一样使用。
l C++结构可以包括函数,但是C不能,只可以包含函数的指针。C++结构可以从其他类派生而来。Struct Struct2: Struct1{ int z; } ;可以使用Struct1的成员。
l 在C++中,编译器会检验获得函数返回值的变量与函数的数据类型是否一致,并检验参数的数量、顺序和类型是否与函数原形相匹配。在C中不作这些比较,C中所有函数的返回默认值都是整数。返回值不是整数时才需要对类型声明。
l 在全局范围内声明一个数组,它将被创建在程序的数据段,在函数内部声明一个数组,它创建在堆栈段。VC++默认的堆栈长度是1MB(C语言用堆栈存储其它的变量以及返回地址)。使用/F指令,或者/STACK链接指令,可以增加堆栈空间。另一种选择把数组创建在堆中,或者使用Windows全局分配函数
l Sizeof()把终结符也计算在内,而strlen()不包括终结符。
l 对数组元素使用指针时,编译和运行时都不对指针进行越界检查,可能是第一个元素之前或最后一个元素之后。在C和C++中,LongArray[-8] 都是合法操作。当试图访问数组以外的元素时,编译和运行时都不报错。
l int IntArray[] = {4,8,22,12};double DoubleArray[] = {2.5, 6.8, 12.4}; void *Void[] = {IntArray, DoubleArray};访问方式:
l #define 当且仅当两个变量被重复定义时,才可以接受。定义完全相同。
l 可以用命令行处理预处理指令。可以用—D编译指令来定义它。如:C:>cl –DTABSTOPs=4 myprog.cpp <enter> 和C:>cl –D ”TABSTOPs= 4” myprog.cpp <enter> 等价
l 空#define常量用于头文件的标志符,用于防止一些代码无意间被重复包括。
l 标志符可以在任何地方取消定义,即使以前未被定义过的标志符也可以取消定义。
l Sizeof()操作数可以是个表达式,只考虑表达式的值,而不计算表达式,如sizeof(++x) x 不被计算。
l 当使用#define命令时,并不分配存储空间。使用时才分配。每使用一次就分配一次。而const只需要分配一次空间。只需从内存中取回它的值,不需要分配它的空间。
l 为了赋值的需要,必须把const char*类型转化为char*类型,才可以赋值。
l 可以在头文件中使用#define常量,而避免使用const常量。每个包含头文件的源文件都会对常量声明一个自己的实例。如果使用const常量,就会引起标志符多重定义。。。可以把它声明static const常量,可以把常量的各个实例放在不同的存储空间中,若是这样,就体现不出const节省空间的好处了。或者在源文件中声明并初始化一个常量,在其他用到这个常量的源文件中,将它声明为static。
l #define除非取消定义和重新定义,它的值才可以改变。而const是相对的。可以把它的地址赋给一个非常量的变量,然后间接的改变它。比如const char * TEST=“baby”;char* str1 = (char*)TEST; char* str2 = (char *)TEST; 然后char * s=strstr(str1, “two”);你会发现str1 和str2的值都改变了,而用#define不会改变的,只改变一个。
l volatile 是const的反义词,其值可能在任何时候改变,甚至可能会在外界的影响下改变。一个变量使用了volatile,即使程序的下一条语句会再次修改它,它也会理解被写到内存中
l 文件名包含在双引号中,在文件下同一文件夹下查找,然后在 / I编译指令指定的文件目录下查找,最后从包含路径下查找。
l 卫式语句:名为 sentry 和 guardian 预处理指令用于头文件中,防止编译器器多次编译同一个文件,就是#ifdef #endif 的语句功能。GUID 当前时间和LAN网卡网络地址,如果没有网卡UUID(一般唯一标志符)机器上上是唯一的。
l #if 预处理器计算表达式的值,表达式必须是完整的,只能包含整形变量、字符常量和defined操作符,不能包括任何类型转换,不能包括sizeof操作符,也不得包括任何枚举类型,不能有任何C 或者C++代码中的值。表达式的结果将被看作无符号loog型。
l #ifdef 和#ifndef 将被 defined代替。#ifdef = #if defined #ifndef = #if !defined
l Char* strArray[] = {{first string/n},{second string/n},{the third string is a long one/n}};这时存储空间就降到73字节。61存储字节本身。12个字节是指针。比char chArray[][32]节省了很多空间。