精通c语言中的指针(精通c指针1)

之前学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]                 取出内存序号里面存的值。

posted @ 2023-06-21 10:18  一日学一日功  阅读(36)  评论(0)    收藏  举报