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

宝应县住房建设局网站liunx wordpress 搭建

宝应县住房建设局网站,liunx wordpress 搭建,建设一个房产网站赚钱吗,网站设计风格确认书目录 一、学习目标#xff1a; 二、内存镜像 什么是进程 C进程内存布局 栈内存 静态数据 数据段#xff08;存储静态数据#xff09;与代码段 堆内存 三、字符操作函数 函数strstr 函数strlen strlen与sizeof的区别 函数strtok 函数strcat与strncat 函数strc…目录 一、学习目标 二、内存镜像 什么是进程 C进程内存布局 栈内存 静态数据 数据段存储静态数据与代码段 堆内存 三、字符操作函数 函数strstr 函数strlen strlen与sizeof的区别 函数strtok 函数strcat与strncat 函数strcpy与strncpy 函数strcmp与strncmp 函数strchr与strrchr 四、总结 一、学习目标 知识点 一文掌握 C 语内存镜像关系掌握编程时各代码位置的实际分布内存简单了解字符操作函数的应用 二、内存镜像 什么是进程 进程与程序的关系 程序 是一个静态的文件文件内存储的是一系列的二进制执行指令 gcc hello.c -o hello 其中 Hello 就是一个程序文件。 进程则是把一个程序文件加载到内存中由 CPU 去执行对应的指令的一个过程因此进程是一个动态的过程这个动态的过程会有一些列对与内存的申请和释放操作。 本小节就详细了解进程在运行过程中究竟是怎么申请内存空间以及申请到的内存分别有什么特性。 C进程内存布局 任何一个程序正常运行都需要内存资源用来存放诸如变量、常量、函数代码等等。这些不同的内容所存储的内存区域是不同的且不同的区域有不同的特性。因此我们需要研究财经处内存布局逐个了解不同内存区域的特性。         每个C语言进程都拥有一片结构相同的虚拟内存所谓的虚拟内存就是从实际物理内存映射出来的地址规范范围最重要的特征是所有的虚拟内存布局都是相同的极大地方便内核管理不同的进程。例如三个完全不相干的进程p1、p2、p3它们很显然会占据不同区段的物理内存但经过系统的变换和映射它们的虚拟内存的布局是完全一样的。 PMPhysical Memory物理内存。VMVirtual Memory虚拟内存。 将其中一个C语言含如进程的虚拟内存放大来看会发现其内部包下区域 栈stack堆heap数据段代码段 虚拟内存中内核区段对于应用程序而言是禁闭的它们用于存放操作系统的关键性代码另外由于 Linux 系统的历史性原因在虚拟内存的最底端 0x0 ~ 0x08048000 之间也有一段禁闭的区段该区段也是不可访问的。 虚拟内存中各个区段的详细内容: 栈内存 什么东西存储在栈内存中 环境变量 比如库文件的路径、头文件的路径、可执行文件的路径等都被记录与环境变量中命令行参数  比如执行程序时从命令行中携带的参数./a.out 123 456 Hello  局部变量包括形参  所有在函数体内定义的变量栈内存有什么特点 空间有限尤其在嵌入式环境下。因此不可以用来存储尺寸太大的变量。每当一个函数被调用栈就会向下增长一段用以存储该函数的局部变量。每当一个函数退出栈就会向上缩减一段将该函数的局部变量所占内存归还给系统。 注意 栈内存的分配和释放都是由系统规定的我们无法干预。 void func(int a, int *p) // 在函数 func 的栈内存中分配 {double f1, f2; // 在函数 func 的栈内存中分配... // 退出函数 func 时系统的栈向上缩减释放内存 }int main(void) {int m 100; // 在函数 main 的栈内存中分配func(m, m); // 调用func时系统的栈内存向下增长 } 地址验证 #include stdio.h #include stdlib.hint main(int argc, char const *argv[]) {char * path getenv(PATH);int a 123 ;char * ptr NULL ;// 输出各项地址 高地址 -- 低地址printf(***********环境变量**********\n);printf(path:%p\n , path );printf(***********命令行参数**********\n);for (int i 0; i argc; i){printf(argv[%d]:%p\n , i , argv[i] );}printf(***********局部变量**********\n);printf(argc:%p\n , argc);printf(argv:%p\n , argv);printf(path:%p\n , path);printf(a:%p\n , a);printf(ptr:%p\n , ptr);return 0; }静态数据 C语言中静态数据有两种 全局变量定义在函数外部的变量。 定义在函数体之外静态局部变量定义在函数内部且被static修饰的局部变量。示例 int a; // 全局变量退出整个程序之前不会释放 void f(void) {static int b; // 静态局部变量退出整个程序之前不会释放printf(%d\n, b);b; }int main(void) {f();f(); // 重复调用函数 f()会使静态局部变量 b 的值不断增大 } 为什么需要静态数据 全局变量在默认的情况下对所有文件可见为某些需要在各个不同文件和函数间访问的数据提供操作上的方便。当我们希望一个函数退出后依然能保留局部变量的值以便于下次调用时还能用时记录上一次调用时的状态静态局部变量可帮助实现这样的功能。 注意1 若定义时未初始化则系统会将所有的静态数据自动初始化为0静态数据初始化语句只会执行一遍。静态数据从程序开始运行时便已存在直到程序退出时才释放。注意2 static修饰局部变量使之由栈内存临时数据变成了静态数据存储于数据段中。static修饰全局变量使之由各文件可见的静态数据变成了本文件可见的静态数据。static修饰函数使之由各文件可见的函数变成了本文件可见的静态函数。 数据段存储静态数据与代码段 数据段细分成如下几个区域 .bss 段存放未初始化的静态数据它们将被系统自动初始化为0.data段存放已初始化的静态数据.rodata段存放常量数据 ro - read Only 代码段细分成如下几个区域 .text段存放用户代码 (比如自己写的函数 main \ func \ test).init段存放系统初始化代码( 由对应的编译器自动添加到程序中去 用于初始化该程序的内存空间) int a; // 未初始化的全局变量放置在.bss 中 int b 100; // 已初始化的全局变量放置在.data 中int main(void) {static int c; // 未初始化的静态局部变量放置在.bss 中static int d 200; // 已初始化的静态局部变量放置在.data 中// 以上代码中的常量100、200防止在.rodata 中 }注意数据段和代码段内存的分配和释放都是由系统规定的我们无法干预。 const static 同时修饰一个变量 // 被static 修饰后 kk 的内存在数据段中申请 // 再加一个 修改 const 则修饰为 read only 数据 // 最终 kK 的内存被分配到 .rodata const static int kk 123 ; // 存储于.rodata 不允许修改 // int * p_kk kk ; // *p_kk 4333 ; // 尝试从侧面偷偷修改这个数据会导致段错误// const 修改一个普通的变量并不会改变该变量的存储区域因此它依然在栈中 const int bb 456 ; // 存储于栈 可以被偷偷修改 int * p_bb bb ; *p_bb 45435 ; printf(bb:%d\n , bb );堆内存 堆内存heap又被称为动态内存、自由内存简称堆。堆是唯一可被开发者自定义的区段开发者可以根据需要申请内存的大小、决定使用的时间长短等。但又由于这是一块系统“飞地”所有的细节均由开发者自己把握系统不对此做任何干预给予开发者绝对的“自由”但也正因如此对开发者的内存管理提出了很高的要求。对堆内存的合理使用几乎是软件开发中的一个永恒的话题。 堆内存基本特征 相比栈内存堆的总大小仅受限于物理内存在物理内存允许的范围内系统对堆内存的申请不做限制。相比栈内存堆内存从下往上增长。堆内存是匿名的只能由指针来访问。自定义分配的堆内存除非开发者主动释放否则永不释放直到程序退出。 相关API 申请堆内存malloc() / calloc() /realloc () / reallocarray()清零堆内存bzero()设置内存值memset ()释放堆内存free() API 分析 malloc (配置内存空间) 头文件 #include stdlib.h 定义函数 void *malloc(size_t size); 参数分析size -- 需要申请的堆内存区的大小 返回值若配置成功则返回一指针指向该内存区失败则返回 NULL. free (释放原先配置的内存) 头文件#include stdlib.h 定义函数void free(void *ptr); 参数分析ptr -- 需要释放的内存空间的【入口地址】 返回值无 calloc (配置内存空间) 该函会把申请到的内存空间进行初始化清空为 0 而malloc 则不会进行初始化操作 头文件:#include stdlib.h 定义函数:void *calloc(size_t nmemb, size_t size); 参数分析nmemb -- 需要申请连续内存卡的数量size -- 每一个内存块的大小 返回值成功 返回成功申请到的堆内存地址失败 返回 NULL memset (将一段内存空间填入某值) 头文件#include string.h 定义函数void * memset(void *s, int c, size_t n); 参数分析:s -- 需要设置的数据c -- 需要设置的具体数据的值 【必须是 一个字节的大小 0 - 255】n -- 需要设置的内存区大小 返回值成功返回 s 指针失败返回NULL 实例 // 进按字节行设置 // 从ptr 开始 按【每一个字节】填入一个 97 一共填入 6个 memset( ptr , 97 , 6 ); memset( ptr , a , 6 ); bzero ( ptr , 6 ) ; // 设置ptr 的前6个字节的内存空间为 0 realloc (重新对堆内存空间进行调整大小) void *realloc(void *ptr, size_t size); 参数分析ptr -- 需要重新设置的内存入口地址size -- 新的大小 , 如果为 0 则相当于free 释放现有的内存 返回值成功 返回新的入口地址 并free原先的地址失败 返回NULL 注意 如果发生地址移动则该函数会释放原先的地址         并把原先内存中的数据拷贝到新地址中         如果是缩小的一般会不出现新的地址 但是后面的数据不应该再进行访问属于非法。 reallocarray (重新对堆内存空间进行调整大小) void *reallocarray(void *ptr, size_t nmemb, size_t size);函数分析ptr -- 需要调整大小的地址nmemb -- 新内存的数量 多少块size -- 每一块的大小返回值成功 返回新的入口地址 并free原先的地址失败 返回NULL 注意 malloc()申请的堆内存默认情况下是随机值(不会清空内存)一般需要用 bzero() 、 memset() 来清零。calloc()申请的堆内存默认情况下是已经清零了的不需要再清零。free()只能释放堆内存并且只能释放整块堆内存(并且参数ptr必须是申请时的入口地址)不能释放别的区段的内存或者释放一部分堆内存。 释放内存的含义 释放内存意味着将内存的使用权归还给系统。释放内存并不会改变指针的指向。释放内存并不会对内存做任何修改更不会将内存清零。因此在freeptr 之后ptr 变成了一个野指针 应该 ptr NULL ; 三、字符操作函数 函数strstr 示例 char *s abcd.txt; char *p strstr(s, .wps);if(p NULL)printf(文件[%s]不是WPS文件\n, s); elseprintf(文件[%s]是WPS文件\n, s); 函数strlen 示例 char *s www.yueqian.com.cn; printf(粤嵌官网地址的长度是%d\n, strlen(s)); strlen与sizeof的区别 char * msg Hello \0 Even Nihao GZ2351;// strlen 计算的过程中遇到 \0 结束符则直接停止工作// 因此, 对于以上例子中 msg 内有 \0 则结算到该结束符就停止计算并返回size_t len strlen(msg);printf(Len:%ld\n , len );// strlen 与sizeof 的区别// strlen 计算的是字符串的长度// sizeof 计算的是变量或类型的大小size_t size sizeof(msg);printf(size:%ld\n , size);char arr [] Hello GZ2351;printf(strlen(arr):%ld\n , strlen(arr)); // 计算数据的长度printf(sizeof(arr):%ld\n , sizeof(arr)); // 计算变量的大小// bzero(arr , 100);// 数组总大小 / 某个元素大小 * 每一个元素的尺寸 数组所占内存尺寸memset(arr , 0 , sizeof(arr)/sizeof(arr[0]) * sizeof(char) );printf(strlen(arr):%ld\n , strlen(arr)); // 计算数据的长度 0printf(sizeof(arr):%ld\n , sizeof(arr)); // 计算变量的大小 100 函数strtok 注意 该函数会将改变原始字符串 str使其所包含的所有分隔符变成结束标记 ‘\0’ 。由于该函数需要更改字符串 str因此 str 指向的内存必须是可写的。首次调用时 str 指向原始字符串此后每次调用 str 用 NULL 代替。参数delim 是一个字符串实际上会认为给字符串中的没有给字符都是分隔符。如 delime -; 在分割的过程中只要与到- 或 或 ; 都会进行分割 示例 char s[20] www.yueqian.com.cn;char *p strtok(s, .); // 首次调用时s 指向需要分割的字符串 while(p ! NULL) {printf(%s\n, p);p strtok(NULL, .); // 此后每次调用均使用 NULL 代替。 }注上述代码的运行结果就是将字符串 s 拆解为www、“yueqian”、“com” 和 “cn” 函数strcat与strncat 注意 这两个函数的功能都是将 src 中的字符串复制拼接到 dest 的末尾。strcat() 没有边界控制因此可能会由于 src 的过长而导致内存溢出。strncat() 有边界控制最多复制 n1 个字符其中最后一个是 ‘\0’ 到 dest 的末尾。 n 的大小应该通过计算得到 目标地址的空余量 - 1 示例 char s1[10] abc; strcat(s1, xyz); printf(%s\n, s1); // 输出 abcxyzchar s2[10] abc; strcat(s3, 123456789); // 此处操作内存溢出可能会发生内存崩溃char s[10] abc; strncat(s, 123456789, sizeof(s)-strlen(s)-1); printf(%s\n, s); // 输出 abc123456两个字符串被拼接到了一起且不会溢出注意strncat()是具备边界检查的安全版本推荐使用。 函数strcpy与strncpy 注意 这两个函数的功能都是将 src 中的字符串复制到 dest 中。strcpy() 没有边界控制因此可能会由于 src 的过长而导致内存溢出。strncpy() 有边界控制最多复制 n-1 个字符其中最后一个是 ‘\0’ 到 dest 中。 char s1[5] abc; strcpy(s1, xyz); printf(%s\n, s1); // 输出 xyz原有的abc被覆盖char s2[5] abc; strcpy(s2, 123456789); // 此处操作内存溢出可能会发生内存崩溃 注意strncpy()是具备边界检查的安全版本推荐使用。 函数strcmp与strncmp 注意 比较字符串大小实际上比较的是字符的 ASCII码值的大小。从左到右逐个比较两个字符串的每一个字符当能“决出胜负”时立刻停止比较。示例 printf(%d\n, strcmp(abc, abc)); // 输出0两个字符串相等 printf(%d\n, strcmp(abc, aBc)); // 输出1abc 大于 aBc printf(%d\n, strcmp(999, aaa)); // 输出-1999 小于 aaa 函数strchr与strrchr 注意 这两个函数的功能都是在指定的字符串 s 中试图找到字符 c。strchr() 从左往右找strrchr() 从右往左找。字符串结束标记 ‘\0’ 被认为是字符串的一部分。 memcmp (比较内存内容) 头文件:#include string.h 定义函数:int memcmp (const void *s1, const void *s2, size_t n); 参数分析s1 -- 需要比较的内存1 s2 -- 需要比较的内存1 n -- 需要比较的内存区大小 返回值相同 返回 0 不同 返回差值memcpy (内存内容的拷贝) 头文件#include string.h 函数原型void *memcpy(void *dest, const void *src, size_t n); 参数分析 dest -- 目标地址src -- 原地址n -- 期望拷贝的字节数 返回值成功返回 dest 失败返回 NULL 总结 strxxxx 类型的函数在执行过程中有多个结束条件 遇到字符串中的 \0 结束符                        如果strnxxx 则到达一个指定的大小条件 strcpy( buf1 , buf2 ); // 结束条件只有一个 遇到\0 结束符 strncpy( buf1 , buf2 , 10 ); // 结束条件有两个 遇到\0 结束符 达到期望值10个字节 memxxx 类型的函数他执行过程中只有一个结束条件就是达到用户的期望值。遇到结束符则把结束符也当成比较或拷贝的目标。 四、总结 本文介绍了C的编程时各代码位置的实际分布内存还有字符操作函数等其他知识。理解本文所有知识点后便可打败其中的小怪拿下经验值~         本文参照 粤嵌文哥 部分课件经整理和修改后发布在C站如有转载请联系本人
http://www.zqtcl.cn/news/349019/

