reverse_xiaoyu

忘记并不可怕,可怕的是你从来就都不知道!

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

指针(一)

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

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

  答:我们可以用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\n %d\n %d\n",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\n%d\n%d\n",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\n%d\n%d\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n",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\n",x);    
79 }
80 
81 int main(int argc, char* argv[])
82 {
83     CharOnePoint();
84     ShortOnePoint();
85     IntOnePoint();
86     printf("\n\n\n");
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\n");        
14     }            
15     else            
16     {            
17         printf("2\n");        
18     }            
19 
20 }
21 
22 int main(int argc, char* argv[])
23 {
24     function();
25     
26     return 0;
27 }

 

   

  总结:

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

posted on 2019-10-29 16:41  Reverse-xiaoyu  阅读(325)  评论(0编辑  收藏  举报