学习笔记6-C语言内存管理+构造类型

1常见动态内存分配函数

使用之前导入头文件stdlib.h

1) malloc

void  *malloc(unsigned size)

作用是在堆区分配一个大小为size的连续空间,如果成功返回新分配内存的首地址否则返回null。在使用新内存之前必须判断是否分配成功。

 

申请空间       int *p=(int *)malloc (4*sizeof(int)); 分配空间强制类型转换

使用    if(p!=NULL){

  //正常使用空间

}else{ 

//空间分配失败处理

}

注意 malloc 申请的内存空间,如果不赋值 存的是随机数。

 memset (地址,‘a’size) 把地址后的size长度的字符都设置为字符a

2) calloc按块分配

int *p=(int *) calloc(块数,块数大小);

申请的空间也是连续的,如果不赋值 初始化为0。

3) relloc (扩充原内存)

p =relloc(原内存地址p,新的内存大小);、

扩充内存时,如果内存不够用,会重新寻找一块足够大的连续内存,把新内存地址返回。

4) 野指针和内存泄漏

野指针是没有指向的指针。

解决方法:给指针初始化为NULL,使用之后再次赋值为NULL或者释放。

内存泄漏:指针释放了,内存没有释放。

解决方法:在释放指针之前,先释放内存空间。

                        free(p)。

                       同时将p的指针赋值为 NULL,避免野指针。

2 指针函数

概念:返回值为指针的函数。

类型说明符 * 函数名(形参列表){

函数体

}

       函数体中返回返回值的地址。

注意值传递和地址传递。

 

使用举例

输入一个1-7 的值返回星期

<span style="font-size:14px;"><span style="white-space:pre">	</span>char * getDay(int n){
<span style="white-space:pre">	</span>char *days[]={
<span style="white-space:pre">	</span>“monday”,
<span style="white-space:pre">	</span>“tuesday”,
<span style="white-space:pre">	</span>“wednesday“,
<span style="white-space:pre">	</span>“thursday“,
<span style="white-space:pre">	</span>“friday“,
<span style="white-space:pre">	</span>“saturday“,
<span style="white-space:pre">	</span>“sunday“
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>return  0<n<8?days[n]:”输入有误”;  //返回days[n]字符串的首地址。否则返回字符串“输入有误的首地址“。
<span style="white-space:pre">	</span>}</span>


3 函数指针

指向函数的指针。

1) 函数指针定义:  返回值类型  (*函数指针名)(形参列表);

                 int (*p)(int x,int y);

        2)普通函数定义  返回值类型 函数名sum(形参列表){

              函数体;

}

       int sum(int x ,int  y){

return x+y;

}

         3)函数指针的初始化:p=sum; //函数名sum是该函数的首地址。

              注意

初始化时函数指针的返回值类型和形参列表与函数必须一致。

定义函数指针的时候可以不写形参名,但是必须写形参类型。

4)函数指针的使用。

              可以把p当sum使用

              sum(3,4);

              p(3,4);

              (*p)(3,4);  //取值调用

注意

 p是一个指针变量,通过对p的重新赋值可以使p获得其他函数的首地址,调用其它函数。

 函数指针不能算术运算。


4 构造类型

       构造数据类型是根据已定义的一个或者多个数据类型用构造方法定义。

构造类型的值可以分解为一个基本数据类型或者一个构造类型。

 

数组是一个数据类型相同的构造类型。

结构体是数据类型多元化的构造类型。

 

1)结构体定义:

struct 结构名{

成员变量列表;     //成员变量之间用分号分隔

}; //此处有分号

struct student{

       char  *name;

       int   class;

       float  score;

};

 

2) 结构体变量

定义

a 先定义结构体,再定义结构体变量

struct  student stu1;

b 定义结构体的同时定义结构体

struct 结构体名{

        成员变量

}结构体变量1,结构体变量2;//逗号间隔,分号结束

c 匿名结构体

struct  {

        成员变量

}结构体变量1,结构体变量2;//逗号间隔,分号结束

 

结构体变量的成员访问

 

结构体变量名.结构体成员变量

stu1.name

 

结构体变量的初始化

a 先定义结构体后初始化

stu1.name=”xiaoming”

b 定义结构体的同时初始化

struct student stu1={“xiaoming”,9,59.5};

c 指定元素初始化

struct student stu1={.name=”xiaoming”};

3)结构体变量的存储原理

   数据成员对齐作用

        简化处理器与内存之间传输系统的设计

        提升数据的读取速度。

结构体存储的大小是各个成员变量字节和(考虑对齐问题)

4)结构体的作用域 全局和局部

 

5)结构体数组

 

结构体数组的定义

和结构体变量定义方法一样。只不过是一个结构体数组。

 

结构体数组的初始化

a  定义的同时初始化

         struct student{

               成员变量

stu[5]={{ },{ },{ }};

b 先定义后初始化

struct student{

               成员变量

};

student stu[3]={{},{},{}};

c 先定义的后初始化,整体赋值

  struct student stu[3];

  stu[0]=(struct student){  ,  ,  };

d 先定义数组后,点方法赋值

       stu[0].name=”ss”;

 

6)结构体指针

       指向结构体变量的指针

定义 struct  student *pstu;

                struck student stu=NULL;

      初始化赋值  pstu=&stu;


结构体指针间接访问变量的值

       (*结构体指针).成员变量

         结构体指针->成员变量

7)结构体嵌套


8)结构体与函数参数

       成员值作为函数的参数。 和普通实参类似,值传递。

       结构体变量作为函数参数。类似数组,会给形参分配空间,把实参值赋值给形参变量,值传递。

              void xx(sructstudent stu){  };

      结构体指针作为函数参数。类似指针,地传递。

              void xx(sruct  student * pstu){  };

 

 enum  weekday{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};

5 枚举类型

枚举类型是基本数据类型,值不可以分解。

定义

       enum 枚举类型名 {

               枚举值列表     //逗号分隔

}

 

       

      使用

            enum 枚举类型名  枚举变量名;

       枚举变量的值

             打印值 :printf(“%d”,枚举变量名);

              默认第0个枚举值为0,依次+1.

             如果手动赋值,其后的值为当前值累加1。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值