c指针经典案例:学习笔记02

一:认识下内存四区

栈区:系统自动开辟,释放。(定义变量,根据作用域开辟或释放内存)

堆区:程序员主动开辟释放。在头文件stdlib.h里面,malloc(),free()分别是开辟空间和释放空间

全局区:全局静态变量

代码区:保存代码

二:地址

把内存(内存条)以字节为单位,编号,地址是唯一的 是一种数据

& 取址符 单目运算符 右结合性 作用是返回一个变量的地址

首地址:这个数据的第一个存储单元的地址

三:指针变量

指针变量来存储地址。

定义一个指针:

int main(){

int a;                 //整形变量

int *p;               //指向整形的指针

pa = &a;

return 0;

}

指针类型 *变量名

              数据类型:这个指针变量指向的类型

              *             :星号只是说明这里是一个指针变量,标记。

              变量名   :通常p的前缀 pointer

对指针赋值

    初始化:定义的时候直接赋值

                  int a;  

                  int *pa = &a;

     赋值:先定义,再赋值

指针的引用:

       指针变量自己的值:pa

       指针变量指向的值: *pa

      (星号:在定义指针变量的时候,*取表示,说明定义指针变量。

                     *的前面没有数据类型,她是一个运算符 取值运算符 取某一个指针指向的值)

 函数调用的时候:只是把实参的值传递给形参,在函数中形参的变化并不影响实参

四:野指针

        没有明确指向的指针。很危险,不确定指向的地址有没有被使用

         明确的知道这个指针会不会产生不必要的麻烦,如果会,则在定义的时候 int *p = NULL;

五:空指针

        不确定类型的指针(地址)。

        void*

        void* malloc(4);  //开辟4个字节的空间

        void*类型 可以强制转换成其他任意类型  (int*)malloc(4); (char(*)[4]malloc(4);

                     注意:类型的大小

六:指针的运算

        指针的运算其实就是地址的偏移(+ - ++ --)。两个地址之间的运算是没有意义的(比如天安门的地址+圆明园的地址等于?)。

        int *p

        p+1;

        p+2

        p-1;

        p++;

        p--;

        + -          p的指向是不会动的

        ++ --       p的指向是会动的

        p+1;  //p 1000 p+1 = 1001?  不一定 跟指向的类型有关系。指针的偏移总是以这个指针所指向的数据的大小来偏移的

        举例:

#include <stdio.h>


int main()
{
    char a;
    char *pa = &a;
    
    int b;
    int *pb = &b;
    
    int c[10];
    int (*pc)[10] = &c;
    
    printf("pa = %d,pa+1 = %d\n",pa,pa+1);
    printf("pb = %d,pb+1 = %d\n",pb,pb+1);
    printf("pc = %d,pc+1 = %d\n",pc,pc+1);
   
    return 0;
}

          执行结果为:

     pa = 1365882871,pa+1 = 1365882872
     pb = 1365882864,pb+1 = 1365882868
     pc = 1365882816,pc+1 = 1365882856

七:一维数组与指针

      &a是指向整个数组的指针。

      a是数组名:【数组名是这个数组的首地址】

      int *p1   =  a;

      int (*p2)[5]  = &a;

      a指向数组的第一个存储单元 a[0]

      访问数组元素: 

              数组名:*(a+m)   //    a[m]

               指针:int *

       int a[5] = {1,2,3,4,5};

       int *pa =a;     //pa =&a[0];

       for(i=0;i<5;i++)

       {

            printf("%d\t",*(pa+i));     //pa不变化

       }

       for(i=0;i<5;i++)

       {

            printf("%d\t",*(pa++));     //改变了pa的指向

       }

       总结:a   *(a+0)  *(a+1) .....  *(a+m) 就是a[m]

                 pa   *(pa+0) *(pa+1) ........*(pa+m)   就是pa[m]

八:二维数组

      假设int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

      在内存中是连续存储的,本质上是由三个一维数组组成的,分别是a[0],a[1],a[2];

      内存分布为:

01234567891011

                                              a[0]                              a[1]                               a[2]

                                              a+0                              a +1                              a+2

                                              *(a+0) 

                                              a[0] 一维数组名

      这个数组名是a,指向数组的【第一个存储单元】,如果是二维数组,那么第一个存储单元就是指一维数组,

      访问m行n列:

       *(*(a+m) +n)  值

九:多维数组和指针

        8维数组

               k b c d e f g h

                 *(*(*(*(*(*(*(*a+k)+b)+c)+d)+e)+f)+g)+h)

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                *(a+m)

                *(*(a+m)+n)

                 *( *(*(a+m)+n)+k)

备注:此笔记由观看学习B站博主会编程的小家伙的视频《彻底搞定C语言指针详细完整版-初学者必备》所记,感谢这位老师,侵权删。

 

 

 

 

 

 

 

        

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值