1,全局变量与局部变量在内存中的区别
对于二者而言,主要区别有以下两点:
1. 生存周期不同
2. 作用范围不同
对于生存周期:
- 全局变量和静态变量是存储在一起的,初始化过的全局变量和静态变量在同一块区域,未初始化的全局变量和静态变量存放在一块相邻的区域内。此区域由系统在程序结束后释放。
- 局部变量放在堆栈中,由编译器自动分配释放,存放函数的参数值,局部变量的值等。
对于作用范围:
- 全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用
extern
关键字再次声明这个全局变量。 - 局部变量也只有局部作用域,它是自动对象(
auto
),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。
2,函数缺省参数问题
对于函数的缺省参数:
- 只能从右往左进行缺省。
例如,对于函数原型:
void test(int a,int b=7,char* p=”*”)
- 调用方法1:
test(6, '$');
这种情况时可行的,此时编译器认为缺省的是第三个参数,第二个参数就相当于传入的&的ASCII码值。
- 调用方法2:
test(5, "8");
此时这种情况就是错误的了,因为第二个参数传入的是一个字符串,而将字符串赋值给int型是不合法的。
3,格式化输出与对齐问题
以四个例子说明:
-
%-8d
表示输出占8个空格的位置,左对齐,右边多余位置补上空格。 -
%-08d
等价于**%-8d**,因为不可能在右边的空位补0。 -
%08d
表示输出占8个空格的位置,右对齐,左边多余位置补上0。 -
%+8d
表示输出占8个空格的位置,右对齐,左边多余位置补空格,必须输出正负号。
4,移位操作的优先级
就优先级而言:
- 运算符+ 的优先级高于左移<<,即普通计算的运算符优先级要高于移位运算符。
对于题目:
- 1<<3+2
从上面的优先级我们可以得到,先计算3+2,再进行左移运算,因此,最后的结果应该是:
- 32
5,空类的大小
在C++中,对于空类或者空结构体,如果对其sizeof操作,默认都是一个字节。
6,存储标识符的可见性与存在性
所谓可见性:
- 在什么地方可以调用,能调用的地方就是可见的。
所谓存在性:
- 即在什么地方、什么时候初始化,然后使用完之后在什么地方、什么时候释放,存在性一般是在运行时的生命周期内起作用的。
一、变量的作用域与存储类型
按作用域划分:内部变量、外部变量
- 内部变量:在函数内定义称之为内部变量(局部)
- 外部变量:在函数外定义称之为外部变量(全局)
二者的区别:定义出现的位置。
按存储类型划分:auto、static/register(动态、静态/寄存器变量)
-
auto:动态
位置:动态区
特点:程序运行时动态分配,每次调用时都重新赋初值,调用不赋初值时,其值不确定。 -
static:静态
位置:静态区
特点:程序编译时静态分配,每次调用时不再重新赋初值,保留最后一次调用的值。
二者的区别:存储位置不同。
- register:寄存器
位置:在CPU内
特点:速度快
变量的“存在性”与“可见性”
对于题目:
内部静态类在函数内可见,但是函数结束并没有释放。
而对于外部类、自动类和寄存器类而言,函数结束时,它们也都自动释放了。
因此,静态存储类的可见性和存在性不一致。
7,局部变量与全局变量相关
1,如在定义局部变量时不赋值的话:
- 对于静态变量而言,编译时自动赋值初值0或空字符。
- 对于自动变量而言,如果不赋值,它的值是一个不确定的值。
2,在函数调用完后,静态局部变量的值不会消失。
3,全局变量若不初始化,则系统默认它的值为0。
8,类的大小
类的大小只与成员变量(非static数据成员变量)和虚函数指针有关,还要考虑到对齐。
对于题目:
定义类A
class A
{
public:
int fun1();
virtual void fun2();
private:
int _a;
};
在32位的机器上,sizeof(A)
的值:
4个字节(int _a)+ 4个字节(指向虚函数的指针)= 8字节
因此,sizeof(A) = 8
9,运算符的重载
在C++中,不可重载的运算符:
- 类属关系运算符
.
- 成员指针运算符
*
- 作用域运算符
::
sizeof
运算符- 三目运算符
?
除此之外的运算符都可以被重载。
需要注意的是,sizeof既是关键字,又是运算符(操作符),但不是函数。
10,x&(x-1)与x|(x-1)
- x&(x-1): 统计x的二进制中1的个数
- x|(x-1): 统计x的二级制中的0的个数