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

用自己的服务器建网站网络营销推广策略

用自己的服务器建网站,网络营销推广策略,郑州新一网站建设,企业服务公司的经营范围有哪些文章目录为什么存在动态内存分配❓#x1f449;动态内存函数#x1f448;mallocfreecallocrealloc❌常见的动态内存错误❌练习题#x1fae0;C/C程序的内存开辟#x1f914;柔性数组柔性数组的特点柔性数组的优势:star:动态通讯录:star:初始化添加销毁为什么存在动态内… 文章目录为什么存在动态内存分配❓动态内存函数mallocfreecallocrealloc❌常见的动态内存错误❌练习题C/C程序的内存开辟柔性数组柔性数组的特点柔性数组的优势:star:动态通讯录:star:初始化添加销毁为什么存在动态内存分配❓ 静态内存分配 当你声明数组时你必须用一个编译时常量指定数组的长度(c99前)。但是数组的长度常常在运行时才知道这是由于它所需要的内存空间取决于输入数据。例如一个用于计算学生等级和平均分的程序可能需要存储一个班级所有学生的数据但不同班级的学生数量可能不同。在这些情况下我们通常采取的方法是声明一个较大的数组它可以容纳可能出现的最多元素。 这样声明的数组有3个缺陷 这种声明引入了认为的限制如果使用的长度超过了声明的长度计算机无法处理这种情况如果程序使用的元素较少时这样会导致多余的空间被浪费如果输入的数据超过了数组的容纳范围那么程序不得不做出一种合理的相应 int main() {int val 20;//在栈上开辟4个字节int arr[10] { 0 };//在栈上开辟40个字节的连续空间return 0; }上述开辟空间的方式有2个特点 开辟空间的大小是固定的数组在声明时必须指定数组的长度它所需要的内存在编译时分配 上述开辟空间的方式称为静态内存开辟 动态内存分配 在计算机科学中, 动态内存分配Dynamic memory allocation又称为堆内存分配是指计算机程序在运行期中分配使用内存。它可以当成是一种分配有限内存资源所有权的方法。 动态分配的内存在被程序员明确释放或被垃圾回收之前一直有效。与静态内存分配的区别在于没有一个固定的生存期。这样被分配的对象称之为有一个“动态生存期”。 动态内存函数 以下动态内存函数均包含头文件stdlib.h 动态内存函数开辟的空间都在堆上 mallocfree malloc的参数是开辟空间的字节数 如果开辟成功则返回一个指向开辟好空间的指针开辟的内存存放的是随机值。如果开辟失败则返回一个NULL指针因此malloc的返回值一定要做检查。返回值的类型是 void* 所以malloc函数并不知道开辟空间的类型具体在使用的时候使用者自己来决定。如果参数 size 为0malloc的行为是标准是未定义的取决于编译器。 free函数用来释放通过malloc,calloc,realloc动态开辟的空间如果指针ptr指向的空间不是上述函数动态开辟出来的那么行为是未定义的如果ptr是NULL指针那么调用free函数什么也不会做 int main() {int i, n;char* buffer;printf(How long do you want the string? );scanf(%d, i);buffer (char*)malloc(i 1);//需要留一个空间给结束符if (buffer NULL) exit(1); //分配空间失败for (n 0; n i; n) buffer[n] rand() % 26 a;buffer[i] \0;printf(Random string: %s\n, buffer);free(buffer);//释放动态开辟的内存return 0; }calloc calloc函数的第一个参数是要开辟的元素个数第二个参数是每一个元素的字节数 calloc动态开辟一段内存并且将申请的字节中每一个比特位初始化为0开辟成功返回开辟的这段空间起始地址开辟失败返回NULL指针如果第二个参数为0返回的结果# 取决于特定的库(不一定返回NULL指针),这个返回的指针不能够被解引用 int main() {int* pa (int*)calloc(5, sizeof(int)); //申请5个连续存储int的空间并初始化为0if (pa!NULL)for (int i 0; i 5; i) printf(%d , pa[i]);free(pa);//释放动态开辟的内存return 0; }realloc realloc函数让动态内存管理更灵活我们可以通过realloc对动态开辟的内存进行更改(扩大/缩小) realloc函数的第一个参数是待扩容内存起始地址第二个参数是扩容后的字节数 如果扩容成功返回扩容内存后的首地址(可能与之前的地址不一样)如果扩容失败返回NULL指针如果第一个参数为NULL指针则realloc行为和malloc行文一样如果size参数为0 对于c90/c98ptr指向的空间被free并且返回NULL指针 对于c99/c11返回值取决于特定的库实现它可能是空指针或其他不应被取消引用的位置。 当原空间后面有连续足够大的空间时realloc返回原空间起始地址当原空间后面没有足够大的空间时 对于情况一直接返回已知空间的起始地址 对于情况二 realloc寻找可以存放下的空间将原来的在已知空间中的数据拷贝到可用空间中free已知空间返回目标空间的起始地址 int main() {int input, n;int count 0;int* numbers NULL;int* more_numbers NULL;do {printf(Enter an integer value (0 to end): );scanf(%d, input);count;more_numbers (int*)realloc(numbers, count * sizeof(int));//没输入一个数申请一个多空间if (more_numbers ! NULL) {numbers more_numbers;numbers[count - 1] input;}else perror(realloc失败-\n);} while (input ! 0);printf(Numbers entered: );for (n 0; n count; n) printf(%d , numbers[n]);free(numbers);return 0; }从这个例子中可以很好的体现动态开辟的优势即使我事先不知道用户要输入多少个数(甚至用户也不知道)我也可以将用户输入的数字记录下来 注意调用realloc时最后用临时变量接受返回值不然返回值如果为NULL时原来已知空间中的地址找不到了,因为原本记录那个地址的变量现在变成了NULL ❌常见的动态内存错误❌ 对NULL指针解引用 //1.对空指针解引用 int main() {int* p (int*)malloc(INT_MAX);*p 20;free(p);return 0; }malloc开辟失败返回空指针没有检查是否开辟成功就直接解引用有可能解引用空指针程序崩溃 对动态开辟空间的越界访问 //2.对动态开辟的内存进行越界访问 int main() {int* p (int*)malloc(sizeof(int) * 5);assert(p);for (int i 0; i 5; i){p[i] i 1;} return 0; p指向的是5个int的空间但是当i等于5时程序访问了未定义的位置这样会越界访问越界访问有可能会时程序崩溃有可能不会(不代表问题不严重) 对非动态开辟内存使用free释放 int main() {int a 10;int* p a;free(p);return 0; }使用free释放动态开辟内存的一部分 //4.使用free释放动态开辟内存的一部分 int main() {int* p (int*)malloc(sizeof(int) * 5);free(p);return 0; }对用一块内存多次释放 //5.对同一块内存多次释放 int main() {int* p (int*)malloc(sizeof(int) * 5);free(p);//释放一次后p指向的空间不在是动态开辟的了free(p);//此时释放非动态开辟的内存报错return 0; }动态开辟的内存忘记释放(内存泄漏) void test() {int* p (int*)malloc(100 * sizeof(int)); } int main() {while (1){test();}return 0; }当内存大量泄漏时程序会吃掉大部分内存这样操作系统没有过多的内存分配给其他应用因此内存泄漏可能会导致操作系统崩溃 切记动态开辟的内存一定要释放并且保证正确释放 为了避免这种情况我们应该保证自己申请的内存自己释放自己不释放的应当写文档告诉别人来释放 练习题 //1.下面程序会打印什么 void GetMemory(char* p) {p (char*)malloc(100); }int main() {char* str NULL;GetMemory(str);strcpy(str, hello world);printf(str); }可以通过函数返回开辟的地址和传二级指针修正程序 //修正1 char* GetMemory() {char* tmp (char*)malloc(100);return tmp NULL ? NULL : tmp; }int main() {char* str GetMemory();strcpy(str, Hello world);printf(str);free(str);//释放动态分配的内存str NULL;return 0; }//修正2 void GetMemory(char** pp) {*pp (char*)malloc(100); }int main() {char* str NULL;GetMemory(str);strcpy(str, Hello world);printf(str);free(str);str NULL;return 0; }//2.输出结果是什么 char* GetMemory(void) {char p[] hello world;return p; } void Test(void) {char* str NULL;str GetMemory();printf(str); }//3.输出什么 void GetMemory(char** p, int num) {*p (char*)malloc(num); } int main() {char* str NULL;GetMemory(str, 100);strcpy(str, hello);printf(str);return 0; }//4.输出什么 int main() {char* str (char*)malloc(100);strcpy(str, hello);free(str);if (str ! NULL){strcpy(str, world);printf(str);} }C/C程序的内存开辟 看见这个图相比就会大致了解C/C的内存区域规划了吧hhh~ 柔性数组 想必不少人一开始听到这个词比较陌生什么叫做柔性数组变长数组我知道数组的长度可以是变量嘛柔性数组是什么鬼嘛‍ 柔性数组和变长数组都是在C99中加上的 C99 中结构中的最后一个元素允许是未知大小的数组这就叫做『柔性数组』成员。 柔性数组的特点 1.柔性数组不占结构体的大小 2.柔性数组只能是结构体中最后一个成员并且结构体除柔性数组外至少有一个其他成员 //定义柔性数组的两种错误写法 struct flexible_array {int arr[]; };struct flexible_array {int arr[];int i; }; 3.包含柔性数组成员的结构用malloc()函数进行内存的动态分配并且分配的内存应该大于结构的大小以适应柔性数组的预期大小 //malloc分配结构的大小分配的空间必须大于结构的大小 typedef struct flexible_array {int i;int arr[]; }flexible_array; int main() {//给柔性数组分配10个int大小flexible_array* pa (flexible_array*)malloc(sizeof(flexible_array) sizeof(int) * 10);assert(pa);for (size_t i 0; i 10; i) pa-arr[i] i;for (size_t i 0; i 10; i) printf(%d , pa-arr[i]);free(pa);return 0; }更改数组的大小 int main() {flexible_array* pa (flexible_array*)malloc(sizeof(flexible_array) sizeof(int) * 10);//给柔性数组分配10个int大小assert(pa);for (size_t i 0; i 10; i) pa-arr[i] i;for (size_t i 0; i 10; i) printf(%d , pa-arr[i]);puts();//数组扩容成20个int大小flexible_array* tmp (flexible_array*)realloc(pa, sizeof(flexible_array) sizeof(int) * 20);assert(tmp);pa tmp;for (size_t i 10; i 20; i) pa-arr[i] i;for (size_t i 0; i 20; i) printf(%d , pa-arr[i]);puts();free(pa);return 0; }柔性数组的优势 上述代码可以写成 typedef struct flexible_array {int i;int* arr; }flexible_array; int main() {flexible_array* pa (flexible_array*)malloc(sizeof(flexible_array)); pa-arr (int*)malloc(sizeof(int) * 10);for (size_t i 0; i 10; i) pa-arr[i] i;for (size_t i 0; i 10; i) printf(%d , pa-arr[i]);puts();//flexible_array* tmp (flexible_array*)realloc(pa-arr, sizeof(int) * 20);assert(tmp);pa-arr tmp;for (size_t i 10; i 20; i) pa-arr[i] i;for (size_t i 0; i 20; i) printf(%d , pa-arr[i]);puts();//先释放arrfree(pa-arr);free(pa);return 0; }对比上述两种写法 第一个好处是方便内存释放 如果我们的代码是在一个给别人用的函数中你在里面做了二次内存分配并把整个结构体返回给 用户。用户调用free可以释放结构体但是用户并不知道这个结构体内的成员也需要free所以你不能指望用户来发现这个事。所以如果我们把结构体的内存以及其成员要的内存一次性分配好了并返回给用户一个结构体指针用户做一次free就可以把所有的内存也给释放掉。第二个好处这样有利于访问速度. 连续的内存有益于提高访问速度(计算机在访问当前地址时会默认把当前地址相邻的数据加载到寄存器中)也有益于减少内存碎片(使用柔性数组只调用一次malloc,而指针写法调用了两次malloc) ⭐️动态通讯录⭐️ 在了解动态内存函数之后我们可以将之前的静态通讯录改进为动态通讯录不会静态通讯录看这里静态通讯录 首先明确一点静态通讯录是通过一个大小固定的数组来存放联系人的信息而数组的大小每次都是固定的所以通讯录的长度不能更改动态通讯录就是通讯录的容量可以更改这样的好处有1. 存多少人的信息就开辟多少空间不够了随时可以扩容2. 动态开辟的空间是在堆上的堆上的空间比栈上的大所以存储的联系人也比静态通讯录存储的多 将数组换成指针变量即可实现动态通讯录并且需要增加变量capacity来存储当前通讯录的最大容量 动态通讯录只有在初始化、增加联系人、销毁时和静态通讯录不一样 初始化 //动态通讯录 typedef struct Contact {PeoInfo* data;//data是一个指针指向动态开辟的内存int sz; //当前联系人个数int capacity;//当前最大容量 }Contact;//动态通讯录初始化 void InitContact(Contact* con) {con-data NULL;con-capacity FITST_NUM;//一开始的最大容量con-sz 0; } 添加 添加联系人之前需要检查一下当前最大容量是否满了如果满了需要扩容 //检查容量是否满了 void CheckContact(Contact* con) {if (con-capacity con-sz || con-sz 0){PeoInfo* pc (PeoInfo*)realloc(con-data, MAGNIFICATION * sizeof(con-capacity));if (NULL pc){perror(扩容失败\n);return;}con-capacity * MAGNIFICATION;//容量扩成当前最大容量的两倍con-data pc;printf(扩容成功当前容量最大容量%d\n, con-capacity);}return; }//动态通讯录添加 void AddContact(Contact* con) {CheckContact(con);printf(请输入你需要添加人的姓名:);scanf(%s, con-data[con-sz].name);printf(请输出你需要添加人的年龄:);scanf(%d, (con-data[con-sz].age));printf(请输入你需要添加人的性别:);scanf(%s, con-data[con-sz].sex);printf(请输入你需要添加人的电话:);scanf(%s, con-data[con-sz].tele);printf(请输入你需要添加人的地址:);scanf(%s, con-data[con-sz].address);con-sz;printf(添加成功!\n); } 销毁 //动态通讯录销毁 void DestroyContact(Contact* con) {printf(你确定要清空通讯录吗?(YES/NO)\n);char selection[MAX] { 0 };scanf(%s, selection);fflush(stdin);if (strcmp(selection, YES) ! 0) return;free(con-data);printf(清空成功!\n); }
http://www.yingshimen.cn/news/74430/

