#include<iostream>
using namespace std;
// 可以通过指针来保存内存的地址。
int main()
{
int a = 10;
// 1、指针定义的语法:数据类型 * 指针变量名;
int* p;
// 让指针记录变量a的地址
p = &a;
cout << "a的地址为:" << &a << endl;
cout << "a的地址为:" << (int)&a << endl;
cout << "p的值为:" << p << endl; // 与a的地址相同。
// 2、拿到地址怎么用?
// 可以通过 解引用 的方式来找到指针指向的内存中存储的数据。
// 解引用:指针的前面加上 * 。找到指针指向的内存中的数据。
cout << "解引用p:即*p:" << *p << endl;
// 间接使用指针来修改、访问内存中存储的值。
*p = 1000;
cout << "通过*p修改内存之后a的值为:" << a << endl;
cout << endl;
// 3、指针类型所占的空间。都是根据操作系统的位数决定了。x64占8个字节。x86占用4个字节。
cout << "sizeof (int*) = " << sizeof(int*) << endl;
cout << "sizeof (string*) = " << sizeof(string*) << endl;
cout << "sizeof (float*) = " << sizeof(float*) << endl;
cout << "sizeof (double*) = " << sizeof(double*) << endl;
cout << "sizeof (char*) = " << sizeof(char*) << endl;
// 4、空指针
// 空指针:指针变量指向内存中编号为0的空间。
// 用途:初始化指针变量。
// 注意:空指针指向的内存是不可以访问的。
// 因为:0~255之间的内存,是系统占用的,一旦访问就报错:写入访问权限冲突。
int* p1 = NULL;
//*p1 = 200; //写入访问权限冲突
//cout << *p1 << endl; //读取访问权限冲突
// 5、野指针:指针变量指向非法的内存空间。
int* p2 = (int*)0x1100;
//cout << *p2 << endl; // 编译器无法检测出这个问题。:未申请,却访问。
// 小结:
// 空指针和野指针都不是我们申请的空间,因此不要访问。
// 6、const修饰指针
//(1)const修饰指针:常量指针。
//(2)const修饰常量:指针常量。
//(3)const即修饰指针,又修饰常量。
//(1)const修饰指针:常量指针:在指针的前面加上一个const
int x = 10;
int y = 10;
int* p3 = &x; // p3指针保存的x的地址。
const int* p4 = &x; // 常量指针:特点:指针的指向可以修改,但是指针指向的值不可以改。
//const后面跟的是类型。类型是指针,所以说是常量指针。
//常量的值不可变。
// *p4 = 20; // 这行代码错误:因为常量指针指向的值不可变。VS会提示:表达式左边必须是可修改的左值。
// p4 = &y; // 这行代码正确:因为常量指针指向可以变。
// (2)const修饰常量:指针常量
int* const p5 = &x;
// const加在变量名前。const后面跟的是变量名。const修饰的是变量。所以指针常量。
// 特点:指针的指向不可以改,指针指向的值可以改。
//*p5 = 20; // 正确:指针指向的值,可以改。
//p5 = &y; // 错误:指针的指向不可以改。
// (3)const即修饰指针,又修饰常量。
const int* const p6 = &x;
// 特点:指针的指向和指针指向的值都不可以改。
// *p6 = 20; // 错误。
// p6 = &y; // 错误。
//记忆方法:const修饰的是类型:类型不可以变更。类型是由内容决定的。所以可以随意指向,但是类型不可变。因为值决定类型,一旦值变了,那么类型也必然变动。因此值不可变。可以指向其他同类型值。
//记忆方法:const修饰的是变量:变量不可随意指向。
int z = 20;
p4 = &z;
cout << "常量指针p4所指向的值不可以修改,但是指针指向可以改,因为指向修改导致值的修改为:" << *p4 << endl;
string s = "abc";
//p4 = &s; // VS编译器会提示:不能讲std::string* 类型的值分配到const int *类型的实体。
//常量指针 指向 可以变。但是类型不可变,为了保证类型不可变,所以限定值不可变。
//指针常量修饰的是变量,限定的是变量,变量不可随意指向。
//但是值可以修改,but,虽然值可以改,但是值的类型不可以改。
system("pause");
return 0;
}
//记忆方法:const修饰的是类型:类型不可以变更。类型是由内容决定的。所以可以随意指向,但是类型不可变。因为值决定类型,一旦值变了,那么类型也必然变动。因此值不可变。可以指向其他同类型值。
//记忆方法:const修饰的是变量:变量不可随意指向。
- 常量指针://常量指针 指向 可以变。但是类型不可变,为了保证类型不可变,所以限定值不可变。
- 指针常量://指针常量修饰的是变量,限定的是变量,变量不可随意指向。地址不可以变,后面要讲的引用的本质。
- //但是值可以修改,but,虽然值可以改,但是值的类型不可以改。因为地址中的内存大小早已被限定。