【C语言疯狂讲义】(十一)C语言动态内存及结构体

  1、动态内存管理

 

    内存分为5大区域:

 

    栈:存放局部变量

 

    堆:存放程序运行过程中,动态申请的空间

 

    BSS:未初始化的全部变量,和静态变量

 

    数据段:已经初始化的全局变量和静态变量 常量

 

    代码段:程序源代码编译生成的二进制文件

 

 

    1 malloc 

 

        (void *)malloc(size)    //动态的向内存申请连续的size个字节

        返回的是新申请的内存空间的首地址

 

        int *p = (int *)malloc(100);

        //p是在栈区      malloc(100)在堆区

 

        malloc不会把新申请的空间初始化

 

        memset(p,0,100);  //全部初始化为0

 

    2) calloc

 

        calloc 可以向堆区连续申请多个少长度为指定长度的空间

 

        int *p = (int *)calloc(5,4);  //申请5个长度为4的空间

        

        calloc可以把新申请的空间初始化0

 

  

    注意:判断一个空间是否申请成功

 

         if(p!=NULL){

 

              //只有申请成功了,才能操作

 

         }

 

    3) realloc 

 

         重新改变一块内存空间的大小

   

         p = (int *)realloc(p,size);

 

 

    4) free

 

        释放我们指定的内存空间

 

        free(p);    //p是我们新申请的内存单元

 

        如果不释放,造成内存的泄露

 

 

 

 2、指针和函数之间的关系

 

 

    1)返回值值是指针的函数  指针函数

  

       char * getday(){

 

          return "星期一";

       }

 

       int * getAddr(int *a,int *b){

 

         return *a>*b?a:b;

       }

 

 

    2)函数指针

 

      指向函数的指针

 

      格式:返回值  (*指针变量名)(函数的参数);

 

      int sum(int a,int b){

 

          return a+b;

      }

 

      //定义一个函数指针p1p1只能指向返回值是int类型,并且函数参数有两个,而且整形

      int (*p1)(int a,int b);

      int (*p2)(int,int);

 

      技巧:

      声明的格式:int sum(int a,int b);

 

      int (*p3)(int a,int b);

 

     4、结构体基本概念

 

       构造类型:由一个或者多个相同类型或者不同类型已经定义的变量用构造的方法,构造一个新的类型;

 

       数组  结构体  共用体

 

       结构体定义:

 

            struct 结构体名 {

 

                 成员列表 (格式:数组类型 成名名)

 

            };

 

      使用构造类型的步骤:

 

           定义构造类型  --  定义构造类型的变量 --> 结构体变量初始化

 

           --》使用结构体的变量

 


 

  5、结构体的变量定义

 

     1)定义结构的同时,定义变量

  

        struct Car{

 

           int lunzi;

 

        }car1,car2;    //定义了两个结构体变量,car1car2都是 Car类型

 

     2)先定义结构体,后定义变量

 

        struct Student{

             int sno;

        };

 

        struct Student  stu1,stu2;  //stu1stu2都是Student类型的

 

     3)匿名结构体定义变量

 

        struct {

 

          int screen_size;

 

        }iphone5,iphone6;

 

 

  6、结构体变量的初始化

 

     初始化结构体变量应注意:初始化的值得类型和顺序要一致。

 

     1)定义结构的同时,定义变量,然后初始化

     

     struct Car{

     

     int lunzi;

     char pp[10];

     

     }car1={1,"BMW"},car2={2,"BYD"};    //定义了两个结构体变量,car1car2都是 Car类型

     

     2)先定义结构体,后定义变量,然后初始化

     

     struct Student{

     int sno;

     };

     

     struct Student  stu1={438},stu2={12};  //stu1stu2都是Student类型的

     

     3)匿名结构体定义变量,然后初始化

     

     struct {

     

     float screen_size;

     

     }iphone5={4.7f},iphone6={5.5f};

     

     4)指定初始化的属性

 

     struct Car{

     

     int lunzi;

     char pp[10];

     

     }c1={.pp="xxxx"};

 

     struct Car c2;

     //c2.pp = "BMW";  X

 

 

  7、结构体变量成员的访问方法

 

     格式:结构体的变量名.成员变量名

 

     c1.lunzi

     c1.pp

 

 

  8、结构的内存存储细节

 

     结构体内存占用?

 

          每个元素占用之和(还要考虑对齐的问题)

 

     对齐?

 

          为了提高读取效率,计算机每次读取一个数的倍数(防止一个数读取两次)

 

     对齐的模数

 

          一个结构体中,占用的字节数最大的那个数,就是对齐的模数

 

     计算存储的时候,按照模数存储和分配存储空间

 

          

 

     计算长度:sizeof(struct 结构名)

 

          从结构体的第一个成员开始,每次分配模数大小的空间,要考虑空闲的空间的再利用


    9、结构体的作用域

 

     全局的结构体:从定义的位置开始    文件的末尾

 

     局部的结构体:在函数的内部或者代码块内部定义的结构体

 

                 从定义的位置开始    所在的代码块 “}” 结束

 

     结构体的作用域的使用,同局部变量和全局变量使用一样

 

 

   10、结构体的数组

 

      由相同类型的结构体变量组成的有序的集合。

 

      定义格式:

 

            1) 定义结构体的同时定义结构体数组

 

               struct Car{

                  int lunzi;

                  int speed;

               }cars[5];

 

            2) 使用匿名结构体定义数组

 

             struct {

                 int lunzi;

                 int speed;

             }cars[5];

 

            3)先定义结构体在定义变量

 

               struct Car cars[5];

 

    初始化:

 

         1) 定义结构体数组的同时进行初始化1

         

         struct Car{

         int lunzi;

         int speed;

         char name[20];

         }cars[2]={{2,50},{80,300}};

         

         2)

         

         struct {

         int lunzi;

         int speed;

         }cars[2]={{2,50},{80,300}};

         

         3

         

         struct Car cars[2]={{2,50},{80,300}};

 

         4)先定义数组,后初始化

 

           cars[0].lunzi = 4;

           cars[0].speed = 200;

           //cars[0].name="xxxx"; 错误的

           strcpy(cars[0].name,"xxxx");

 

           const char a;

 

           //用一个整体去初始哈哈

           cars[1]=(struct Car){6,100};

 

 

       11、结构体指针

 

          定义一个指针 指向 结构体变量

 

          格式:结构体类型  * 结构体的变量名;

 

               struct Student stu1;

 

               struct Studetn *pstu;

 

               pstu = &stu1;

 

          目的:间接访问 结构体变量中保存的成员变量值

 

               (*pstu).name   (*pstu).sno 

 

          新的访问方法

 

               pstu->name   等价于 (*pstu).name

 

 

 

     12、结构体与函数之间的关系

 

         1)结构体变量的成员变量做函数参数(除了数组之外,都是值传递)

 

         2)结构体变量作为函数的参数 (值传递)

 

         3)结构体指针作为函数的参数  (地址传递)


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值