1、数组初始化问题;
int b[6]={0};//则编译器会把第一个初始化值赋给数组的第一个元素,然后用0赋给其余的元素;如果只定义,不给一列赋值,编译器不会做初始化工作。
char b[6]={'a','b','c'};//后面的会自动初始化为0;
char b[6]={'a'};//除了第一个,其它都初始化为0;
2、const常量问题集合
1)类似于#define功能
a)const常量默认为内部连接。此时并不为const创建存储空间,只是把定义保存在符号表里面;使用const常量时,编译时会进行常量折叠。
b)如果是声明为extern外部连接,或者对const常量取地址的话,则编译器会为const创建存储空间。
c)const int i=100;
const int j=i+10;
long address = (long)&j;//强制分配存储空间。
char buf[j+10];//被分配存储空间后,还是一个const常量。
2)表示const变量在变量生命周期内是不变的。
3)当声明const集合时,并不是放在符号表(因为太大),得创建存储空间存储集合常量。不能在编译期间使用它的值。
4)const指针的指向问题。定义指针的技巧是在标识符的开始出读它并从里向外读,const修饰“最靠近”它的那个。
a)指向const的指针:
const int* u;//u是一个指针,它指向一个const int。
int const*v ;//v是恰好是const的int的普通指针。跟上面的指针是一样的。
b)const指针
int* const w=&d;//w是一个指针,这个指针是指向int的const指针。因为指针是const的,必须先赋初始值。可以改变它对应的值,但是不能改变指针的值。
const int* const x2=&d;//指针和对象都不能改变。
5)可以把一个非const对象的地址赋给一个const指针。不能把一个const对象的地址赋给一个非const的指针。
6)字符数组的的字面值。
char *p = “hello”;//“hello”是常量字符组。所以p不能更改它的字符。要更改的话,只能定义为:char p[]="hell0";
7)临时变量的问题
X f5(){return X();}
void f7(X& x){x.modify();}
如果这样调用:f7(f5());//warnning,编译错误。因为调用f5()产生一个X,系统会用一个临时变量保存它,但是它是const类型的。所以修改X的话,会导致错误。
8)函数(非成员函数)的const声明。
const int *const w(){static int i; return &i;}
main中可以这样调用 const int *const ccip=w();
也可以这样调用: const int *cip2 = w(); 这是因为原始变量不能被更改。只有当把const int *const 中的第二个const当作一个左值使用时(编译器会阻止这种情况),它才能显示其意义所在。
9)类里的const变量必须在构造函数初始化列表中初始化。
编译期间类里的常量:1)使用 class constattr {static const int size = 100;};来获取。
2)类中使用enum:class Bunch{enum {size=100}; int i[size];};enum保证不占用对象的存储空间。
类中声明为const的变量,表示不能改变的。声明为const的成员成员函数表示它可以被const对象所调用,而且不能更改对象中数据成员。const成员函数在声明和定义都必须使用const关键字,这样才能保证它是const类型的成员函数。
class x {int i;int f()const;}; int x::f() const {return i;}//声明和定义中都出现const。这是const成员函数的例子;
class y {const char * q();};const char*q(){return “dddd”;}//返回const变量的成员函数例子。
非const成员函数不能被const对象调用。但是非const对象可以调用const成员函数。
成员函数中还是可以更改成员变量的。这涉及到按位const和按逻辑const。对于按逻辑const,可以修改成员变量。方法有两种:
a)强制转化常量性。class Y{int i; public: void f() const;}; void Y::f(){ ((Y*) this)->i++; (const_cast<Y*>(this))->i++;}//两种转化都可以改变变量。
b)成员变量声明为mutable。class Z{mutable int j; public: void f() const;}; void Z::f() const { j++;}//直接修改mutable的成员变量。
对于const Y yy; yy.f();//可以改变对象的值。
注意:在C语言中,const只是一个不能被改变的普通变量,总是占用存储,而且名字是全局的。所以也不能有这样的声明:const int SIZE = 10;int arr[SIZE];而且C默认const为外部连接的。
3、函数默认参数
默认参数只能放在声明。而且声明可以是不带标志符的。例如:
void f(int x, int = 0, float = 1.1);
4、C/C++中函数参数是按照从右到左压栈的。所以也是从右到左计算的。