指针(一)
- “带*类型” 的特征探测:宽度
- “带*类型” 的特征探测:声明
- “带*类型” 的特征探测:赋值
- “带*类型” 的特征探测:++ --
- “带*类型” 的特征探测:加上/减去 一个整数
- “带*类型” 的特征探测:求差值
- “带*类型” 的特征探测:比较
对于一个变量来说,最重要的一个特征就是数据的宽度,如何探测某个类型的变量的宽度?
答:我们可以用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 }
总结:
带*的变量,如果类型相同,可以做大小的比较。