#指针
指针
指针(pointer)是C++中一个比较重要的应用。通过指针,可以简化一些C++编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的。
变量的地址
每一个变量都有一个内存位置,地址则表示了在内存中的一个位置。变量的地址是由十六进制数构成的整型常量。
#include <iostream>
using namespace std;
int main() {
int a = 1;
// 4字节 的十六进制构成的常量,不可修改
cout << "地址:" << &a << endl;
return 0;
}
运行结果:
地址:0x6ffe1c
指针的作用
指针 -> 访问变量的地址(内存中的位置) -> 访问目标变量
导航 -> 输入目的地的地址(地球中的位置) -> 访问到目的地
指针类型和指针变量
指针变量也是一个变量,只不过其值为另一个变量的地址。就像其他变量或常量一样,你必须在使用指针存储其他变量地址之前,对其进行声明。
int* p; // 整型指针变量
double* p; // 浮点型指针变量
char* p; // 字符型指针变量
比如int*
类型的指针变量p可以存储int型变量的地址。
#include <iostream>
using namespace std;
int main() {
int a = 1;
// 4字节 的十六进制构成的常量,不可修改
cout << "地址:" << &a << endl;
// 指针变量是存储地址的
// int* 整型指针类型 p 整型指针变量-指针变量是存储地址的
int* p = &a;
return 0;
}
指针的作用和解引用
作用:
- 指针变量是用来存地址的。
解引用:
- 指针变量p存的是谁的地址,那么
*p
就是谁。
#include <iostream>
using namespace std;
int main() {
int a = 1;
// 4字节 的十六进制构成的常量,不可修改
cout << "地址:" << &a << endl;
// 指针变量是存储地址的
// int* 整型指针类型 p 整型指针变量-指针变量是存储地址的
int* p = &a;
cout << p << endl;
return 0;
}
运行结果:
地址:0x6ffe14
0x6ffe14
取值
#include <iostream>
using namespace std;
int main() {
int a = 1;
// 4字节 的十六进制构成的常量,不可修改
cout << "地址:" << &a << endl;
// 指针变量是存储地址的
// int* 整型指针类型 p 整型指针变量
// 作用:指针变量是用来存地址的。
int* p = &a;
cout << p << endl;
// *p 解引用:指针变量p存的是谁的地址,那么 *p 就是谁。
cout << *p << endl;
return 0;
}
运行结果:
地址:0x6ffe14
0x6ffe14
1
指针地址和变量是不是一样的
#include <iostream>
using namespace std;
int main() {
int a = 1;
int* p = &a;
// p 地址 的值 加1
(*p)++;
cout << *p << " " << a << endl;
return 0;
}
运行结果:
2 2
指针变量的内存
指针变量的内存:
- 32位编译器中所有类型的指针变量大小均为4Byte(字节)
- 64位编译器中所有类型的指针变量大小均为8Byte(字节)
指针可以为空指针:
- int* p = nullptr,空指针一样有内存大小。
#include <iostream>
using namespace std;
int main() {
int a = 1;
int* p = &a;
// 内存
// 32位编译器中所有类型的指针变量大小均为4Byte(字节)
// 64位编译器中所有类型的指针变量大小均为8Byte(字节)
// 根据系统来,正好够寻址整个空间即可
cout << sizeof(p) << "byte" << endl;
// 空指针 一样占用内存
int* s = nullptr;
cout << "空指针占用内存:" << sizeof(s) << "byte" << endl;
return 0;
}
运行结果:
8byte
空指针占用内存:8byte
#基于指针的数组访问
通过指针访问数组
我们首先定义一个数组:
int a[6] = {1, 2, 3, 4, 5, 6};
其中a是数组名,也是地址常量,常量不可修改。
a数组名代表数组首元素的地址,可以通过指针变量存储。
int* p=a;
#include <iostream>
using namespace std;
int main() {
int a[] = {1, 2, 3, 4, 5, 6};
//数组名a代表数组中首元素的地址
int* p = a;
cout << *p << endl;
return 0;
}
运行结果:
1
通过指针打印数组
先打印该数组中每个元素的地址。
对于数组来说,数组中元素的地址是从低到高连续的
,数值相差类型的字节数
。
一开始 *p 就是array数组第一个元素。
随后 p++;
等价于 p=p+1*sizeof(int);
此时的 *p 就是array数组的第二个元素。
#include <iostream>
using namespace std;
int main() {
int a[] = {1, 2, 3, 4, 5, 6};
//数组名a代表数组中首元素的地址
int* p = a;
cout << *p << endl;
//数组中地址是由低到高排列的
//数组中每个元素之间地址的差值是sizeof(type)
for(int i = 0; i < 6; i++){
cout << &a[i] << endl;
}
return 0;
}
运行结果:数组中每个元素地址,相差4字节
1
0x6ffdf0
0x6ffdf4
0x6ffdf8
0x6ffdfc
0x6ffe00
0x6ffe04
通过指针访问数组元素
#include <iostream>
using namespace std;
int main() {
int a[] = {1, 2, 3, 4, 5, 6};
int* p = a;
for(int i = 0; i < 6; i++){
cout << *p << endl;
p++; // p = p + 1 * sizeof(int)
}
return 0;
}
运行结果:
1
2
3
4
5
6
#字符指针
字符指针和字符数组
我们之前学过用整型指针访问整型数组,现在我们可以尝试一下通过字符指针访问字符数组。
#include <iostream>
using namespace std;
int main() {
char str[] = "hello";
char* p = str;
//直接访问
cout << p << " " << str << endl;
for(int i = 0; i < 5; i++){
cout << *p;
p++;
}
return 0;
}
运行结果:
hello hello
hello
字符指针和字符串
"hello"可以称作字符串,又叫字符串常量,其值对应的是串中首元素的地址,那么对于这样一个字符串我们也可以直接用指针变量存储该字符串的首地址
,即char* p = "hello;"
字符指针变量p里面存的就是字符串"hello"的首地址。现在就可以通过指针变量p可以访问整个字符串了。
char* p="hello";
"hello"叫做字符串,p只是存了字符串的首地址,所以p并不能代表字符串本身。
通过指针打印字符串
#include <iostream>
using namespace std;
int main() {
const char*p = "hello";
while(*p){
cout << *p;
p++;
}
return 0;
}
运行结果:
hello
为什么while(*p)
会自动结束呢?
字符指针变量p里面存的就是字符串"hello"的首地址,p++依次向后遍历,最后会取到结尾字符\0
就是0,退出while循环。
#指向结构体的指针
指向结构体的指针
定义一个学生结构sth,包含学号id、姓名name、同桌deskmate,请问同桌deskmate应该是什么类型?
没错,同桌deskmate也是stu类型,然而我们不能在stu结构体里面存储stu结构体,这是C++不允许的!
如何解决上述问题呢?虽然不能直接存储stu结构体,但是我们可以存储stu结构体的地址,通过地址访问到结构体本身。
所以我们需要一个指针去存储地址,什么类型的呢?没错,答案就是stu*
类型的结构体指针。
参考代码:
#include <iostream>
using namespace std;
struct stu{
int id;
string name;
stu* p; // 同桌
};
int main() {
stu A, B;
A.id = 1; A.name = "laowang";
B.id = 2; B.name = "xiaohe";
A.p = &B;
cout << A.name << "的同桌是" << A.p->name << endl;
return 0;
}
运行结果:A.p->name
解引用
laowang的同桌是xiaohe