C进阶:指针的进阶(1)

Bertha 。 2023-10-13 13:54 123阅读 0赞

446a55645ee24a87b9c6545b337627f4.png

回归

哈喽哈喽大家好呀,我是灰灰快醒醒,时隔一个月又与大家见面了。众所周知,期末考试是中国教育部为大学生专门研发的一款开放式大逃杀游戏,学生需要扮演大难将至而绝望的人类,与小骚书共同完成《**期末复习**》的任务,不断逃离挂科的局面……所以作者一个月没写文章(借口)。

好了回归正题,今天讲解的内容是指针的进阶,我们继续探讨指针的高级主题(假装一本正经的样子)。

简要回顾(指针的简介)

我们都知道,计算机当中的内存会划分为一个个内存单元,每个单元都有独立的编号地址,而地址在C语言中称为指针。简:编号=地址=指针

指针(地址)需要存储起来——存储至变量中,该变量为指针变量。指针变量的大小根据(32/64)位平台分为(4/8)两种大小。

新内容学习

字符指针

顾名思义:字符指针就是指向字符的指针,所以其类型为char*。

一般使用如下:

  1. #include<stdio.h>
  2. int main()
  3. {
  4. char ch = 'a';
  5. //定义指针变量p,指向ch的类型为字符类型
  6. char* pc = &ch;
  7. *pc = 'b';
  8. return 0;
  9. }

还有一种使用方法如下:

  1. #include<stdio.h>
  2. int main()
  3. {
  4. //这里是将一个字符串放入到pstr指针变量里面了吗?
  5. char* pstr = "hello";
  6. printf("%s\n", pstr);
  7. return 0;
  8. }

这段代码的打印结果就是是“hello”,所以就会有人误解为将这一整段字符串放入指针pstr里面了,但实际上是将hello的首字符的地址放入了pstr指针当中

上面代码的意思就是把一个常量字符串的首字符h的地址存放到指针变量pstr当中了。

下面再看这样一道题:

  1. #include<stdio.h>
  2. int main()
  3. {
  4. char str1[] = "hello";
  5. char str2[] = "hello";
  6. char* str3 = "hello";
  7. char* str4 = "hello";
  8. if (str1 == str2)
  9. printf("str1 and str2 are same\n");
  10. else
  11. printf("str1 and str2 are not same\n");
  12. if (str3 == str4)
  13. printf("str3 and str4 are same\n");
  14. else
  15. printf("str3 and str4 are not same\n");
  16. return 0;
  17. }

上面一段代码的结果又是什么,让我们看一下输出:

54347cfbf4f54d458571c9c5e0b012e5.png

为何会出现这样的结果,让我们来逐一分析一下:

要首先记住这几个关键的概念:

1.一般情况下,数组名代表的是数组首元素的地址。

2.常量字符串是不允许被修改的。

(1)str1 和 str2 :分别创建了str1[ ]和str2[ ]这两个独立的数组,所以它们在内存中的存放的地址也肯定不相同,所以首个字符的地址也肯定不同,所以判断出来是不相同的。

(2)str3 和 str4 : 首先定义一个指向hello第一个字符的指针变量str3,然后因为上面第二个概念嘛,定义第二个指针变量str4一定还是指向同一个字符串的第一个字符,所以它们指向的是同一个位置。

指针数组

定义:指针数组是一个存放指针的数组,数组中的每一个元素的类型是指针类型

数组我们已经知道的有整型数组与字符数组等。

int arr[ ]

char arr[ ]

它们的类型一个是整型int,一个是字符类型char

因此类比得到整型指针数组和字符指针数组

int* arr[ ]

char* arr[ ]

数组指针可以用来模拟二维数组,举例如下:

  1. #include<stdio.h>
  2. int main()
  3. {
  4. int arr1[] = { 1,2 };
  5. int arr2[] = { 3,4 };
  6. //定义一个指针数组,两个元素分别为前面两个数组的首元素地址
  7. int* arr[] = { arr1,arr2 };
  8. int i = 0;
  9. //循环遍历数组
  10. for (i = 0; i < 2; i++)
  11. {
  12. int j = 0;
  13. for (j = 0; j < 2; j++)
  14. {
  15. //*(*(arr + i) + j) -> *(arr[i] + j) -> arr[i][j]
  16. printf("%d ", *(*(arr + i) + j));
  17. }
  18. printf("\n");
  19. }
  20. return 0;
  21. }

数组指针

定义:能够指向数组的指针。

基本书写格式:类型 (*数组指针名)[元素数量]

eg:int (*p) [10]

解释:p先和*结合,说明p是一个指针变量,然后指向的是一个数组大小为10的整型数组,所以p是一个指针,指向数组,叫做数组指针。

这里要注意: [ ]的优先级是大于*的,所以要先使用()以此保证p与*先结合。

那数组指针是怎么使用的呢?

既然数组指针指向的是数组,那数组指针中存放的应该是数组的地址。

一个数组指针的使用:还是以遍历二维数组为例:

  1. #include <stdio.h>
  2. //注意二维数组传参时,数组指针还是可以省略行,不可以省略列
  3. void print_arr(int (*p)[5],int row, int col)
  4. {
  5. int i = 0;
  6. for (i = 0; i < row; i++)
  7. {
  8. int j = 0;
  9. for (j = 0; j < col; j++)
  10. {
  11. printf("%-3d", p[i][j]);
  12. }
  13. printf("\n");
  14. }
  15. }
  16. int main()
  17. {
  18. int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
  19. //数组名arr,表示首元素的地址
  20. //但是在二维数组当中,首元素就是第一行
  21. //所以这里传递的arr就是第一行的地址,也就是一维数组的地址
  22. //所以我们可以使用一个数组指针来接收一行的地址
  23. print_arr(arr, 3, 5);
  24. return 0;
  25. }

打印结果如下:

8f4cad8ed34846f29b6b16be2b4634ec.png

学了指针数组和数组指针让我们一起来看看下面代码的意思:

  1. int arr[5];
  2. //定义一个整型数组,数组中共有五个元素
  3. int *parr1[10];
  4. //定义一个指针数组,每个元素的类型为int*,共有十个元素
  5. int (*parr2)[10];
  6. //定义一个数组指针parr2,其指向一个大小为10的整型数组
  7. int (*parr3[10])[5];
  8. //可以将*parr3[10]看作*p所以总的来说它是一个数组指针,
  9. //指向一个大小为5的整型数组,而*parr3[10]又可以看成一个指针数组
  10. //因此可以将它看成一个10行5列,每个元素为int的二维数组

这一期就讲到这里,感谢各位观众老爷支持。

发表评论

表情:
评论列表 (有 0 条评论,123人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C指针(一)

    > 大家好,我是深鱼~ 【前言】: 指针的主题,在初阶指针章节已经接触过了,我们知道了指针的概念: 1.指针就是个变量,用来存放地址,地址的唯一标识一块内存空间(指针变量