一个指针只是一个地址,它是一个保存了内存地址的整数,
指针无所谓类型,类型是完全没有意义的,
所有类型的指针,都是保存了内存地址的整数
如果我们给指针一个类型,只是说这个地址的数据,被假设为我们所给的类型,除此之外,没有其他意义
指针实质上只是一个内存地址的变量,它是一个整数
定义一个空指针,它是无类型的,它的内存地址是0
pointer 指针,简写ptr
void* ptr = 0;
void* ptr = NULL;
void* ptr = nullptr;
我们给这个指针的内存地址是 0
0 实际上不是一个有效的内存地址,内存地址不会一直到0,0是无效的,这意味着指针是无效的,无效指针可以接受的状态
我们不能从内存地址0中读取或写入,如果我们尝试这样做,系统会崩溃,所有0意味着没有
我们有变量var,指针ptr指向var
int main()
{
int var = 8;
void* ptr = &var;
std::cin.get();
}
内存地址 4个字节
我们可以通过在指针前面插入一个*星号来实现从指针回到var变量
换句话说,我们实际上是在逆向引用这个ptr指针,
意味着,我们现在可以读取或者写入数据到var变量
int main()
{
int var = 8;
void* ptr = &var;
*ptr = 10;
std::cin.get();
}
第五行会出现错误,
计算机不能把10这个值写入到void类型的空指针,计算机不知道10是什么
可能是short类型2个字节
可能是int类型 4个字节
可能是long long类型 8个字节的整数
他不知道需要多少个字节的数据
这个时候需要类型,告诉编译器,它是一个整数
把空指针改成int类型的指针,告诉编译器,它是int类型的整数,有4个字节
#include <iostream>
#define LOG(x) std::cout << x << std::endl
int main()
{
int var = 8;
int* ptr = &var;
*ptr = 10;
LOG(var);
std::cin.get();
}
断点查看可以发现,var的内存地址,存放的数据从8变成10
int main()
{
char* buffer = new char[8];
std::cin.get();
}
创建一个char类型的指针,我们知道他只有一个字节长度,
这里我们分配了8个字节的内存,并返回一个指向这块内存开始的指针
我们可以用memset()函数,指定数据填充一个内存块
它接收一个指针,这个指针将会是内存块开始的指针
#include <iostream>
#define LOG(x) std::cout << x << std::endl
int main()
{
char* buffer = new char[8];
memset(buffer, 1, 8);
delete[] buffer;
std::cin.get();
}
可以看到buffer指针指向的地址被赋值
new关键字可以创建一块动态内存
使用完毕之后,可以用关键字delete删除
new出来一个数组,要用delete[] 来删除动态内存
双指针
指向指针的指针 char** ptr = &buffer;
#include <iostream>
#define LOG(x) std::cout << x << std::endl
int main()
{
char* buffer = new char[8];
memset(buffer, 1, 8);
char** ptr = &buffer;
delete[] buffer;
std::cin.get();
}
可以看到ptr指针指向了一个地址
使用系统是64位, 8个字节等于64个位,只是内存顺序颠倒了0x000002A254D98620
把地址顺序重新排列
可以看到是buffer的地址
地址指向new出来的内存块