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;
}
原文地址:https://www.cnblogs.com/mungerz/p/10509092.html