相关练习和测试代码
C指针 1."带*类型" 的特征探测:宽度 宽度探测 带一个*的探测 源代码 #include "stdafx.h" #include <string.h> void fun() { char* a = (char*)1; short* b = (short*)2; int* c =(int*)3; printf("%d %d %d ",a,b,c); } int main(int argc, char* argv[]) { fun(); return 0; } 反汇编代码 9: char* a = (char*)1; 0040B818 mov dword ptr [ebp-4],1 10: short* b = (short*)2; 0040B81F mov dword ptr [ebp-8],2 11: int* c =(int*)3; 0040B826 mov dword ptr [ebp-0Ch],3 上述显示都是站4个字节 带两个*的探测 源代码 #include "stdafx.h" #include <string.h> void fun() { char** a = (char**)1; short** b = (short**)2; int** c =(int**)3; printf("%d %d %d ",a,b,c); } int main(int argc, char* argv[]) { fun(); return 0; } 反汇编代码 9: char** a = (char**)1; 0040B818 mov dword ptr [ebp-4],1 10: short** b = (short**)2; 0040B81F mov dword ptr [ebp-8],2 11: int** c =(int**)3; 0040B826 mov dword ptr [ebp-0Ch],3 上述显示还是都站4个字节 带两个以上*的探测 源代码 #include "stdafx.h" #include <string.h> void fun() { char******* a = (char*******)1; short******* b = (short*******)2; int******* c =(int*******)3; printf("%d %d %d ",a,b,c); } int main(int argc, char* argv[]) { fun(); return 0; } 反汇编代码 9: char******* a = (char*******)1; 0040B818 mov dword ptr [ebp-4],1 10: short******* b = (short*******)2; 0040B81F mov dword ptr [ebp-8],2 11: int******* c =(int*******)3; 0040B826 mov dword ptr [ebp-0Ch],3 上述显示还是都站4个字节 结论: 不管什么类型,不管带多少个*,她们所站的字节大小都是4个字节; 2."带*类型"的特征探测:声明 上述1题目中已经探测了,任何类型都可以带*,加了*就是新类型,然后可以加很多个* ,而且写法是标准最好推荐的写法是类似:int* x; 这样方便阅读 结论: (1)带有*的变量类型的标准写法:变量类型* 变量名 (2)任何类型都可以带* 加上*以后是新的类型 (3)*可以是任意多个 3."带*类型" 的特征探测:赋值 上述1题目已经探测了,测试赋值操作; 结论: 1.带*类型的变量赋值时只能使用"完整写法". 2.带*类型的变量宽度永远是4字节,无论类型是什么,无论有几个*. 4."带*类型" 的特征探测:++ -- 带一个*的测试 源代码 #include "stdafx.h" #include <string.h> void fun() { char* a; short* b; int* c; a = (char*)100; b = (short*)100; c = (int*)100; a++; b++; c++; printf("%d %d %d ",a,b,c); } int main(int argc, char* argv[]) { fun(); return 0; } 运行结果:101 102 104 反汇编代码 9: char* a; 10: short* b; 11: int* c; 12: 13: a = (char*)100; 0040B818 mov dword ptr [ebp-4],64h 14: b = (short*)100; 0040B81F mov dword ptr [ebp-8],64h 15: c = (int*)100; 0040B826 mov dword ptr [ebp-0Ch],64h 16: 17: 18: a++; 0040B82D mov eax,dword ptr [ebp-4] 0040B830 add eax,1 0040B833 mov dword ptr [ebp-4],eax 19: b++; 0040B836 mov ecx,dword ptr [ebp-8] 0040B839 add ecx,2 0040B83C mov dword ptr [ebp-8],ecx 20: c++; 0040B83F mov edx,dword ptr [ebp-0Ch] 0040B842 add edx,4 0040B845 mov dword ptr [ebp-0Ch],edx 带两个*的测试 #include "stdafx.h" #include <string.h> void fun() { char** a; short** b; int** c; a = (char**)100; b = (short**)100; c = (int**)100; a++; b++; c++; printf("%d %d %d ",a,b,c); } int main(int argc, char* argv[]) { fun(); return 0; } 运行结果:104 104 104 反汇编代码 9: char** a; 10: short** b; 11: int** c; 12: 13: a = (char**)100; 0040B818 mov dword ptr [ebp-4],64h 14: b = (short**)100; 0040B81F mov dword ptr [ebp-8],64h 15: c = (int**)100; 0040B826 mov dword ptr [ebp-0Ch],64h 16: 17: 18: a++; 0040B82D mov eax,dword ptr [ebp-4] 0040B830 add eax,4 0040B833 mov dword ptr [ebp-4],eax 19: b++; 0040B836 mov ecx,dword ptr [ebp-8] 0040B839 add ecx,4 0040B83C mov dword ptr [ebp-8],ecx 20: c++; 0040B83F mov edx,dword ptr [ebp-0Ch] 0040B842 add edx,4 0040B845 mov dword ptr [ebp-0Ch],edx 带两个以上*的测试 源代码 #include "stdafx.h" #include <string.h> void fun() { char********* a; short********* b; int********* c; a = (char*********)100; b = (short*********)100; c = (int*********)100; a++; b++; c++; printf("%d %d %d ",a,b,c); } int main(int argc, char* argv[]) { fun(); return 0; } 反汇编代码 9: char********* a; 10: short********* b; 11: int********* c; 12: 13: a = (char*********)100; 0040B818 mov dword ptr [ebp-4],64h 14: b = (short*********)100; 0040B81F mov dword ptr [ebp-8],64h 15: c = (int*********)100; 0040B826 mov dword ptr [ebp-0Ch],64h 16: 17: 18: a++; 0040B82D mov eax,dword ptr [ebp-4] 0040B830 add eax,4 0040B833 mov dword ptr [ebp-4],eax 19: b++; 0040B836 mov ecx,dword ptr [ebp-8] 0040B839 add ecx,4 0040B83C mov dword ptr [ebp-8],ecx 20: c++; 0040B83F mov edx,dword ptr [ebp-0Ch] 0040B842 add edx,4 0040B845 mov dword ptr [ebp-0Ch],edx 运行结果:104 104 104 结论: 1.不带*类型的变量,++或者-- 都是加1 或者减1 2.带*类型的变量,可是进行++ 或者 --的操作 3.带*类型的变量,++ 或者 -- 新增(减少)的数量是去掉一个*后变量的宽度 5."带*类型" 的特征探测:加上/减去 一个整数 带一个*的测试 源代码 #include "stdafx.h" #include <string.h> void fun() { char* a; short* b; int* c; a = (char*)100; b = (short*)100; c = (int*)100; a = a + 6; b = b + 6; c = c + 6; printf("%d %d %d ",a,b,c); } int main(int argc, char* argv[]) { fun(); return 0; } 运行结果:106 112 124 反汇编代码 9: char* a; 10: short* b; 11: int* c; 12: 13: a = (char*)100; 0040B818 mov dword ptr [ebp-4],64h 14: b = (short*)100; 0040B81F mov dword ptr [ebp-8],64h 15: c = (int*)100; 0040B826 mov dword ptr [ebp-0Ch],64h 16: 17: a = a + 6; 0040B82D mov eax,dword ptr [ebp-4] 0040B830 add eax,6 0040B833 mov dword ptr [ebp-4],eax 18: b = b + 6; 0040B836 mov ecx,dword ptr [ebp-8] 0040B839 add ecx,0Ch 0040B83C mov dword ptr [ebp-8],ecx 19: c = c + 6; 0040B83F mov edx,dword ptr [ebp-0Ch] 0040B842 add edx,18h 0040B845 mov dword ptr [ebp-0Ch],edx 带两个*的测试 源代码 #include "stdafx.h" #include <string.h> void fun() { char** a; short** b; int** c; a = (char**)100; b = (short**)100; c = (int**)100; a = a + 6; b = b + 6; c = c + 6; printf("%d %d %d ",a,b,c); } int main(int argc, char* argv[]) { fun(); return 0; } 运行结果:124 124 124 反汇编代码 9: char** a; 10: short** b; 11: int** c; 12: 13: a = (char**)100; 0040B818 mov dword ptr [ebp-4],64h 14: b = (short**)100; 0040B81F mov dword ptr [ebp-8],64h 15: c = (int**)100; 0040B826 mov dword ptr [ebp-0Ch],64h 16: 17: a = a + 6; 0040B82D mov eax,dword ptr [ebp-4] 0040B830 add eax,18h 0040B833 mov dword ptr [ebp-4],eax 18: b = b + 6; 0040B836 mov ecx,dword ptr [ebp-8] 0040B839 add ecx,18h 0040B83C mov dword ptr [ebp-8],ecx 19: c = c + 6; 0040B83F mov edx,dword ptr [ebp-0Ch] 0040B842 add edx,18h 0040B845 mov dword ptr [ebp-0Ch],edx 带两个以上*的测试 源代码 #include "stdafx.h" #include <string.h> void fun() { char********* a; short********* b; int********* c; a = (char*********)100; b = (short*********)100; c = (int*********)100; a = a + 6; b = b + 6; c = c + 6; printf("%d %d %d ",a,b,c); } int main(int argc, char* argv[]) { fun(); return 0; } 运行结果:124 124 124 反汇编代码 9: char********* a; 10: short********* b; 11: int********* c; 12: 13: a = (char*********)100; 0040B818 mov dword ptr [ebp-4],64h 14: b = (short*********)100; 0040B81F mov dword ptr [ebp-8],64h 15: c = (int*********)100; 0040B826 mov dword ptr [ebp-0Ch],64h 16: 17: a = a + 6; 0040B82D mov eax,dword ptr [ebp-4] 0040B830 add eax,18h 0040B833 mov dword ptr [ebp-4],eax 18: b = b + 6; 0040B836 mov ecx,dword ptr [ebp-8] 0040B839 add ecx,18h 0040B83C mov dword ptr [ebp-8],ecx 19: c = c + 6; 0040B83F mov edx,dword ptr [ebp-0Ch] 0040B842 add edx,18h 0040B845 mov dword ptr [ebp-0Ch],edx 结论: 1.带*类型的变量可以加、减一个整数,但不能乘或者除. 2.带*类型变量与其他整数相加或者相减时: 带*类型变量 + N = 带*类型变量 + N*(去掉一个*后类型的宽度) 带*类型变量 - N = 带*类型变量 - N*(去掉一个*后类型的宽度) 所以计算结果就是:带*变量的值加上或者减去去掉一个*之后的类型宽度乘以一个整数; 例如: 上面测试加法的时候,两个以上*的计算操作:100+4x6=124 上面测试减法的时候,两个以上*的计算操作:100-4x6=76 6."带*类型" 的特征探测:求差值 带一个*的测试 源代码 #include "stdafx.h" #include <string.h> void fun() { char* a; char* b; a = (char*)200; b = (char*)100; int c = a - b; printf("%d ",c); } int main(int argc, char* argv[]) { fun(); return 0; } 运行结果:100 反汇编代码 9: char* a; 10: char* b; 11: 12: a = (char*)200; 0040B818 mov dword ptr [ebp-4],0C8h 13: b = (char*)100; 0040B81F mov dword ptr [ebp-8],64h 14: 15: int c = a - b; 0040B826 mov eax,dword ptr [ebp-4] 0040B829 sub eax,dword ptr [ebp-8] 0040B82C mov dword ptr [ebp-0Ch],eax 带两个*的测试 源代码 #include "stdafx.h" #include <string.h> void fun() { char** a; char** b; a = (char**)200; b = (char**)100; int c = a - b; printf("%d ",c); } int main(int argc, char* argv[]) { fun(); return 0; } 运行结果:25 反汇编代码 9: char** a; 10: char** b; 11: 12: a = (char**)200; 0040B818 mov dword ptr [ebp-4],0C8h 13: b = (char**)100; 0040B81F mov dword ptr [ebp-8],64h 14: 15: int c = a - b; 0040B826 mov eax,dword ptr [ebp-4] 0040B829 sub eax,dword ptr [ebp-8] 0040B82C sar eax,2 0040B82F mov dword ptr [ebp-0Ch],eax 带两个以上*的测试 源代码 #include "stdafx.h" #include <string.h> void fun() { char************ a; char************ b; a = (char************)200; b = (char************)100; int c = a - b; printf("%d ",c); } int main(int argc, char* argv[]) { fun(); return 0; } 运行结果:25 反汇编代码 9: char************ a; 10: char************ b; 11: 12: a = (char************)200; 0040B818 mov dword ptr [ebp-4],0C8h 13: b = (char************)100; 0040B81F mov dword ptr [ebp-8],64h 14: 15: int c = a - b; 0040B826 mov eax,dword ptr [ebp-4] 0040B829 sub eax,dword ptr [ebp-8] 0040B82C sar eax,2 0040B82F mov dword ptr [ebp-0Ch],eax 结论: 1.两个类型相同的带*类型的变量可以进行减法操作. 2.想减的结果要除以去掉一个*的数据的宽度. 例如: 上面的计算操作:200-100=100 100/4=25 7."带*类型" 的特征探测:比较 #include "stdafx.h" #include <string.h> void fun() { char************** a ; char************** b ; a = (char**************)200; b = (char**************)100; if(a>b) { printf("6 "); } else { printf("8 "); } } int main(int argc, char* argv[]) { fun(); return 0; } 结论: 带*的变量,如果类型相同,可以做大小的比较。 课后练习 1.char类型占几字节?char*类型占几字节?int*****占几字节? char 占用1字节 (32位下)char* 站用4字节 (32位下)int***** 站用4字节 2、char** arr[10] 占多少个字节? 4x10=40 (32位下)char*** arr[10]占用40个字节 3、自定义结构体如下: struct Student { int x; int y; }; 正常不带*测试代码 #include "stdafx.h" #include <string.h> struct student { int x; int y; }; void fun() { student s; s.x = 100; s.y = 200; printf("%d %d",s.x,s.y); } int main(int argc, char* argv[]) { fun(); return 0; } 带一个*的测试 源代码 #include "stdafx.h" #include <string.h> struct student { int x; int y; }; void fun() { student* s; s = (student*)100; s++; printf("%d",s); } int main(int argc, char* argv[]) { fun(); return 0; } 运算结果;108 反汇编代码: 4: #include "stdafx.h" 5: #include <string.h> 6: 7: struct student 8: { 9: int x; 10: int y; 11: }; 12: 13: 14: void fun() 15: { 0040B800 push ebp 0040B801 mov ebp,esp 0040B803 sub esp,44h 0040B806 push ebx 0040B807 push esi 0040B808 push edi 0040B809 lea edi,[ebp-44h] 0040B80C mov ecx,11h 0040B811 mov eax,0CCCCCCCCh 0040B816 rep stos dword ptr [edi] 16: student* s; 17: 18: s = (student*)100; 0040B818 mov dword ptr [ebp-4],64h 19: 20: s++; 0040B81F mov eax,dword ptr [ebp-4] 0040B822 add eax,8 0040B825 mov dword ptr [ebp-4],eax 21: 22: printf("%d",s); 0040B828 mov ecx,dword ptr [ebp-4] 0040B82B push ecx 0040B82C push offset string "6 " (0042001c) 0040B831 call printf (00401110) 0040B836 add esp,8 23: } 0040B839 pop edi 0040B83A pop esi 0040B83B pop ebx 0040B83C add esp,44h 0040B83F cmp ebp,esp 0040B841 call __chkesp (00401190) 0040B846 mov esp,ebp 0040B848 pop ebp 0040B849 ret 带两个*的测试 源代码 #include "stdafx.h" #include <string.h> struct student { int x; int y; }; void fun() { student** s; s = (student**)100; s++; printf("%d",s); } int main(int argc, char* argv[]) { fun(); return 0; } 运算结果:104 带两个以上*的测试 源代码 #include "stdafx.h" #include <string.h> struct student { int x; int y; }; void fun() { student******* s; s = (student*******)100; s++; printf("%d",s); } int main(int argc, char* argv[]) { fun(); return 0; } 运算结果:104 进行加上或者减去一个整数测试 带一个*测试 源代码 #include "stdafx.h" #include <string.h> struct student { int x; int y; }; void fun() { student* s; s = (student*)100; s = s + 2; printf("%d",s); } int main(int argc, char* argv[]) { fun(); return 0; } 运算结果:116 带两个*测试 #include "stdafx.h" #include <string.h> struct student { int x; int y; }; void fun() { student** s; s = (student**)100; s = s + 2; printf("%d",s); } int main(int argc, char* argv[]) { fun(); return 0; } 运算结果:108 带两个以上*测试 源代码 #include "stdafx.h" #include <string.h> struct student { int x; int y; }; void fun() { student********* s; s = (student*********)100; s = s + 2; printf("%d",s); } int main(int argc, char* argv[]) { fun(); return 0; } 加法:100+2x4=108 减法:100-2x4=92 相减进行测试 源代码 两个以上*测试 #include "stdafx.h" #include <string.h> struct student { int x; int y; }; void fun() { student********* s1; student********* s2; int x; s1 = (student*********)200; s2 = (student*********)100; x = s1 - s2; printf("%d",x); } int main(int argc, char* argv[]) { fun(); return 0; } 运算结果:25 通过测试两个*的计算结果也是25 一个*测试 源代码 #include "stdafx.h" #include <string.h> struct student { int x; int y; }; void fun() { student* s1; student* s2; int x; s1 = (student*)200; s2 = (student*)100; x = s1 - s2; printf("%d",x); } int main(int argc, char* argv[]) { fun(); return 0; } 运算结果:12 200-100=100 100/8=12.5 取12 8的由来是结构体里面两个整形int,所站字节数是8 结论: 结构体定义带*的操作跟其他类型一样,当定义两个*以上的类型,都按照4个字节宽度进行计算,当定义一个*的时候按照结构体内部实际字节站用的计算