202111051401指针类型.mp4

大纲要求

•【4】指针的概念及调用

•【4】指针与数组

•【4】字符指针与string类

•【4】指向结构体的指针


指针类型

指针是“指向(point to)”另外一种类型的复合类型。复合类型是指基于其它类型定义的类型。

指针**在 C++ 是保存另一个变量的存储器地址的变量。
引用**是一个已经存在的变量的别名。
一旦引用被初始化为一个变量,它就不能被更改为引用另一个变量。

理解指针,先从内存说起:内存是一个很大的、线性的字节数组。每一个字节都是固定的大小,由 8 个二进制位组成。最关键的是,每一个字节都有一个唯一的编号,编号从 0 开始,一直到最后一个字节。

程序加载到内存中后,在程序中使用的变量、常量、函数等数据,都有自己唯一的一个编号,这个编号就是这个数据的地址。

指针的值实质是内存单元(即字节)的编号,所以指针单独从数值上看,也是整数,他们一般用16进制表示。指针的值(虚拟地址值)使用一个机器字的大小来存储,也就是说,对于一个机器字为w位的电脑而言,它的虚拟地址空间是11. 指针类型 - 图2,程序最多能访问11. 指针类型 - 图3个字节。这就是为什么 xp 这种 32 位系统最大支持 4GB内存的原因了。

用来保存指针的对象,就是指针对象。如果指针变量 p1 保存了变量 a 的地址,则就说:p1 指向了变量a,也可以说 p1 指向了 a 所在的内存块 ,这种指向关系,在图中一般用 箭头表示:
image.png

  1. // 普通变量
  2. int a = 3;
  3. // 定义了变量a,int类型,值为3.内存中有一块内存空间是放a的值
  4. // 对a的存取操作,就是直接到这个内存空间存取
  5. // 内存空间的位置,叫地址
  6. // 存放 3 的地址,可以用 取地址操作符 & 得到,&a
  7. // 指针变量
  8. int *p = NULL;
  9. // 定义了一个指针变量 p,p指向一个内存空间,里面存放的是一个内存地址
  10. // 现在赋值为NULL(就是0,表示特殊的空地址),空指针
  11. // 申请一个空间给 p,*p内容不确定
  12. int *p = new(int);
  13. // 给指针变量 p 赋值, & 发音 and
  14. p = &a;
  15. // 把 a 变量的内存空间地址给了 p
  16. // 直接对 p 存取,操作的是地址
  17. // 通过这个地址,间接地操作,才是整数3
  18. // p的间接操作要使用指针操作符 *, *p 的值才是3
  1. // 指针定义
  2. // 类型说明符 *指针变量名
  3. int a = 10;
  4. int *p;
  5. // 取地址运算符 &
  6. p = &a;
  7. // 间接运算符 *,解引用符 *
  8. *p = 20;
  9. // 指针变量直接存取的是内存地址
  10. cout << p << '\n'; // 0x4097ce
  11. // 间接存取的才是存储类型的值
  12. cout << *p << '\n'; // 20
  1. // *有靠近变量类型的,有靠近变量名称的
  2. // 有什么区别呢
  3. int *p;
  4. int* p;
  5. // *靠近哪一个都可以,编译器都会认为是指针变量,所以本质是一样的
  6. // 推荐靠近变量名称写 int *p
  7. int &ret;
  8. int& ret;
  9. // 这个也是同理
  1. // 指针与引用
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. int main(){
  5. // 指针在声明后,无论何时都可以初始化为任意值
  6. // 可以分配一个指针来指向一个NULL值
  7. // 指针需要使用 *
  8. // 指针可以改为指向相同类型的任何变量
  9. int a = 5;
  10. int *p;
  11. p = &a;
  12. // or int *p = &a;
  13. cout << *p << '\n';
  14. // 引用被声明时必须进行初始化
  15. int b = 6;
  16. int &ref = b;
  17. cout << ref << '\n';
  18. return 0;
  19. }

引用符号的写法

https://blog.csdn.net/qq_17846375/article/details/104422529#:~:text=int%20%26c%20%3D%20a%3B%20int%20%26%20d%20%3D,printf%20%28%22d%20%28int%20%26d%29%3A%25d%20n%22%2C%20d%29%3B%20system%20%28%22pause%22%29%3B
image.png

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N = 10;
  4. int a[N][N];
  5. int main()
  6. {
  7. cout << a << '\n';
  8. cout << a[0] << '\n';
  9. cout << &a[0][0] << '\n';
  10. cout << &a[0][1] << '\n';
  11. cout << a[1] << '\n';
  12. cout << &a[1][0] << '\n';
  13. return 0;
  14. }
  15. /*
  16. 0x1098d50c0
  17. 0x1098d50c0
  18. 0x1098d50c0
  19. 0x1098d50c4
  20. 0x1098d50e8
  21. 0x1098d50e8
  22. */

指针与数组

  1. // 下标法
  2. a[i];
  3. // 指针法
  4. *(a + i);
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = 110;
  4. int a[N], n;
  5. int main(){
  6. cin >> n;
  7. for (int i = 0; i < n; i++) scanf("%d", a + i); //也可以这样读,编译有warning
  8. for (int i = 0; i < n; i++) printf("%d ", *(a + i));
  9. puts("");
  10. return 0;
  11. }

