之前学c语言的时候,指针这一章学的半吊子,似是而非,最近经过学习,对指针有个更加深刻的理解。
如果之前学过c指针,并且可以使用指针随心所欲操作内存中的任何数据,那么说明指针学好了,否则就是半吊子。
如果之前学过指针,那最好忘记之前学过的所有概念,把指针当做一种新的类型来学习。这种新的类型特点就是带*号。
现在学习一种新的类型:
1)这种类型就是在之前学过的所有类型后边加*号(注意,可以加多个*号),
之前学过char、short、int、long、int arr[4]、struct等基本类型,现在在这些类型后边加*号,char*、short*、int*、long*、int* arr[4]、struct*、char****、short**;
写这种类型以这样的写法int* a,short********* b,这样方便理解;不要写成int *a,short ********* b,这样不好理解。
2)这种带*号的新类型,有什么特点呢?
每学习一个新的类型,都要对这种类型做探测,探测这种类型的几种属性:宽度、赋值方式、++、--、加减一个整数N、乘除、两个带*的相减、两个带*的比较
char* a ;int* b; int********** c;
3)宽度探测: printf("%d",sizeof(a));printf("%d",sizeof(b));printf("%d",sizeof(c));最终会发现都是4(字节)
总结:所有带*号的,不管带多少个*号,只要带*号,这种新的类型宽度都是4字节。
4)赋值探测: int a=4的完整写法应该是int a=(int)4;一般为了省事,我们都是简写int a=4;
short* a=4;通过编译器报错提醒,我们发现这种*号的类型赋值的时候不能简写,得使用完整赋值写法,我们知道怎样给带*号的类型赋值。
short* a=4;char**** c=(char****)4;
5)++、--探测:定义一个short* a=( short*)4;char**** d=(char****)5;
a++相当于a=a+1;printf("%a",a);会发现打印的是6;
d++相当于d=d+1;printf("%d",d);会发现打印的是9;
a打印6是因为a+1=a+1×2=4+2=6;
d打印9是因为d+1=5+1×4=9;
总结:所有带*号的,不管带多少个*号类型加减N(例如:c+N),等于c的值加上N乘以(去掉1个*号的类型宽度),即c+N×(去掉一个*号的c的类型宽度)
以后不管带多少个*,那么加减法我们都会做了。
6) 乘除探测:不能做乘除。
7)两个带*的比较探测:可以比较。
8)并不是所有的变量前边都可以加*,只有之前这个变量被定义为带*的类型,这个变量前边才能加*,才可以在程序中出现“*变量”的格式。但是任何变量前边都可以加&。
9)变量前边加*,得到的类型,原来定义类型减掉1个*。
10)*号在反汇编代码是什么样的,例如*p,是两句反汇编代码,就是把p的值当做地址序号,取出这个序号指向的内存地址中的值。
int* p;
p在堆栈中是[ebp-4]的位置
&p 是ebp-4
*p
mov eax,[ebp-4] 在堆栈中取出p的值
mov edx, [eax] 再把p当做序号,取出序号里面存的值。
**p
mov eax,[ebp-4] 在堆栈中取出p的值
mov edx, [eax] 取出序号里面存的值,然后这个值变成一个内存序号
mov eax, [edx] 取出内存序号里面存的值。
标签:精通,short,语言,int,char,序号,类型,指针 From: https://www.cnblogs.com/gusseMe/p/17495495.html