(不是专业讲师,可能讲得不是很清楚,有问题可以留言)
(综合视频在文末,其中略有错误,文中对应有说明。建议和文章一起看)
指针体系可以分为5个部分。
1.指针
2.指针与引用
3.指针与函数
4.指针与数据
5.指针+结构体 == 数据结构
1.指针
指针定义:存储地址的变量;
声明定义模板:typename* name (= 地址),例如int* prt;
值得注意的是两个指针变量之间只能做 “-” 运算。因为其他运算毫无意义可言。
2.指针与引用
引用定义:已存在变量的别名(小名);
声明定义模板:typename& name = data_name;例如int& p = a;
template<typename Type>
void Print(Type value) {
std::cout << value << std::endl;
return;
};
int main() {
int a = 3, b = 4,c=5;
int* prt = &a;
int& p = a;//都指向a
Print(prt);
p = b;//仍然指向a
Print(p);
p = c;
Print(p);//仍然指向a,定义完引用后一直跟随不能更改
}
引用
根据视频中的操作方式,我们可以看见引用p的地址始终是变量a的地址。
也就是说 & = *const(固定地址的指针)
3.指针与函数
指针在函数中的引用主要在于多数据的更改。顺便一提,引用也可以达到更改多数据的目的,因为其本质就是指针。这部分讲解集中在文末视频。
对于视频中的swap1函数调用完成后,代码目的未实现的原因单独拎出来再说一说。
我们可以很清楚的知道,在一段程序编写中(数据的处理中),我们难免会出现某一时刻大量相同的数据,但是它们存储在不同变量。
如何精确处理这些数据?这就牵扯到编译器自身就是传输地址-->处理地址相对应的数据。
如果看过/学过 反汇编代码 ,我们知道其中牵扯到cpu指令call的执行。这个指令的作用就是跳转到函数体执行代码,执行完成后,恢复成函数参数进入函数时的状态。
可以说是,就是对于swap1函数的情况,编译器会认为传入常量。
值得一提的scanf函数
从上述头文件函数定义代码我们可以知道,scanf有两个传递值 一个字符串用来表示输入的格式,一个指针用来表示存储的地址(地方)。
所以以下代码变得可行,可理解
int* p = new int;//int* p = (int*) malloc(sizeof(int));
scanf("%d",p);
4.指针与数组
我们知道数组名就是指针,这就有了数组和指针的关系。
而理解这件事情并不难,因为编译器存储/认识一个数据靠的就是地址。而在记录一连串数据时(一个数组),那么我们只需要知道头一个数据地址就可以查询到其余数据。
视频纠正:[]对于指针+数字来说 就是 *( + );
所以 a[i] 与 i[a] 都表示 *(a+i)或者*(i+a);那它们访问的肯定时同一个值。这里的知识点仅作了解,除非你要参加乱码大赛,让读代码的人蛋疼去。
容易混淆:int*p[10] 与 int(*p)[10];
讲解:
对于int* p[10]; 明确一点 [] 优先级大于 *([]>*),所以式子可以改成int* (p[10]);
我们可以先明确这是一个数组,然后看数据类型,int* --> 指向整数类型的指针。重新组织语言
int* p[10] 表示 存储 指向整数类型指针的 数组;
对于int (*p)[10];,因为()改变优先级,所以我们可以明确种类是指针,可能看int(*p)[10]很抽象,所以我做出以下等价变换,int(*p)[10] == int[10] (*p) ;所以我们可以得知,数据类型是长度为10的数组。重新组织语言得到, int (*p) [10] 是 指向 长度为10的数组的 指针。
指针基础