相关文章:

  • 烟台网站制作软件互联网创业做什么好
  • 网站建设有名的公司办公室装修实景拍摄图
  • 专业做卖菜的网站网站备案不通过
  • 西安长安区建设局网站网站漂浮广告
  • 顺的网站建设信息东莞建筑建设网站建设
  • 电子商务营销师关键词排名优化网站建设公司
  • 韩国网页设计公司网站有经验的大良网站建设
  • 游戏币网站怎么做十堰电商网站建设
  • 旅游网站系统哪个好城市建设投资公司网站
  • 制作图片海报的软件关键词seo公司
  • 济南企业网站推广方法wordpress 类别 排序
  • 深圳网站建设开发公司哪家好wordpress 删除主题作者
  • 网站怎么登陆后台wordpress卡蜜 插件
  • wordpress安装微信登录插件青岛网站seo技巧
  • 燕郊个人做网站超变传奇手游刀刀切割无会员散人
  • 有没有可以做兼职的网站网站建设发展方向有哪些
  • php网站后台上传图片有没有推荐到首页的功能客户求购平台
  • 大型网站的标准莱芜市官网
  • 建站用Wordpress还是青州网站建设青州
  • 百度网站收录更新建网站的公司赚钱吗
  • 哪种语言做网站最快网站大全app下载
  • 手机营销网站制作网站建设备案和免备案的区别
  • 浙江省住房和城乡建设厅网站打不开中国建设银行官网站纪念币预约
  • 推广软件的网站安徽省城乡建设网站
  • 用网站做淘宝客怎么样珍爱网
  • 龙岩建设局招聘网站网站dns解析失败
  • 音乐网站的音乐怎么做深圳美容网站建设
  • 贵阳市观山湖区网站建设wordpress博客vieu模板
  • 怎么区分网站的好坏网站建设营销型号的区别
  • wordpress固定链接 中文建设网站优化