当前位置: 首页 > news >正文

四川省建设厅建造师官方网站/百度推广app

四川省建设厅建造师官方网站,百度推广app,德州中文网站建设,wordpress 添加外观一、动态分配内存 申请堆区的空间,需要手动申请,手动释放 如果直接定义在代码中的变量,是系统默认分配栈区的空间,栈区空间自动申请,生命周期结束自动释放。 需要用到头文件#include malloc和free一定成对出现 1.…


一、动态分配内存

申请堆区的空间,需要手动申请,手动释放

如果直接定义在代码中的变量,是系统默认分配栈区的空间,栈区空间自动申请,生命周期结束自动释放。

需要用到头文件#include

malloc和free一定成对出现

1.1 malloc

函数原型:
void *malloc(size_t size);   //有参数有返回值函数
功能:
从堆区申请size个字节,并将这一片空间的首地址返回给主调函数处
所以返回值为void*方便强转
void*表示万能指针(可以被强转成任何类型的指针)
使用:
int *p = (int*)malloc(sizeof(int));  //赋值运算符右侧的(int*)表示将malloc申请的首地址,强转成int类型
//让int*类型的指针p指向malloc申请的(sizeof(int))大小的堆区空间
//int *p = (int*)malloc(4);

1.2 free

功能:释放堆区的内存空间

函数原型:void free(void *ptr);
返回值:无
参数:要释放的堆区空间的首地址
堆区申请空间一定要使用free释放防止内存泄漏
一般释放完堆区内存后,会将原本指向堆空间的指针指向NULL

1.3 指针的强转

因为不同数据类型的指针的大小相同,所以指针之间的强转是安全的

但是会改变指针的偏移量

int *p; 
char *p1=(char*)p; 
上面的强转过程不会造成数据的丢失,但是如果p本身已经指向int类型数据,使用p1访问该数据时,可能只访问到低字节的数据

1.4 堆空间的地址作为指针函数的返回值

#include <stdio.h>
#include <stdlib.h>
int *func()
{int *p=(int*)malloc(4);*p=49;return p;
}
int main(int argc, const char *argv[])
{int *ret=func();  //因为func的返回值为堆空间申请的内存,不手动释放不会被回收    printf("%d\n",*ret);printf("%p\n",ret);//释放堆内存free(ret);return 0;
}

1.5 悬空指针

指针指向一片地址,但是对这片地址没有使用权,间接访问可能会发生段错误

1.5.1 指向已经堆放的空间

#include <stdio.h>
#include <stdlib.h>
int *func()
{int *p=(int*)malloc(4);*p=49;return p;
}
int main(int argc, const char *argv[])
{int *ret=func();  //因为func的返回值为堆空间申请的内存,不手动释放不会被回收    printf("%d\n",*ret);printf("%p\n",ret);//释放堆内存free(ret);printf("%p\n",ret);  //释放前后,ret的值不变//一般释放完堆区内存后,会将原本指向堆空间的指针指向NULLret=NULL;return 0;
}

1.5.2 指向已经被回收的空间

#include <stdio.h>
int *func()
{int a=90;int *p=&a;return p;   //这种方式返回编译不会报警告,因为智能识别到p是局部变量,返回p的值
}
int main(int argc, const char *argv[])
{int *ret=func();  //ret是一个悬空指针,指向已经被回收的栈空间的地址printf("%d\n",*ret);printf("%p\n",ret);return 0;
}

1.6 特殊指针

  1. 空指针:指向NULL的指针,间接访问一定会段错误
  2. 野指针:没有明确指向的指针,间接访问错误不可预知
  3. 悬空指针:指向已经被回收没有使用权的地址的指针,间接访问错误不可预知(知道指向,但是对空间没有使用权)
  4. 万能指针:可以强转为任意类型的指针

1.7 大小端存储

小端存储:低数据位存在低地址上

大端存储:低数据位存在高地址上

#include <stdio.h>
int main()
{int a = 0x12345678;char *p = &a;  //因为要取一个字节的数据进行判断//如果使用int *,*p取得是四个字节的内容if(*p==0x78){printf("小端存储\n");    }else if(*p=0x12){printf("大端存储\n");    }
}

1.8 练习

