1.指针和引用的区别
指针存放某个对象的地址,其本身就是变量(命了名的对象),本身就有地址,所以可以有指向指针的指针;可变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变。
引⽤就是变量的别名,从⼀⽽终,不可变,必须初始化。
不存在指向空值的引⽤,但是存在指向空值的指针。
可变性:
指针: 可以改变指针的指向,使其指向不同的内存地址。
引⽤: ⼀旦引⽤被初始化,它将⼀直引⽤同⼀个对象,不能改变绑定。
⽤途:
指针: 通常⽤于动态内存分配、数组操作以及函数参数传递。
引⽤: 通常⽤于函数参数传递、操作符重载以及创建别名。
2.const关键字
-
const作用:被它修饰的值不能改变,是只读变量。必须在定义的时候就给它赋初值。
-
const可修饰:普通变量或成员变量,指针变量,函数参数,成员函数,修饰引用
-
常量指针
- 是指定义了⼀个指针,这个指针指向⼀个只读的对象,不能通过常量指针来改变这个对象的值,但可以改变指针的指向。常量指针强调的是指针对其所指对象的不可改变性。
- 形式:
(1)const 数据类型 *指针变量= 变量名
(2)数据类型 const *指针变量 = 变量名
-
指针常量
- 指针常量是指定义了⼀个指针,这个指针的值只能在定义时初始化。指针常量强调的是指针的不可改变性。——指针指向不可变,但可以通过指针改变指针指向的值。
- 形式:数据类型 * const 指针变量=变量名
//常量指针
int temp = 10;
const int* a = &temp;
int const *a = &temp;
// 更改:
*a = 9; // 错误:只读对象
temp = 9; // 正确
//指针常量
int temp = 10;
int temp1 = 12;
int* const p = &temp;
// 更改:
p = &temp2; // 错误
*p = 9; // 正确
-
const 引用:const 引用是指向 const 对象的引用,可以读取变量,但不能通过引用修改指向的对象。
-
const修饰类成员函数:const 修饰类成员函数,其目的是防止成员函数修改被调用对象的值,如果我们不想修改一个调用对象的值,所有的成员函数都应当声明为 const 成员函数。
3.static关键字
static 关键字主要⽤于控制变量和函数的⽣命周期、
作⽤域以及访问权限。
在 C++ 中,使用 static 可以定义局部静态变量、外部静态变量、静态函数、
静态成员变量和静态成员函数。因为 C++ 中有类的概念,
静态成员变量、静态成员函数都是与类有关的概念。
-
静态局部变量:
- 在函数内部使⽤ static 关键字修饰的局部变量是静态局部变量。
- 静态局部变量的⽣命周期延⻓到整个程序的执⾏过程,但只在声明它的函数内可⻅。
-
静态成员变量:
- 在类中使⽤ static 关键字修饰的成员变量是静态成员变量。
- 所有类的对象共享同⼀个静态成员变量的副本。
- 静态成员变量必须在类外部单独定义,以便为其分配存储空间。
-
静态成员函数:
- 在类中使⽤ static 关键字修饰的成员函数是静态成员函数。
- 静态成员函数不能直接访问⾮静态成员变量或⾮静态成员函数。
- 静态成员函数可以通过类名调⽤,⽽不需要创建类的实例。
4.define和typedef区别
- define
- 只是简单的字符串替换,没有类型检查
- 是在编译的预处理阶段起作⽤
- 可以⽤来防⽌头⽂件重复引⽤
- 不分配内存,给出的是⽴即数,有多少次使⽤就进⾏多少次替换
- typedef
- 有对应的数据类型,是要进⾏判断的
- 是在编译、运⾏的时候起作⽤
- 在静态存储区中分配空间,在程序运⾏过程中内存中只有⼀个拷⻉
#include <stdio.h>
typedef char* ptr;
#define PTR char*
int main()
{
ptr a, b, c;
PTR x, y, z;
printf("sizeof a:%zu\n" ,sizeof(a) );
printf("sizeof b:%zu\n" ,sizeof(b) );
printf("sizeof c:%zu\n" ,sizeof(c) );
printf("sizeof x:%zu\n" ,sizeof(x) );
printf("sizeof y:%zu\n" ,sizeof(y) );
printf("sizeof z:%zu\n" ,sizeof(z) );
return 0;
}
sizeof a:8
sizeof b:8
sizeof c:8
sizeof x:8
sizeof y:1
sizeof z:1
5.define 和 inline 的区别
-
define:
定义预编译时处理的宏,只是简单的字符串替换,⽆类型检查,不安全。 -
inline:
inline是先将内联函数编译完成⽣成了函数体直接插⼊被调⽤的地⽅,减少了压栈,跳转和返回的操作。
没有普通函数调⽤时的额外开销;
内联函数是⼀种特殊的函数,会进⾏类型检查。 -
C++中inline编译限制:
- 不能存在任何形式的循环语句
- 不能存在过多的条件判断语句
- 函数体不能过于庞⼤
- 内联函数声明必须在调⽤语句之前
6.const于define的区别
const⽤于定义常量;⽽define⽤于定义宏,⽽宏也可以⽤于定义常量。都⽤于常量定义时,它们的区别有:
const | define | |
---|---|---|
编译阶段 | ⽣效于编译的阶段 | define⽣效于预处理阶段 |
存储空间 | 存储在内存中、需要额外的内存空间的 | define定义的常量,运⾏时是直接的操作数,并不会存放在内存中 |
安全性 | 定义的常量是带类型的 | 定义的常量不带类型。因此define定义的常量不利于类型检查。 |
7. volatile关键字
- 定义:
[与const绝对对⽴的,是类型修饰符]影响编译器编译的结果,⽤该关键字声明的变量表示该变量随时可能发⽣变
化,与该变量有关的运算,不要进⾏编译优化;会从内存中重新装载内容,⽽不是直接从寄存器拷⻉内容。 - 作⽤:
指令关键字,确保本条指令不会因编译器的优化⽽省略,且要求每次直接读值,保证对特殊地址的稳定访问 - 使⽤场合:
在中断服务程序和cpu相关寄存器的定义
8.extert
- 定义:声明外部变量[在函数或者⽂件外部定义的全局变量]
9.前置++与后置++
++a表示取a的地址,增加它的内容,然后把值放在寄存器中;
a++表示取a的地址,把它的值装入寄存器,然后增加内存中的a的值;
前置++的效率高于后置++,因为前置的++没有生成额外的对象,意味着不需要过多的内存,也就是不需要在栈上生成对象。而后置的++需要创建栈空间上的对象,占用栈空间,并且需要调用构造函数,返回后需要调用析构函数。
10.函数指针和指针函数
- 函数指针:
- 是指向函数的指针变量。它可以⽤于存储函数的地址,允许在运⾏时动态选择要调⽤的函数。
- 指针函数:
- 指针函数是⼀个返回指针类型的函数,⽤于返回指向某种类型的数据的指针。