zoukankan      html  css  js  c++  java
  • 10深入理解C指针之---指针运算和比较

      该系列文章源于《深入理解C指针》的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教。

      指针运算有很多种,主要有指针的声明*、指针的解引*、指针指向(*).或->、指针+、指针-、指针==、指针!=、指针>、指针>=、指针<、指针<=、指针转换(数据类型)。

      通过代码:  

     1 #include <stdio.h>
     2 
     3 int main(int argc, char **argv)
     4 {
     5     char charVar;                                                        
     6     short shortVar;
     7     int intVar;
     8     long longVar;
     9     float floatVar;
    10     double doubleVar;
    11     
    12     printf("不同数据类型的长度如下:
    ");
    13     printf("数据类型		长度(字节)
    ");
    14     printf("char			 %d
    ", sizeof(charVar));
    15     printf("short			 %d
    ", sizeof(shortVar));
    16     printf("int			 %d
    ", sizeof(intVar));
    17     printf("long			 %d
    ", sizeof(longVar));
    18     printf("float			 %d
    ", sizeof(floatVar));
    19     printf("double			 %d
    ", sizeof(doubleVar));
    20     
    21     return 0;
    22 }

      代码结果:

    不同数据类型的长度如下:
    数据类型                长度(字节)
    char                         1
    short                        2
    int                          4
    long                         8
    float                        4
    double                       8    

      不同系统的基本数据类型可能稍微不同,请自己测试。知道自己系统的基本数据类型的大小之后,就可以继续学习下面的内容了,指针的声明和解引,前面已经学习过,下面主要进行其他部分。

      一、指针指向->:用于访问结构指针引用的字段内容,是(*).的简化版本而已,

        1、定义:可以通过指针方便快捷的访问结构的字段,而且书写更加简单方便,可以减少两次敲击键盘的次数

        2、特征:

          1)、使用前需要声明结构体

          2)、使用前需要声明结构体指针      

          3)、可以使用->指针指向访问结构体指针的字段

          4)、也可以使用(*).解引指针和成员运算符访问结构体指针的字段

        3、应用:

          1)、结构体的声明方式是非常多样化的,不同的声明方式,使用方式略有不同

          2)、使用结构体指针需要先分配内存

          3)、如果结构体中含有指针,需要二次分配内存

          4)、如果结构体中含有指针,释放内存顺序与分配内存顺序完全相反

      代码如下:代码很简单,仔细阅读即可:  

      1 #include <stdio.h>                                                                                                                                                                                                                                                                                                                         
      2 #include <string.h>
      3 #include <stdlib.h>
      4 
      5 int main(int argc, char **argv)
      6 {
      7     //结构体的普通声明
      8     struct _person{
      9         char* firstName;
     10         char* lastName;
     11         char* title;
     12         int age;
     13     };
     14     struct _person* person1;
     15     person1 = (struct _person*)malloc(sizeof(struct _person));
     16     (*person1).firstName = (char*)malloc(sizeof(char) * 20);
     17     strcpy((*person1).firstName, "zhang");
     18     (*person1).lastName = (char*)malloc(sizeof(char) * 30);
     19     strcpy((*person1).lastName, "san");
     20     (*person1).title = (char*)malloc(sizeof(char) * 100);
     21     strcpy((*person1).title, "A");
     22     (*person1).age = 29;
     23 
     24     printf("The struct _person *person1 info:
    ");
     25     printf("(*person1).firstName: %s
    ", (*person1).firstName);
     26     printf("(*person1).lastName: %s
    ", (*person1).lastName);
     27     printf("(*person1).title: %s
    ", (*person1).title);
     28     printf("(*person1).age: %d
    ", (*person1).age);
     29     
     30     free((*person1).firstName);
     31     free((*person1).lastName);
     32     free((*person1).title);
     33     free(person1);
     34 
     35     struct _person* person2;
     36     person2 = (struct _person*)malloc(sizeof(struct _person));
     37     person2->firstName = (char*)malloc(sizeof(char) * 20);
     38     strcpy(person2->firstName, "li");
     39     person2->lastName = (char*)malloc(sizeof(char) * 30);
     40     strcpy(person2->lastName, "si");
     41     person2->title = (char*)malloc(sizeof(char) * 100);
     42     strcpy(person2->title, "B");
     43     person2->age = 21;
     44 
     45     printf("The struct _person *person2 info:
    ");
     46     printf("person2->firstName: %s
    ", person2->firstName);
     47     printf("person2->lastName: %s
    ", person2->lastName);
     48     printf("person2->title: %s
    ", person2->title);
     49     printf("person2->age: %d
    ", person2->age);
     50     
     51     free(person2->firstName);
     52     free(person2->lastName);
     53     free(person2->title);
     54     free(person2);
     55 
     56     //结构体的高级声明,声明方式不一样,使用方式稍微有点不同
     57     typedef struct _personNew{
     58         char* firstName;
     59         char* lastName;
     60         char* title;
     61         int age;
     62     } Person;
     63 
     64     Person* person3;
     65     person3 = (Person*)malloc(sizeof(Person));
     66     (*person3).firstName = (char*)malloc(sizeof(char) * 20);
     67     strcpy((*person3).firstName, "wang");
     68     (*person3).lastName = (char*)malloc(sizeof(char) * 30);
     69     strcpy((*person3).lastName, "wu");
     70     (*person3).title = (char*)malloc(sizeof(char) * 100);
     71     strcpy((*person3).title, "C");
     72     (*person3).age = 29;
     73 
     74     printf("The struct _person *person3 info:
    ");
     75     printf("(*person3).firstName: %s
    ", (*person3).firstName);
     76     printf("(*person3).lastName: %s
    ", (*person3).lastName);
     77     printf("(*person3).title: %s
    ", (*person3).title);
     78     printf("(*person3).age: %d
    ", (*person3).age);
     79 
     80     free((*person3).firstName);
     81     free((*person3).lastName);
     82     free((*person3).title);
     83     free(person3);
     84 
     85     Person* person4;
     86     person4 = (Person*)malloc(sizeof(Person));
     87     person4->firstName = (char*)malloc(sizeof(char) * 20);
     88     strcpy(person4->firstName, "zhao");
     89     person4->lastName = (char*)malloc(sizeof(char) * 30);
     90     strcpy(person4->lastName, "liu");
     91     person4->title = (char*)malloc(sizeof(char) * 100);
     92     strcpy(person4->title, "D");
     93     person4->age = 21;
     94 
     95     printf("The struct _person *person4 info:
    ");
     96     printf("person4->firstName: %s
    ", person4->firstName);
     97     printf("person4->lastName: %s
    ", person4->lastName);
     98     printf("person4->title: %s
    ", person4->title);
     99     printf("person4->age: %d
    ", person4->age);
    100 
    101     free(person4->firstName);
    102     free(person4->lastName);
    103     free(person4->title);
    104     free(person4);
    105 
    106     typedef struct _personNewN{
    107         char* firstName;
    108         char* lastName;
    109         char* title;
    110         int age;
    111     } *PersonN;
    112 
    113     PersonN person5;
    114     person5 = (PersonN)malloc(sizeof(PersonN));
    115     (*person5).firstName = (char*)malloc(sizeof(char) * 20);
    116     strcpy((*person5).firstName, "zhou");
    117     (*person5).lastName = (char*)malloc(sizeof(char) * 30);
    118     strcpy((*person5).lastName, "qi");
    119     (*person5).title = (char*)malloc(sizeof(char) * 100);
    120     strcpy((*person5).title, "E");
    121     (*person5).age = 29;
    122 
    123     printf("The struct _person *person5 info:
    ");
    124     printf("(*person5).firstName: %s
    ", (*person5).firstName);
    125     printf("(*person5).lastName: %s
    ", (*person5).lastName);
    126     printf("(*person5).title: %s
    ", (*person5).title);
    127     printf("(*person5).age: %d
    ", (*person5).age);
    128 
    129     free((*person5).firstName);
    130     free((*person5).lastName);
    131     free((*person5).title);
    132     free(person5);
    133 
    134     PersonN person6;
    135     person6 = (PersonN)malloc(sizeof(PersonN));
    136     person6->firstName = (char*)malloc(sizeof(char) * 20);
    137     strcpy(person6->firstName, "wu");
    138     person6->lastName = (char*)malloc(sizeof(char) * 30);
    139     strcpy(person6->lastName, "ba");
    140     person6->title = (char*)malloc(sizeof(char) * 100);
    141     strcpy(person6->title, "F");
    142     person6->age = 21;
    143 
    144     printf("The struct _person *person6 info:
    ");
    145     printf("person6->firstName: %s
    ", person6->firstName);
    146     printf("person6->lastName: %s
    ", person6->lastName);
    147     printf("person6->title: %s
    ", person6->title);
    148     printf("person6->age: %d
    ", person6->age);
    149 
    150     free(person6->firstName);
    151     free(person6->lastName);
    152     free(person6->title);
    153     free(person6);
    154 
    155     return 0;
    156 }                                                                                                                                                                                                                                                                                                                                   
    ~        

      代码结果:

    The struct _person *person1 info:
    (*person1).firstName: zhang
    (*person1).lastName: san
    (*person1).title: A
    (*person1).age: 29
    The struct _person *person2 info:
    person2->firstName: li
    person2->lastName: si
    person2->title: B
    person2->age: 21
    The struct _person *person3 info:
    (*person3).firstName: wang
    (*person3).lastName: wu
    (*person3).title: C
    (*person3).age: 29
    The struct _person *person4 info:
    person4->firstName: zhao
    person4->lastName: liu
    person4->title: D
    person4->age: 21
    The struct _person *person5 info:
    (*person5).firstName: zhou
    (*person5).lastName: qi
    (*person5).title: E
    (*person5).age: 29
    The struct _person *person6 info:
    person6->firstName: wu
    person6->lastName: ba
    person6->title: F
    person6->age: 21

      通过以上代码,相比阅读者对数据结构有了比较深刻的认识吧。有人可能会想到鲁迅笔下的孔乙己吧,这种做法会不会有茴香豆的茴字有四种写法的卖弄,如果这样想就错了,编程过程中,会碰到各种奇怪的应用场景,每一种用法都要学习点,以备不时之需吧。代码阅读完毕了,相比读者对使用->指针指向访问结构体指针的字段和使用(*).解引指针和成员运算符访问结构体指针的字段有了比较深入的理解了。

      二、指针+和指针-:用于访问数组下表对应的内容,

        1、定义:可以通过对指针进行简单的加减法,这点同普通变量一样,但是计算机的体现又是不一样的

        2、特征:

          1)、指针+和指针-的大小与加减的数值有关

          2)、指针+和指针-的大小与指针的数据类型有关      

          3)、指针+和指针-的最终大小就是加减的数值与数据类型的大小的乘积

          4)、不同的指针的指针+和指针-的大小是复杂的,要特别注意

          5)、void类型的指针最好不要作加减操作

        3、应用:

          见如下代码:

      代码如下:

     1 #include <stdio.h>
     2
     3 int main(int argc, char **argv)
     4 {
     5     int iArray[] = {28, 32, 89, 77};
     6     int *ptrArray = iArray;
     7
     8     //普通数组的访问
     9     printf("The iArray: ");
    10     for(int i = 0; i < 4; i++){
    11         printf("%d ", iArray[i]);
    12     }
    13     printf(" ");
    14
    15     //普通数组的特殊访问
    16     printf("The Other iArray: ");
    17     for(int i = 0; i < 4; i++){
    18         printf("%d ", i[iArray]);
    19     }
    20     printf(" ");
    21
    22     //普通数组的指针访问
    23     printf("The Pointer+ iArray: ");
    24     for(int i = 0; i < 4; i++){
    25         printf("%d ", *ptrArray);
    26         ptrArray += 1;
    27     }
    28     printf(" ");
    29
    30     printf("The Pointer- iArray: ");
    31     for(int i = 0; i < 4; i++){
    32         ptrArray -= 1;                                                   
    33         printf("%d ", *ptrArray);
    34     }
    35     printf(" ");
    36
    37     return 0;
    38 }

      代码结果:

    The iArray:
    28      32      89      77
    The Other iArray:
    28      32      89      77
    The Pointer+ iArray:
    28      32      89      77
    The Pointer- iArray:
    77      89      32      28

      代码中的26行使用了指针+操作,32行使用了指针-操作,由于指针是int型,因此,指针每增加或减少1,地址都会增加或减少整型数据的长度4。将指针值打印出来,在25行和33行下面增加如下:  

    printf("%p	", ptrArray);

      则代码结果为:

    The iArray:
    28      32      89      77
    The Other iArray:
    28      32      89      77
    The Pointer+ iArray:
    28      0x7ffd8b190ed0  32      0x7ffd8b190ed4  89      0x7ffd8b190ed8  77      0x7ffd8b190edc
    The Pointer- iArray:
    77      0x7ffd8b190edc  89      0x7ffd8b190ed8  32      0x7ffd8b190ed4  28      0x7ffd8b190ed0

      三、指针相减和指针比较:主要是方便定位两个指针对应的数组元素的先后顺序,

        1、定义:可以通过对指针进行简单的加减法,这点同普通变量一样,但是计算机的体现又是不一样的

        2、特征:

          1)、指针 - 指针的结果是两个地址的差值,利用该差值可以很容易判别数组中的元素的顺序

          2)、指针+和指针-的大小与指针的数据类型有关      

          3)、指针与指针的比较确定指针对应数组元素的相对顺序

          4)、指针相减的结果大于0表示前者指针的值大于后者指针

          5)、指针比较的结果1为真,0为假

        3、应用:

          见如下代码:

      代码如下:

     1 #include <stdio.h>                                                                                                  
     2 
     3 int main(int argc, char **argv)
     4 {
     5     int iArray[] = {28, 32, 89, 77,};
     6     int *ptr0Array = iArray;
     7     int *ptr1Array = iArray + 1;
     8     int *ptr2Array = iArray + 2;
     9     int *ptr3Array = iArray + 3;
    10 
    11     printf("指针减法演示:
    ");
    12     printf("ptr3Array - ptr1Array: %d
    ", ptr3Array - ptr1Array);
    13     printf("ptr1Array - ptr3Array: %d
    ", ptr1Array - ptr3Array);
    14 
    15     printf("指针比较演示:
    ");
    16     printf("ptr3Array > ptr1Array: %d
    ", ptr3Array > ptr1Array);
    17     printf("ptr1Array > ptr3Array: %d
    ", ptr1Array > ptr3Array);
    18 
    19     return 0;
    20 }

      代码结果:

    指针减法演示:
    ptr3Array - ptr1Array: 2
    ptr1Array - ptr3Array: -2
    指针比较演示:
    ptr3Array > ptr1Array: 1
    ptr1Array > ptr3Array: 0

      代码比较简单,就不再啰嗦了。

  • 相关阅读:
    2020年“3D视觉工坊”视频号最受欢迎视频 Top 10!
    缓存一致性解决方案杂谈
    Mybatis的@Param注解在多参数时候不写,可以正确执行。
    Redis设计与实现之简单动态字符串
    YApi mac上部署
    拖拽方式生成Vue用户界面
    终于可以愉快的撸Java异步代码了!
    Windows 取证之ShellBags
    初识Fastjson漏洞(环境搭建及漏洞复现)
    mongo-express 远程代码执行漏洞分析
  • 原文地址:https://www.cnblogs.com/guochaoxxl/p/6952724.html
Copyright © 2011-2022 走看看