【C语言】初识指针(终篇)

简介: 本文讲解:初识指针。

 

摸了一手秀发,发现还在~


目录

1、指针运算

1.1指针加减整数

1.2指针减指针

1.3指针关系运算

2、二级指针

3、指针和数组

4、指针数组


前言:

大家好,我是拳击哥。上一期我们讲到了指针类型,指针的访问步长,野指针概念。那今天我们就来讲点新的东西,东西不多就四个模块:指针运算、二级指针、指针和数组、指针数组。下面我就来介绍它们的用法。

初识指针(一)

初识指针(二)


1、指针运算

指针运算分为三种情况:

    • 指针加减整数
    • 指针减指针
    • 指针的关系运算

    1.1指针加减整数

    指针加减整数是什么意思呢,就是指针在往前加往后减造成一段数据发生改变。这就是指针加减的意义,它能使数据发生改变。我们拿加法来举例:

    #include<stdio.h>
    #define N_VALUES 5
    int main()
    {
      float values[N_VALUES] = { 1.2f,2.2f,3.2f,4.2f,5.2f };
      float* p;
      for (p = &values[0]; p < &values[N_VALUES];)
      {
        *p++ = 0;
      }
      for (int i = 0; i < N_VALUES; i++)
      {
        printf("%.0f ", values[i]);
      }
      return 0;
    }

    image.gif

    输出结果: 0 0 0 0 0

    上述程序我依次来给大家讲解:首先初始化了一个单精度浮点型数组values有5个元素,并且定义了单精度浮点型指针变量p。大家不要认为这个程序很复杂,就是define定义了一个常量我把这个常量写得比较有逼格一点。大家容我细细道来。

    第一个for循环()里面,让指针p指向values第一个元素的地址,并且p指向的地址<values最后一个元素的地址+1。这样造成什么呢,造成循环5次。

    我们再看循环体内,第一次循环*p++=0,先对p解引用也就是先修改values第一个元素为0后再使p++也就是使p指向地址往前增长1。所以此时p指向的是values数组第二个元素的地址。直到最后p指向的地址超出了values数组最后一个数组元素地址,结束循环。

    第二个for循环就是遍历values数组,依次打印被修改后的values的各个元素值。

    image.gif编辑相信大家对指针加法有了不一样的见解,指针加一就是使指针指向的地址往后增一。因此我可以先解引用当前地址并且修改当前地址值,或者再往后加一等等,可以实现各种您想要的结果。您学会了吗?


    1.2指针减指针

    理解了指针加法,减法也就不难理解了,也就是指针指向的地址往前减一,因此我可以得到上一个元素的地址

    1.3指针关系运算

    指针关系运算是什么意思呢,就是比较两个指针之间的大小。两个指针的大小又用什么衡量呢,用指针指向的地址的大小来衡量。因此我们就不难理解指针关系运算是怎么回事了。

    #include<stdio.h>
    int main()
    {
      int arry[3] = { 1,2,3 };
      int* p1=arry;
      int* p2=arry+1;
      if (p1 > p2)
      {
        *p1 = 0;
      }
      else
      {
        *p2 = 0;
      }
      for (int i = 0; i < 3; i++)
      {
        printf("%d ", arry[i]);
      }
    }

    image.gif

    输出结果:1 0 3

    上述程序很明显定义了p1指向arry数组的首地址,p2指向了arry数组的第二元素地址。因此p1<p2执行了*p2=0。这就是指针的关系运算,判断两个指针指向地址的大小从而进行一些操作。希望大家能够理解。


    2、二级指针

    平常我们定义的指针是一级指针如:int* p=NULL;只有一个*号这就是一个一级指针。那么二级指针就是有两个*号的指针如:int** pp=NULL;二级指针怎么用呢,有一代码:

    #include<stdio.h>
    int main()
    {
      int a = 10;
      int* p = &a;
      int** pp = &p;
      **pp = 20;
      printf("%d\n", a);
      return 0;
    }

    image.gif

    输出结果:20

    上述代码,我来拆分讲解。首先我先定义了一个整型变量a=10、一个一级指针变量p指向a的地址和一个二级指针变量pp指向指针变量p的地址

    指针p存放的是a的地址,二级指针pp存放的是指针p的地址。然后对pp进行双解引用并把20赋值给双解引用后的pp,从而修改了a的值。结合下图来理解:

    image.gif编辑

    以上地址都是随机的,首先变量a里面存的是10,指针p里面存的是a的地址二级指针pp里面存的是指针p的地址

    指针p可以通过a的地址找到10,那么二级指针pp是不是也能通过指针p的地址找到指针p里面存的a的地址值呢。但是如果我对二级指针pp解引用一次pp指针只能找到a的地址,所以我们解引用两次,就可以得到a了。这就是二级指针的用法。

    有没有三级指针呢,准确来说是有的。指针可以无限套娃也就是可以增长到N级指针,只不过我们平常写代码时顶多用到了二级指针。一般情况没人用到三级和三级以上的指针。


    3、指针和数组

    往期内容我们知道了数组名的地址就是数组首元素地址,以下代码证实这个想法:

    #include<stdio.h>
    int main()
    {
      int arry[3] = { 1,2,3 };
      printf("%p\n", arry);
      printf("%p\n", &arry[0]);
      return 0;
    }

    image.gif

    输出结果

    001AF8F4

    001AF8F4

    可见数组名和数组首元素的地址是一样的。那么我们得出的结论是:数组名表示的是数组首元素的地址


    我们知道数组名是地址,指针变量指向的也是地址。那我们可不可以用指针来修改数组里面的各个值呢?是可以,我们来看一组代码,通过指针实现一个数组里面每个值都增加1:

    #include<stdio.h>
    int main()
    {
      int arry[] = { 1,2,3,4,5 };
      int n = sizeof(arry) / sizeof(arry[0]);
      int* p = arry;
      for (int i = 0; i < n; i++)
      {
          arry[i] = *(p + i) + 1;
      }
      for (int j = 0; j < n; j++)
      {
        printf("%d ", arry[j]);
      }
      return 0;
    }

    image.gif

    输出结果:2 3 4 5 6

    以上结果说明了指针和数组不分家。指针p通过地址依次访问了arry里面的各个元素并使各个元素+1了。这就是指针与数组的关系,您学会了吗?


    4、指针数组

    我们先来玩个文字游戏,指针数组是指针,还是数组呢?答案是数组,就好比好兄弟,好兄弟是好还是兄弟呢,当然是兄弟了。凭啥认为指针数组是数组,我们来看一组代码:

    #include<stdio.h>
    int main()
    {
      int a = 10;
      int b = 11;
      int c = 12;
      int d = 13;
      int* arry[4] = { &a,&b,&c,&d };
      for (int i = 0; i < 4; i++)
      {
        printf("%d ", *arry[i]);
      }
      return 0;
    }

    image.gif

    输出结果

    10 11 12 13

    上述代码,arry是一个数组,有四个元素,每个元素是一个整型指针。arry数组里面的指针依次对应着abcd四个值的地址。因此我们认为指针数组就是一个数组。

    image.gif编辑


    有一代码,使用一维数组模拟一个三行四列的二维数组:

    #include<stdio.h>
    int main()
    {
      int a[4] = { 2,3,4,5 };
      int b[4] = { 6,7,8,9 };
      int c[4] = { 10,11,12,13 };
      int* arry[3] = { a,b,c };
      for (int i = 0; i < 3; i++)
      {
        for (int j = 0; j < 4; j++)
        {
          printf("%d ", arry[i][j]);
        }
        printf("\n");
      }
      return 0;
    }

    image.gif

    输出结果

    2 3 4

    5 6 7

    8 9 10

    image.gif编辑

    我们已经知道了,数组名就是地址。那么把分别把a、b、c三个数组的数组名存放在指针数组arry里面,这样我们就可以通过这三个数组名访问到各个数组的元素。以上方法使用指针数组实现了一维数组组成二维数组。


    所有初识指针内容到这里就结束了,感谢您的观看。

    image.gif编辑

    Never Give Up

    相关文章
    |
    3月前
    |
    C语言
    【c语言】指针就该这么学(1)
    本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
    64 0
    |
    1月前
    |
    存储 NoSQL 编译器
    【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
    指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
    96 3
    【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
    |
    1月前
    |
    存储 编译器 C语言
    【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
    在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
    61 9
    |
    1月前
    |
    安全 程序员 C语言
    【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
    在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
    47 7
    |
    2月前
    |
    存储 C语言
    C语言如何使用结构体和指针来操作动态分配的内存
    在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
    183 13
    |
    2月前
    |
    存储 C语言 开发者
    C 语言指针与内存管理
    C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
    68 11
    |
    2月前
    |
    存储 程序员 编译器
    C 语言数组与指针的深度剖析与应用
    在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
    |
    2月前
    |
    算法 C语言
    C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
    本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
    150 3
    |
    2月前
    |
    存储 算法 程序员
    C 语言指针详解 —— 内存操控的魔法棒
    《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
    |
    2月前
    |
    程序员 C语言
    C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
    C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
    45 1