1.8.1 在堆区申请一个数组的空间,完成对数组元素的输入和输出

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{int *p=(int *)malloc(sizeof(int)*5);  // 申请一个客村下五个数的数组空间printf("请输入存入数组内的数(5)\n");for(int i=0;i<5;i++)  // 输入{scanf("%d",p+i);}printf("arr= ");for(int j=0;j<5;j++)  // 输出{printf("%d ",*(p+j));}free(p);  // 释放空间printf("\n");return 0;
}

二、结构体

属于构造数据类型

存储某些特征的结构,由多个或一个数据类型构成

2.1 定义

以学生为例,一个学生的信息包含:姓名、年龄、成绩、学校,这四个信息需要多个数据类型,数组无法完成,可以将这样的结构封装成结构体。

struct 结构体名
{//结构体成员数据类型 变量名;数据类型 变量名;····   
};   //定义了一个结构体类型

学生结构体的实现

#include <stdio.h>
//一般结构体的定义写在全局处
struct Stu
{int age;//年龄char name[100];//姓名float score;  //成绩
};
int main(int argc, const char *argv[])
{return 0;
}

2.2 定义结构体变量

struct 结构体名 结构体变量名;

2.3 初始化和赋值

2.3.1 完全初始化

定义的同时,按照结构体成员在结构体中的顺序完全初始化
struct Stu s2={20,"zhangsan",75.2}; 

2.3.2 不完全初始化

定义的同时,按照结构体成员在结构体中的顺序给部分成员赋值,未初始化的部分,默认为0
struct Stu s3={21};

2.3.3 按成员初始化

定义的同时,在初始化列标中以访问指定结构体成员的方式赋值
struct Stu s4={.name="lisi",.age=22};
#include <stdio.h>
#include <string.h>
//一般结构体的定义写在全局处
struct Stu
{int age;char name[100];float score;
}s;  //s是在定义结构体类型的同时,直接定义结构体变量int main(int argc, const char *argv[])
{struct Stu s1;   //定义了一个Stu类型的结构体变量s1/**************结构体的初始化和赋值*****************/struct Stu s2={20,"zhangsan",75.2};   //定义结构体变量,并完全初始化printf("s2.age=%d\n",s2.age);printf("s2.name=%s\n",s2.name);printf("s2.score=%f\n",s2.score);struct Stu s3={21}; //定义结构体变量不完全初始化,未初始化结构体成员默认为0printf("s3.age=%d\n",s3.age);printf("s3.name=%s\n",s3.name);printf("s3.score=%f\n",s3.score);//定义结构体变量,按照指定的顺序给某些/全部成员初始化struct Stu s4={.name="lisi",.age=22};printf("s4.age=%d\n",s4.age);printf("s4.name=%s\n",s4.name);printf("s4.score=%f\n",s4.score);/****************结构体变量的赋值******************/s1.age=18;    //单个成员的赋值,不能再进行整体赋值//s1.name="zhaoliu";//gets(s1.name);   用gets的方式给字符数组成员赋值strcpy(s1.name,"zhaoliu");s1.score=79.1;printf("s1.age=%d\n",s1.age);printf("s1.name=%s\n",s1.name);printf("s1.score=%f\n",s1.score);return 0;
}

2.4 访问结构体中的成员

通过.运算符访问结构体中的成员

  1. 结构体变量名.结构体成员名;
  2. 访问Stu中的name成员,已有结构体变量s1
  3. s1.name ---->获取到结构体变量s1中name成员的值

2.5 结构体指针访问结构体成员

struct 结构体名 *结构体指针名;
通过结构体指针访问结构体成员,用->访问
格式:结构体指针名->结构体成员;s1.age=18;    //单个成员的赋值,不能再进行整体赋值//s1.name="zhaoliu";//gets(s1.name);   用gets的方式给字符数组成员赋值strcpy(s1.name,"zhaoliu");s1.score=79.1;//定义结构体指针,指向s1struct Stu *p = &s1; printf("p->age=%d\n",p->age);printf("p->name=%s\n",p->name);printf("p->score=%f\n",p->score);

2.6 嵌套的结构体

#include <stdio.h>
struct Person
{int age;char name[100];
};
struct Stu
{struct Person p1;  //在Stu中嵌套Person类型的成员float score;
};
/*struct A
{//A里面包含了B类型结构体的定义struct B{int a;char c;};float b;
};*/
struct A
{//A里面包含了B类型的结构体成员b1struct B{int a;char c;}b1;float b;
};
//上面两种不同的结构体类型的定义都可以使用里面声明的struct B结构体类型
int main(int argc, const char *argv[])
{struct Stu s1;s1.p1.age = 90;printf("%d\n",s1.p1.age);struct B b2;return 0;
}