指针与字符串

  1. // 字符串的表示形式
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. int main(){
  5. char s1[] = "Hello s1!";
  6. printf("%s\n", s1);
  7. char *s2 = "Hello s2!"; // 把字符串的第1个元素的地址,赋值给了s2
  8. printf("%s\n", s2);
  9. return 0;
  10. }
  11. // %s 是输出字符串时用到的格式符,在输出项中,给出字符指针变量名,则系统先输出它所指的一个字符数据
  12. // 然后自动使 s2 加1,使之指向下一个字符
  13. // 然后再输出一个字符
  14. // 直到,遇到字符串结束标志'\0'为止
  1. // 字符串指针,作为函数参数
  2. // 可以改变字符串里的内容
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. char s[110];
  6. void solve(char *s){
  7. int len = strlen(s);
  8. for (int i = 0; i < len; i++) s[i] -= 32;
  9. }
  10. int main(){
  11. scanf("%s", s);
  12. char *p = s;
  13. solve(p);
  14. printf("%s\n", s);
  15. return 0;
  16. }
  17. /*
  18. 输入:abc
  19. 输出:ABC
  20. */
  21. // 下面这样写也是等价的
  22. #include <bits/stdc++.h>
  23. using namespace std;
  24. char s[110];
  25. void solve(char *s){
  26. int len = strlen(s);
  27. for (int i = 0; i < len; i++) s[i] -= 32;
  28. }
  29. int main(){
  30. scanf("%s", s);
  31. solve(s); //传递的时候,传递数组的名称,就是指针
  32. printf("%s\n", s);
  33. return 0;
  34. }
  35. // 下面这样写也是等价的
  36. #include <bits/stdc++.h>
  37. using namespace std;
  38. char s[110];
  39. void solve(char s[]){ //形参,写成char s[],这也是个指针
  40. int len = strlen(s);
  41. for (int i = 0; i < len; i++) s[i] -= 32;
  42. }
  43. int main(){
  44. scanf("%s", s);
  45. solve(s);
  46. printf("%s\n", s);
  47. return 0;
  48. }

指针与函数

  1. // 指针作为函数参数
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. void swap(int a, int b){
  5. int t = a;
  6. a = b;
  7. b = t;
  8. }
  9. int main(){
  10. int a, b;
  11. cin >> a >> b;
  12. swap(a, b);
  13. cout << a << ' ' << b << '\n';
  14. return 0;
  15. }
  16. /*
  17. 输入:3 4
  18. 输出:3 4
  19. */
  20. #include <bits/stdc++.h>
  21. using namespace std;
  22. void swap(int *a, int *b){
  23. int t = *a;
  24. *a = *b;
  25. *b = t;
  26. }
  27. int main(){
  28. int a, b;
  29. cin >> a >> b;
  30. swap(&a, &b);
  31. cout << a << ' ' << b << '\n';
  32. return 0;
  33. }
  34. /*
  35. 输入:3 4
  36. 输出:4 3
  37. */
  1. // 函数返回指针
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. int a[110], n, m;
  5. // int* find() 这样写的效果是一样的
  6. int *find(){
  7. for (int i = 0; i < n; i++)
  8. if (a[i] == m)
  9. return &a[i];
  10. return NULL;
  11. }
  12. int main(){
  13. cin >> n >> m;
  14. for (int i = 0; i < n; i++) cin >> a[i];
  15. int *p = find();
  16. if (p == NULL) printf("cannot find\n");
  17. else printf("%d %d\n", p, *p);
  18. return 0;
  19. }

结构体指针

  1. // 引用结构体指针变量指向的结构体变量的成员的方法
  2. struct stu{
  3. int score;
  4. string name;
  5. }*p;
  6. 指针名->成员名
  7. (*p).score;
  8. (*指针名).成员名
  9. p->score
  1. // 自引用结构
  2. struct node{
  3. int x, y;
  4. node *next;
  5. }

字符指针

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = 110;
  4. char s[] = "Hello";
  5. int main(){
  6. char *p = s;
  7. printf("%s\n", s);
  8. printf("%c\n", s[4]);
  9. printf("%c\n", *p);
  10. printf("%c\n", *(p + 4));
  11. printf("%c\n", *p + 4);
  12. cout << p << '\n';
  13. // 需要注意的是,字符串的以“\0”结尾,
  14. // 所以对于“Hello”这个字符串实际上含有6个字符
  15. // 因为表示字符串结尾标志的”\0“是自动添加的。
  16. for (int i = 0; s[i] != '\0'; i++) cout << s[i];
  17. puts("");
  18. return 0;
  19. }
  1. // 字符串的创建,含有多种语法
  2. // 比较重要的一点是初始化时可以不指定数组长度
  3. char duckName[6] = {'D','a','v', 'i', 'd'};
  4. char duckName[6] = "David";
  5. char duckName[] = "David";
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = 110;
  4. char s[N];
  5. void f1(char s[]){
  6. printf("%s\n", s);
  7. }
  8. void f2(char *s){
  9. for (; *s != '\0'; s++) printf("%c", *s);
  10. puts("");
  11. }
  12. int main(){
  13. scanf("%s", s);
  14. f1(s);
  15. f2(s);
  16. return 0;
  17. }
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N = 110;
  4. char s[N];
  5. int len;
  6. void f(char *s){
  7. for (int i = 0; i < len; i++) printf("%c", *(s + i));
  8. puts("");
  9. }
  10. int main(){
  11. scanf("%s", s);
  12. len = strlen(s);
  13. f(s);
  14. return 0;
  15. }