相关文章:

  • 辽宁网站设计网站建设跟加入会员哪个效果好
  • 网站数据流分析怎么做怎么做游戏网站的宣传图片
  • 浅谈电子商务网站建设与管理淄博百度电话
  • 网络营销的传播手段seo自然排名关键词来源的优缺点
  • 寮步网站建设哪家好公司crm管理软件
  • 移动网站建设规定wordpress网站的CDN设置
  • 企业网站建设记什么会计科目手机网站建站价格
  • 网站建设后需要录入php购物商城源码
  • 电影网站源码怎么做的网站建设服务费记账分录
  • 手机端网站怎么制作上海企业制作网站有哪些内容
  • 网易企业邮箱电话济南网站seo报价
  • 网站竞价推广托管公司成功营销案例
  • 优质公司网站唯美wordpress简约主题
  • php做的网站模板下载常宁网站设计
  • 公司门户网站项目模版集团网站改版方案
  • 网站开发语言有哪些扬中网站建设好么
  • 百度怎样可以搜到自己的网站市场推广计划书
  • 建设网站本地调试天津网站设计 河西
  • 创新的商城网站建哈尔滨建设规划局网站
  • 福州做网站软件网站名字大全
  • 一个网站按钮怎么做重庆做seo网站优化选择哪家
  • 爱站网站长seo综合查询工具店面门面设计
  • 建设京东类的网站需要什么流程图本地的上海网站建设公
  • 做网站网站的虚拟空间湖南网站建设公司 尖端磐石网络
  • 网站服务器维护内容十堰做网站
  • 广州17做网站网站没有备案用什么cdn
  • 医院网站建设合同范本百度云 做视频网站
  • 单位装专用的网站网页归档外包公司软件开发可以去吗
  • 网站前台管理系统软件项目和网站建设的区别
  • 怎样才能在百度搜索到自己的网站爱站网能不能挖掘关键词