2.7 结构体的大小

结构体的大小需要进行字节对齐

字节对齐的规则:(通用的嵌套结构体也可以用)

  1. 每一个结构体中的成员对首地址的偏移量,必须是该成员本身对齐量的整数倍
  2. 成员本身的对齐量=成员本身对齐量>操作系统对齐量?操作系统的对齐量:成员本身大小(操作系统的对齐量,64位8Byte,32位4Byte)
  3. 结构体整体的大小,必须是最大对齐成员对齐量的整数倍
#include <stdio.h>
struct Person
{int age;char name[5];
};
struct Stu
{struct Person p1;  //在Stu中嵌套Person类型的成员float score;
};
/*struct A
{//A里面包含了B类型结构体的定义struct B{int a;char c;};float b;
};*/
struct Test
{char a;double k;int b;
};
struct A
{//A里面包含了B类型的结构体成员b1struct B{int a;char c;}b1;float b;
};
//上面两种不同的结构体类型的定义都可以使用里面声明的struct B结构体类型
int main(int argc, const char *argv[])
{struct Stu s1;s1.p1.age = 90;printf("%d\n",s1.p1.age);struct B b2;printf("%ld\n",sizeof(struct Person));printf("%ld\n",sizeof(struct A));return 0;
}

2.8 练习

2.8.1 从堆区申请一个结构体数组的空间,并完成对结构体成员的输入和输出

#include <stdio.h>
#include <stdlib.h>
struct Stu  // 定义一个结构体
{int age;char name[100];float score;
};
int main(int argc, const char *argv[])
{struct Stu *arr=(struct Stu*)malloc(sizeof(3));  // 从堆区申请一个储存三个结构体变量的空间for(int i=0;i<3;i++)  // 输入结构体内数据{printf("请输入学生姓名\n");scanf("%s",(arr+i)->name);printf("请输入学生年龄和分数\n");scanf("%d%f",&(arr+i)->age,&(arr+i)->score);}printf("姓名\t年龄\t分数\n");for(int j=0;j<3;j++)  // 输出结构体内数据{printf("%s\t%d\t%f\n",(arr+j)->name,(arr+j)->age,(arr+j)->score);}free(arr);  // 释放空间printf("\n");return 0;
}

2.8.2 计算下列结构体大小

http://www.whsansanxincailiao.cn/news/32051370.html

相关文章:

  • 深圳公司网站设计哪家好/网络营销策划的主要特点
  • 凡科免费做网站/关键词优化报价
  • c 网站购物车怎么做/百度推广怎么优化
  • seo推广排名/南宁seo外包平台
  • 济南兼职做网站/网站推广和优化的原因网络营销
  • 广元百度做网站多少钱/网站设计框架
  • 58网站怎么做优化/seo推广教程seo推广技巧
  • 大型网站 div/百度快速排名案例
  • 厦门手机网站建设公司/竞价推广课程
  • 怎么再贴吧给自己的网站做宣传/下载百度极速版免费安装
  • 湖南省专业建设公司网站/百度百科优化排名
  • 万网备案初审过了后网站能访问吗/在线企业管理培训课程
  • 潍坊网站制作 熊掌号/北京整站线上推广优化
  • 网站seo哪家公司好/网站排名优化培训课程
  • 栾城网站建设/新网站百度多久收录
  • 西安做网站企业/全网营销软件
  • 五金外贸网站/百度新闻下载安装
  • 湛江网站设计哪家好/山东免费网络推广工具
  • 站点创建成功/百度怎么推广自己的视频
  • 一学一做看视频网站有哪些/如何免费制作网站
  • 购买营销型网站/网推拉新app推广平台
  • 自适应网站开发资源/资源猫
  • 外贸一站式推广服务/产品销售方案与营销策略
  • 网站如何做问卷调查/线上销售水果营销方案
  • 珠海网站设计培训学校/如何让百度收录自己的网站信息
  • 东莞网站设计找哪里/搜索引擎的三个技巧
  • 优质网站建设服务/seo推广沧州公司电话
  • 企业手机网站建设精英/品牌推广策划
  • 西安网站设计制作多少钱/网易搜索引擎入口
  • 乌鲁木齐的网站建设/线上拓客渠道有哪些