C/C++基础(二)
解决问题:
C/C++里的const关键字?
C/C++里的static关键字?
1. C/C++里的const关键字
C/C++里的const是一个关键字,一个限定符,它用来限定一个变量不允许改变,它将一个对象转换成了一个常量。
案例1:
const int a = 10; a = 100; //编译错误,const是一个常量,不能修改。
1.1 C和C++中const的区别?
1.1.1 C中的const
C中const修饰的变量是一个只读变量,因为是变量,就会给const分配内存,并且在C中const是一个全局只读变量。
案例2:
const int size = 10; int arr[size]; // 编译错误,size仍旧是变量,C编译器无法再编译时知道size中值。
1.1.2 C++中的const
在C++中,一个const不必创建内存空间,而在C中,一个const总是需要一块内存空间。
1.1.3 总结
(区别一)C语言中全局const会被存储到只读数据段中。C++中全局const当声明extern或者对变量取地址时,编译器会分配存储地址,变量存储在只读数据段中。两个都受到只读数据段的保护,不可修改:
案例3:
const int a = 10; int main(){ int *p = (int *)&a; *p = 200; }
以上代码,编译通过,但是运行错误。因为在修改变量a时,发生写入错误,因为在修改只读数据段中的数据。
(区别二)C语言中的局部const会被存储到堆栈中,只是不能直接修改,但是可以跳过编译器检查,通过指针间接修改:
案例4:
int main(){ const int b = 100; int *p = (int *)&b; *p = 101; }
正常运行!
C++对于局部变量要区别对待:
a. 对于基本数据类型,例如const int a = 10,编译器会把它放到符号表中,不分配内存,当对其取地址时会分配内存。
b. 对于基础数据类型,如果用一个变量初始化const变量,例如const int a =b,那么也会给a分配内存。
案例5:
// 情况a const int a = 10; int *p = (int *)&a; *p = 15; // 情况b const int b = c;
两者都正常运行!
c. 对于自定义数据类型,比如,类对象。也会分配内存。
(区别三)中const默认为外部连接,C++中const默认为内部连接.当c语言两个文件中都有const int a的时候,编译器会报重定义的错误。而在C++中,则不会,因为C++中的const默认是内部连接的。如果想让c++中的const具有外部连接,必须显示声明为: extern const int a = 10;
2. C++中的static关键字
2.1 静态成员(包括静态成员和成员函数)
对于静态成员,无论创建多少个对象,静态成员只有一个拷贝。静态成员被该类所有对象共享。
2.1.1 静态成员变量
静态变量,是在编译阶段就分配空间,对象还没有创建时,就已经分配空间。
- 静态成员变量必须在类中声明,在类外定义。
- 静态数据成员不属于某个对象,在为对象分配空间中不包括静态成员所占空间。
- 静态数据成员可以通过类名或者对象名来引用。
2.1.2 静态成员函数
静态成员函数的意义,不在于信息共享,数据沟通,而在于管理静态数据成员,完成对静态数据成员的封装。
- 静态成员函数只能访问静态变量,不能访问普通成员变量。
- 静态成员函数的使用和静态成员变量一样,可以通过类名和对象来引用。
- 静态成员函数也有访问权限。
- 普通成员函数可访问静态成员变量、也可以访问非静态成员变量。
案例6:
#include <iostream> using namespace std; class Student{ public: static int schoolNum; public: static int getSchoolNum(){ return schoolNum; } }; int Student::schoolNum = 10000; int main(){ int schoolNum = Student::schoolNum; Student student; int schoolNum2 = student.schoolNum; int schoolNum3 = student.getSchoolNum(); cout << "schoolNum" << schoolNum << endl; cout << "schoolNum2" << schoolNum2 << endl; cout << "schoolNum3" << schoolNum3 << endl; return 0; }