• C语言、指针(一)


    指针(一)

    •   “带*类型” 的特征探测:宽度
    •   “带*类型” 的特征探测:声明
    •   “带*类型” 的特征探测:赋值
    •   “带*类型” 的特征探测:++ --
    •   “带*类型” 的特征探测:加上/减去 一个整数
    •   “带*类型” 的特征探测:求差值
    •   “带*类型” 的特征探测:比较

      对于一个变量来说,最重要的一个特征就是数据的宽度,如何探测某个类型的变量的宽度?

      答:我们可以用sizeof,当然最好我们是看反汇编看他到底分配几个字节。

    1、“带*类型” 的如何声明?

      如何声明char/short/int类型的变量呢?

     1 char x;                
     2                 
     3 short y;                
     4                 
     5 int z;                
     6                 
     7 float f;                
     8                 
     9 double d;                
    10                 
    11 struct Student                
    12 {                
    13     int level;            
    14     char name[20];            
    15 };                
    16                 
    17 Student st;                

      声明带有*类型的变量

       

         

       总结: 

      1、带有*的变量类型的标准写法:变量类型* 变量名

      2、任何类型都可以带* 加上*以后是新的类型

      3、*可以是任意多个

    2、“带*类型” 的特征探测:赋值

    char、short、int 类型变量的赋值:

       

     1 #include "stdafx.h"
     2 
     3 struct point
     4 {
     5     int a;
     6     char arr[10];
     7 };
     8 
     9 void function()
    10 {
    11     char a;
    12     short b;
    13     int c;
    14 
    15     a = 1;
    16     b = 2;
    17     c = 3;
    18 
    19 }
    20 
    21 int main(int argc, char* argv[])
    22 {
    23     function();
    24     
    25     return 0;
    26 }

      反汇编代码如下:

       

       从 mov byte ptr ds:[ebp-4],1

      mov word ptr ds:[ebp-8],2。不难看出char占1个字节,short占2个字节,int占四个字节,但是从反汇编代码中可以看出,虽然char占1个字节,short占2个字节,但是编译器为它分配内存的时候,依旧是分配了4个字节

    带*类型的变量的赋值:

       

     1 #include "stdafx.h"
     2 
     3 struct point
     4 {
     5     int a;
     6     char arr[10];
     7 };
     8 
     9 void function()
    10 {
    11     char* a;
    12     short* b;
    13     int* c;
    14 
    15     a = (char*)1;
    16     b = (short*)2;
    17     c = (int*)3;
    18 
    19 }
    20 
    21 int main(int argc, char* argv[])
    22 {
    23     function();
    24     
    25     return 0;
    26 }

       

       从这段反汇编代码看出,这与普通变量的赋值毫无差别,说明仅仅从汇编角度,编译器是不识别你什么指针不指针的。

      我们再来看看带两颗*的情况

     1 #include "stdafx.h"
     2 
     3 struct point
     4 {
     5     int a;
     6     char arr[10];
     7 };
     8 
     9 void function()
    10 {
    11     char** a;
    12     short** b;
    13     int** c;
    14 
    15     a = (char**)1;
    16     b = (short**)2;
    17     c = (int**)3;
    18 
    19 }
    20 
    21 int main(int argc, char* argv[])
    22 {
    23     function();
    24     
    25     return 0;
    26 }

      再观察带两个*的变量的反汇编

       可以看出与带一个*的反汇编代码一毛一样

      我们再来看看多颗*的情况,这回我下了一剂猛药,直接来十颗*!

     1 #include "stdafx.h"
     2 
     3 struct point
     4 {
     5     int a;
     6     char arr[10];
     7 };
     8 
     9 void function()
    10 {
    11     char********* a;
    12     short********* b;
    13     int********* c;
    14 
    15     a = (char*********)1;
    16     b = (short*********)2;
    17     c = (int*********)3;
    18 
    19 }
    20 
    21 int main(int argc, char* argv[])
    22 {
    23     function();
    24     
    25     return 0;
    26 }

      观察反汇编代码如下!

       

      看到这,你可能会怀疑我是不是压根没看反汇编代码,而是直接把上面的复制过来了 ,如果不是复制过来的,那为毛他们反汇编代码一毛一样,一个符号都没有改呢?其实在反汇编里头,无论你是带有几颗*,一律只占(4)dword字节

    再探数据的宽度:

       

      赋值+探测宽度我一并做过了,这个就不写了

      总结:

      1、带*类型的变量赋值时只能使用“完整写法”.

      2、带*类型的变量宽度永远是4字节、无论类型是什么,无论有几个*.

    3、“带*类型” 的特征探测:++ --

      由于加法与减法是一样的,我这里只做加法的演示!!!

    char、short、int类型:

        

     1 #include "stdafx.h"
     2 
     3 struct point
     4 {
     5     int a;
     6     char arr[10];
     7 };
     8 
     9 void function()
    10 {
    11     char a ;            
    12     short b ;            
    13     int c ;            
    14     
    15     a = 100;            
    16     b = 100;            
    17     c = 100;            
    18     
    19     a++;            
    20     b++;            
    21     c++;            
    22     
    23     printf("%d %d %d",a,b,c);            
    24 
    25 }
    26 
    27 int main(int argc, char* argv[])
    28 {
    29     function();
    30     
    31     return 0;
    32 }

       打印的结果如下:

     ·  

     带*类型

      算了,为了合理演示,这里不适合从1颗*到多颗*,得反过来,得从多颗*到1颗*演示才好

      1、带多颗*的类型

     1 #include "stdafx.h"
     2 
     3 struct point
     4 {
     5     int a;
     6     char arr[10];
     7 };
     8 
     9 void function()
    10 {
    11     char********** a ;        
    12     short********** b ;        
    13     int********** c ;        
    14     
    15     a = (char**********)100;        
    16     b = (short**********)100;        
    17     c = (int**********)100;        
    18     
    19     a++;        
    20     b++;        
    21     c++;        
    22     
    23     printf("%d
     %d
     %d
    ",a,b,c);        
    24 }
    25 
    26 int main(int argc, char* argv[])
    27 {
    28     function();
    29     
    30     return 0;
    31 }

      打印结果如下:

       

       2、带两颗*的类型

     1 #include "stdafx.h"
     2 
     3 struct point
     4 {
     5     int a;
     6     char arr[10];
     7 };
     8 
     9 void function()
    10 {
    11     char** a ;        
    12     short** b ;        
    13     int** c ;        
    14     
    15     a = (char**)100;        
    16     b = (short**)100;        
    17     c = (int**)100;        
    18     
    19     a++;        
    20     b++;        
    21     c++;        
    22     
    23     printf("%d
    %d
    %d
    ",a,b,c);        
    24 }
    25 
    26 int main(int argc, char* argv[])
    27 {
    28     function();
    29     
    30     return 0;
    31 }

      打印结果如下:

       

        3、带一颗*的类型

      来了来了,重点在这!!!

     1 #include "stdafx.h"
     2 
     3 struct point
     4 {
     5     int a;
     6     char arr[10];
     7 };
     8 
     9 void function()
    10 {
    11     char* a ;        
    12     short* b ;        
    13     int* c ;        
    14     
    15     a = (char*)100;        
    16     b = (short*)100;        
    17     c = (int*)100;        
    18     
    19     a++;        
    20     b++;        
    21     c++;        
    22     
    23     printf("%d
    %d
    %d
    ",a,b,c);        
    24 }
    25 
    26 int main(int argc, char* argv[])
    27 {
    28     function();
    29     
    30     return 0;
    31 }

      打印结果如下:

       

       注意看了,结果跟上面不一样了哦!

      做加法或者减法运算时,带*类型会在自身具体多少颗*的基础上,会砍掉一颗*做加法,减法

      还记得前面说的类型宽度吗?任何带*类型,它的宽度都是4字节,两颗*以上的,砍掉一颗*,他还是带*类型,只有是带一颗*的类型,他做加减的时候,砍掉一颗*就跟普通变量是一样的了

      总结:

      1、不带*类型的变量,++或者-- 都是假1 或者减1

      2、带*类型的变量,可是进行++ 或者 --的操作

      3、带*类型的变量,++ 或者 -- 新增(减少)的数量是去掉一个*后变量的宽度

    4、“带*类型” 的特征探测:加上/减去 一个整数

      带一颗*的类型

     1 #include "stdafx.h"
     2 
     3 struct point
     4 {
     5     int a;
     6     char arr[10];
     7 };
     8 
     9 void functionAdd()
    10 {
    11     char* a ;        
    12     short* b ;        
    13     int* c ;        
    14     
    15     a = (char*)100;        
    16     b = (short*)100;        
    17     c = (int*)100;        
    18     
    19     a = a + 5;        
    20     b = b + 5;        
    21     c = c + 5;        
    22     
    23     printf("%d %d %d
    ",a,b,c);
    24 }
    25 void functionSub()
    26 {
    27     char* a ;        
    28     short* b ;        
    29     int* c ;        
    30     
    31     a = (char*)100;        
    32     b = (short*)100;        
    33     c = (int*)100;    
    34 
    35     a = a - 5;        
    36     b = b - 5;        
    37     c = c - 5;    
    38     printf("%d %d %d
    ",a,b,c);
    39 }
    40 
    41 int main(int argc, char* argv[])
    42 {
    43     functionAdd();
    44     functionSub();
    45     
    46     return 0;
    47 }

      打印结果如下:

       

       带两颗*的呢?

     1 #include "stdafx.h"
     2 
     3 void functionAdd()
     4 {
     5     char** a ;        
     6     short** b ;        
     7     int** c ;        
     8     
     9     a = (char**)100;        
    10     b = (short**)100;        
    11     c = (int**)100;        
    12     
    13     a = a + 5;        
    14     b = b + 5;        
    15     c = c + 5;        
    16     
    17     printf("%d %d %d
    ",a,b,c);
    18 }
    19 void functionSub()
    20 {
    21     char** a ;        
    22     short** b ;        
    23     int** c ;        
    24     
    25     a = (char**)100;        
    26     b = (short**)100;        
    27     c = (int**)100;    
    28 
    29     a = a - 5;        
    30     b = b - 5;        
    31     c = c - 5;    
    32     printf("%d %d %d
    ",a,b,c);
    33 }
    34 
    35 int main(int argc, char* argv[])
    36 {
    37     functionAdd();
    38     functionSub();
    39     
    40     return 0;
    41 }

      打印结果如下:

       

      带很多*的情况呢?

     1 #include "stdafx.h"
     2 
     3 void functionAdd()
     4 {
     5     char********** a ;        
     6     short********** b ;        
     7     int********** c ;        
     8     
     9     a = (char**********)100;        
    10     b = (short**********)100;        
    11     c = (int**********)100;        
    12     
    13     a = a + 5;        
    14     b = b + 5;        
    15     c = c + 5;        
    16     
    17     printf("%d %d %d
    ",a,b,c);
    18 }
    19 void functionSub()
    20 {
    21     char********** a ;        
    22     short********** b ;        
    23     int********** c ;        
    24     
    25     a = (char**********)100;        
    26     b = (short**********)100;        
    27     c = (int**********)100;    
    28 
    29     a = a - 5;        
    30     b = b - 5;        
    31     c = c - 5;    
    32     printf("%d %d %d
    ",a,b,c);
    33 }
    34 
    35 int main(int argc, char* argv[])
    36 {
    37     functionAdd();
    38     functionSub();
    39     
    40     return 0;
    41 }

       打印结果如下:

       

      总结:

      1、带*类型的变量可以加、减一个整数,但不能乘或者除.

      2、带*类型变量与其他整数相加或者相减时:

      带*类型变量 + N = 带*类型变量 + N*(去掉一个*后类型的宽度)

      带*类型变量 - N = 带*类型变量 - N*(去掉一个*后类型的宽度)

    5、“带*类型” 的特征探测:求差值

      有点累了,就都写一块了,如果读者有心,建议后面的步骤,都如同上面的步骤一样,从char、short、int、__int64、结构体带*变量都试试,从一颗*到多颗*,都试试

      注意:只允许两个带星(*)类型做减法,不允许两个都带星(*)的类型相加,但是带星类型对整数类型可以做加减。

      希望各位看我博客的各位,不要记这些啊,这些都不用记得,你如果要说这么多内容不记住怎么懂呢?其实,你只需要按照我这个顺序,从char、short、int、__int64、数组,结构体定义变量,求宽度,做加减,作比较

      再到char、short、int、__int64、数组,结构体带一颗星的声明一个变量,求宽度、做加减,作比较

      再到char、short、int、__int64、数组,结构体带多颗星的声明一个变量,求宽度,做加减作比较,就自然懂了

       

     1 #include "stdafx.h"
     2 
     3 void CharOnePoint()
     4 {
     5     char* a ;    
     6     char* b ;    
     7     
     8     a = (char*)200;    
     9     b = (char*)100;    
    10         
    11     int x = a - b;    
    12     
    13     printf("%d
    ",x);    
    14 }
    15 
    16 void ShortOnePoint()
    17 {
    18     short* a ;    
    19     short* b ;    
    20     
    21     a = (short*)200;    
    22     b = (short*)100;    
    23         
    24     int x = a - b;    
    25     
    26     printf("%d
    ",x);    
    27 }
    28 
    29 void IntOnePoint()
    30 {
    31     int* a ;    
    32     int* b ;    
    33     
    34     a = (int*)200;    
    35     b = (int*)100;    
    36         
    37     int x = a - b;    
    38     
    39     printf("%d
    ",x);    
    40 }
    41 
    42 void CharMorePoint()
    43 {
    44     char********** a ;    
    45     char********** b ;    
    46     
    47     a = (char**********)200;    
    48     b = (char**********)100;    
    49     
    50     int x = a - b;    
    51     
    52     printf("%d
    ",x);    
    53 }
    54 
    55 void ShortMorePoint()
    56 {
    57     short********** a ;    
    58     short********** b ;    
    59     
    60     a = (short**********)200;    
    61     b = (short**********)100;    
    62     
    63     int x = a - b;    
    64     
    65     printf("%d
    ",x);    
    66 }
    67 
    68 void IntMorePoint()
    69 {
    70     int********** a ;    
    71     int********** b ;    
    72     
    73     a = (int**********)200;    
    74     b = (int**********)100;    
    75     
    76     int x = a - b;    
    77     
    78     printf("%d
    ",x);    
    79 }
    80 
    81 int main(int argc, char* argv[])
    82 {
    83     CharOnePoint();
    84     ShortOnePoint();
    85     IntOnePoint();
    86     printf("
    
    
    ");
    87     CharMorePoint();
    88     ShortMorePoint();
    89     IntMorePoint();
    90     
    91     return 0;
    92 }

       

       

      总结:

      1、两个类型相同的带*类型的变量可以进行减法操作.

      2、想减的结果要除以去掉一个*的数据的宽度.

    6、“带*类型” 的特征探测:比较

     1 #include "stdafx.h"
     2 
     3 void function()
     4 {
     5     char**** a ;            
     6     char**** b ;            
     7     
     8     a = (char****)200;            
     9     b = (char****)100;                
    10     
    11     if(a>b)            
    12     {            
    13         printf("1
    ");        
    14     }            
    15     else            
    16     {            
    17         printf("2
    ");        
    18     }            
    19 
    20 }
    21 
    22 int main(int argc, char* argv[])
    23 {
    24     function();
    25     
    26     return 0;
    27 }

       

      总结:

      带*的变量,如果类型相同,可以做大小的比较。

  • 相关阅读:
    springboot属性类自动加载配置文件中的值
    mysql修改root密码
    idea各种图标说明
    nginx安装配置
    notepad++下载32位,安装插件管理
    crontab 定时执行脚本出错,但手动执行脚本正常
    jenkins安装配置
    VirtualBox从USB设备(PE)启动图文教程
    如何卸载windows的服务?卸载服务?
    在Windows的CMD中如何设置支持UTF8编码?
  • 原文地址:https://www.cnblogs.com/Reverse-xiaoyu/p/11723866.html
Copyright © 2020-2023  润新知