嵌入式Linux上的C语言编程实践--第13章 C语言程序的内存布局
嵌入式系统C语言编程基础PPT课件
精选ppt
小测验?
精选ppt
Quiz 1
• 所有嵌入式系统的主流程最后都进入一个 死循环,怎样用C语言实现一个死循环?
精选ppt
Quiz 2
• while(){….}和do{….}while()有什么区别?
精选ppt
Quiz 3
• 用变量a给出下列定义:
a) 一个整型数 b) 一个指向整型数的指针 c) 一个有10个整型数的的数组 d) 一个有10个指针的数组,该指针是指向一个整型
精选ppt
Quiz 10
• 请评论下面一段程序代码: void test() { char string[10]; char *str = “0123456789”; strcpy(string,str); }
精选ppt
Quiz 11
• 请评论下面一段程序代码: void GetMemory(char *p){ p = (char *)malloc(0x20); } void Test(void){ char *str = NULL; GetMemory(str); strcpy(str,”Hello World!”); printf(str); }
数的
精选ppt
Quiz 4
• 关键字static的作用是什么?
精选ppt
Quiz 5
• 关键字const的作用是什么?
精选ppt
Quiz 6
• 定义一个标准宏MIN ,这个宏输入两个参 数并返回较小的一个。
精选ppt
Quiz 7
• 嵌入式系统中经常要对变量或寄存器进行 位操作。给定一个int型变量a,写两段代码, 第一个将a的bit 3置为1,第二个将a的bit 3 置为0。以上两个操作中,要保持其它位不 变。
C语言操作系统编程进程管理和内存管理
C语言操作系统编程进程管理和内存管理1. 概述操作系统是计算机系统中最核心的软件之一,它负责管理计算机的硬件资源并提供应用程序运行的环境。
编写操作系统需要掌握底层硬件知识、算法与数据结构以及编程语言。
本文将重点介绍C语言在操作系统编程中的进程管理和内存管理实践。
2. 进程管理2.1 进程与线程的概念在操作系统中,进程是指一个正在运行的程序实例,它具有自己的内存空间、代码、数据和文件等资源。
线程是进程的执行单元,一个进程可以拥有多个线程,它们共享进程的资源。
2.2 进程创建和销毁在C语言中,可以利用操作系统提供的API来创建和销毁进程。
常用的API包括`fork()`、`exec()`和`exit()`等。
`fork()`函数可以创建一个新的进程,`exec()`函数可以用新的程序替换当前进程的代码和数据段,`exit()`函数可以正常或异常地退出进程。
2.3 进程调度进程调度决定了系统中哪个进程在什么时候运行。
C语言通过操作系统提供的API进行进程调度,如`sched_yield()`函数可以让出CPU,`sleep()`函数可以使进程进入休眠状态。
此外,还可以使用多线程编程来实现并发执行。
3. 内存管理3.1 内存模型在操作系统中,内存被划分为多个区域,如代码段、数据段、堆和栈等。
C语言程序的内存布局包括:全局变量、静态变量、堆、栈等。
3.2 动态内存分配动态内存分配是指程序在运行过程中根据需要动态地分配和释放内存。
C语言提供了`malloc()`和`free()`函数来实现动态内存分配。
使用时应注意避免内存泄漏和悬空指针等问题。
3.3 内存保护和地址空间操作系统通过内存保护机制来避免不同进程之间的内存访问冲突。
C语言通过指针操作来访问内存,需要合理地使用指针,并通过操作系统提供的API实现内存保护。
4. 示例代码以下是一个简单的示例代码,演示了C语言操作系统编程中的进程管理和内存管理:```c#include <stdio.h>#include <stdlib.h>int main() {// 创建子进程int pid = fork();if (pid < 0) {printf("进程创建失败\n");exit(1);} else if (pid == 0) {// 子进程执行的代码printf("子进程ID:%d\n", getpid()); printf("父进程ID:%d\n", getppid()); exit(0);} else {// 父进程执行的代码printf("父进程ID:%d\n", getpid()); printf("子进程ID:%d\n", pid);}return 0;}```5. 总结本文介绍了C语言操作系统编程中的进程管理和内存管理。
嵌入式c语言程序设计
嵌入式c语言程序设计嵌入式C语言程序设计嵌入式C语言程序设计是指在嵌入式系统中使用C语言进行编程的一种技术。
嵌入式系统是指被嵌入到其他设备中的计算机系统,它通常具有特定的功能和任务。
嵌入式C语言程序设计具有高效、灵活、可移植等特点,因此在嵌入式系统开发中得到广泛应用。
一、嵌入式系统概述嵌入式系统广泛应用于各个领域,如消费电子、汽车电子、医疗设备、工业控制等。
嵌入式系统通常由处理器、存储器、输入输出设备和特定功能模块等组成。
与通用计算机系统相比,嵌入式系统的资源有限,因此需要对程序进行精简和优化,以满足系统的实时性和可靠性要求。
二、嵌入式C语言的特点1. 简洁高效:C语言是一种高级语言,具有简洁、高效的特点。
使用C语言可以以较少的代码实现复杂的功能,提高开发效率和系统性能。
2. 可移植性强:C语言是一种可移植性较强的语言。
嵌入式C语言程序可以在不同的嵌入式系统上进行移植,只需做出适当的修改即可。
3. 丰富的库函数支持:C语言提供了丰富的库函数,如字符串处理、数学计算、文件操作等,方便开发人员进行程序设计。
4. 直接访问硬件:嵌入式C语言程序可以直接访问硬件资源,如寄存器、外设等,使得程序可以更加灵活和高效地控制系统。
三、嵌入式C语言程序设计的基本原则1. 软硬件接口设计:嵌入式C语言程序需要与硬件进行交互,因此需要设计合理的软硬件接口,确保程序能够正确地访问硬件资源。
2. 系统资源管理:嵌入式系统的资源有限,因此需要合理地管理系统资源,包括内存、处理器时间、外设等,以满足系统的实时性和可靠性要求。
3. 实时性要求:嵌入式系统通常需要实时响应外部事件,因此嵌入式C语言程序需要按时完成任务,避免出现延迟或死锁等问题。
4. 代码优化:嵌入式系统的资源有限,因此需要对程序进行优化,以减少代码量、提高运行效率和节约资源消耗。
5. 异常处理:嵌入式系统可能会面临各种异常情况,如硬件故障、通信异常等,嵌入式C语言程序需要具备相应的异常处理机制,以保证系统的稳定性和可靠性。
《C语言程序设计》(第2版)苏小红-13章 12
2021/7/31
40/60
struct sample {
short i; char ch; float f; };
union sample {
short i; char ch; float f; };
2021/7/31
共用体
【例12.8】
printf("%d\n", sizeof(struct sample));
Before function call:1999/04/23 After function call:2000/05/22
指针作函数形参 实参必须为地址值
2021/7/31
33/60
struct date
{
int year; int month;
结构体变量
int day; };
作函数返回值
struct date Func(struct date p)
2021/7/31
【例12.3】利用 结构体数组计 算每个学生的 平均分
25/60
结构体指针的定义和初始化
如何定义指向结构体变量的指针?
pt STUDENT stu1; STUDENT *pt; pt = &stu1;
等价于
STUDENT *pt = &stu1;
stu1 成员1 成员2 成员3 成员4
i ch
f
8个字节
printf("%d\n", sizeof(union sample));
0x0037b00
cfih
4个字节 41/60
共用体
sizeof(union number)取决于占空间最多的那个成员 变量
同一内存单元在每一瞬时只能存放其中一种类型的成员 起作用的成员是最后一次存放的成员,不能作为函数参数 不能进行比较操作,只能对第一个成员初始化
c语言的内存结构
c语言的内存结构C语言是一种高级编程语言,但实际上在计算机中运行时,C语言程序会被编译成可执行文件,然后在计算机内存中运行。
因此,了解C 语言的内存结构对于理解C程序的运行及性能优化至关重要。
C语言的内存结构主要可以分为以下几个部分:栈(Stack)、堆(Heap)、全局内存(Global Memory)和代码区(Code Segment)。
首先是栈(Stack),栈是一种自动分配和释放内存的数据结构。
它用于存储局部变量、函数参数和函数调用信息等。
栈的特点是后进先出(LIFO),也就是最后进入的数据最先被释放。
栈的大小在程序运行时是固定的,一般由编译器设置。
栈的操作速度较快,但内存空间有限。
其次是堆(Heap),堆是一种动态分配和释放内存的数据结构。
它用于存储动态分配的变量、数据结构和对象等。
堆的大小一般由操作系统管理,并且可以在运行时进行动态扩展。
堆的操作相对较慢,因为需要手动分配和释放内存,并且容易产生内存碎片。
全局内存(Global Memory)是用于存储全局变量和静态变量的区域。
全局变量在程序的生命周期内都存在,并且可以在多个函数之间共享。
静态变量作用于其所在的函数内,但是生命周期与全局变量相同。
全局内存由编译器进行分配和管理。
代码区(Code Segment)存储了程序的指令集合,它是只读的。
在程序运行时,代码区的指令会被一条一条地执行。
代码区的大小由编译器决定,并且在程序执行过程中不能修改。
此外,C语言还具有特殊的内存区域,如常量区和字符串常量区。
常量区用于存储常量数据,如字符串常量和全局常量等。
常量区的数据是只读的,且在程序的整个生命周期内存在。
字符串常量区是常量区的一个子区域,用于存储字符串常量。
在C语言中,内存分配和释放是程序员的责任。
通过使用malloc和free等函数,程序员可以在堆中动态地分配和释放内存,从而灵活地管理程序的内存使用。
不过,应当注意避免内存泄漏和野指针等问题,以免出现内存错误和性能问题。
嵌入式系统中的内存管理
嵌入式系统中的内存管理在嵌入式系统中,内存管理是一个至关重要的问题。
嵌入式系统通常运行在有限的资源和功耗的环境中,因此合理而高效地管理内存资源是确保系统性能和稳定性的关键所在。
本文将探讨嵌入式系统中的内存管理策略和技术,并提供一些实用的建议。
一、静态内存管理静态内存管理是嵌入式系统中常用的一种内存管理方法。
在此方法中,内存的分配工作在编译时就完成了。
静态内存管理适用于那些内存需求在编译时可以确定的情况,例如固定大小的数据结构或全局变量。
这种方法的好处是简单且效率高,但是不适用于动态内存需求频繁变化的情况。
二、动态内存管理动态内存管理是指在程序运行时通过动态分配和释放内存来满足程序的需求。
在嵌入式系统中,常用的动态内存管理方式是使用堆来进行内存分配。
堆是由操作系统或者嵌入式系统的运行时库所管理的一块内存空间,程序可以通过申请和释放堆内存来满足其动态内存需求。
在使用动态内存管理的过程中,需要注意以下几点:1. 内存泄漏的风险动态内存管理需要程序员手动申请和释放内存,如果未正确释放已分配的内存,就会导致内存泄漏的问题。
内存泄漏会导致系统性能下降和稳定性问题,并可能最终导致系统崩溃。
因此,在使用动态内存管理时,务必要注意正确释放已分配的内存空间,避免内存泄漏的发生。
2. 内存碎片的处理动态内存分配往往会产生内存碎片问题。
内存碎片是指内存中存在一些空闲但不连续的小块内存,这会导致内存利用率降低。
为了避免内存碎片问题,可以采用内存池技术,将内存按照固定大小的块进行划分,并预先分配给程序使用。
这样可以最大程度地减少内存碎片,提高内存利用率。
3. 内存分配算法的选择在动态内存管理中,选择合适的内存分配算法也非常重要。
常见的内存分配算法包括First Fit、Best Fit和Worst Fit等。
不同的算法有着不同的优缺点,因此在选择时需要根据具体情况进行权衡。
例如,First Fit算法简单高效,但容易产生内存碎片;而Best Fit算法可以最小化碎片问题,但是分配效率较低。
《C语言程序设计》教案(清华谭浩强)
《C语言程序设计》教案(清华谭浩强)第一章:C语言概述1.1 课程介绍介绍C语言的历史和发展解释C语言的特点和应用范围强调学习C语言的重要性和目的1.2 C语言的基本概念解释编程语言和编译器的概念介绍C语言的基本数据类型和变量讲解C语言的语法结构和程序结构1.3 C语言的编译过程解释编译器的角色和功能介绍编译过程中的预处理、编译、汇编和步骤强调编译过程中产生的文件和它们的作用第二章:基本数据类型和运算符2.1 基本数据类型介绍整型、浮点型、字符型和布尔型的概念和用法解释不同数据类型的存储方式和大小强调数据类型的选择和使用场景2.2 变量和常量解释变量的概念和作用介绍变量的声明和初始化方法讲解常量的概念和用法2.3 运算符介绍算术运算符、关系运算符和逻辑运算符的概念和用法解释赋值运算符和条件运算符的作用强调不同运算符的优先级和使用规则第三章:控制语句3.1 条件语句介绍if语句的语法和用法讲解switch语句的概念和用法强调条件语句的选择和嵌套使用3.2 循环语句介绍for循环、while循环和do-while循环的概念和用法解释循环控制语句如break和continue的作用强调循环条件的设置和循环次数的控制3.3 跳转语句介绍goto语句的概念和用法讲解label标签的作用和跳转规则强调跳转语句的使用场景和可能导致的问题第四章:函数和指针4.1 函数的基本概念介绍函数的定义和声明讲解函数的参数传递和返回值强调函数的命名规则和命名规范4.2 指针的概念和用法解释指针的概念和作用介绍指针的声明和初始化方法讲解指针的赋值和指针运算4.3 指针和数组介绍数组的概念和用法解释指针和数组的关系强调指针在数组操作中的应用第五章:结构体和文件操作5.1 结构体的概念和用法介绍结构体的定义和声明讲解结构体的成员访问和内存布局强调结构体在数据组织中的应用5.2 文件操作的基本概念解释文件的概念和文件操作的重要性介绍文件打开、读写、关闭等操作的方法强调文件操作中的错误处理和文件指针的管理第六章:动态内存分配6.1 动态内存分配的概念介绍动态内存分配的原因和必要性解释malloc、calloc和realloc函数的作用和用法强调动态内存分配的注意事项和错误处理6.2 链表的概念和用法介绍链表的定义和结构讲解链表的创建、插入、删除和遍历操作强调链表的优势和应用场景6.3 动态内存分配的应用实例通过实例演示动态内存分配在实际编程中的应用讲解内存泄漏和内存溢出的概念强调编写高效和安全的程序的重要性第七章:字符串处理7.1 字符串的基本概念介绍字符串的定义和表示方法解释字符串的长度和字符串的结束标志强调字符串与数组的区别和联系7.2 字符串的常用函数介绍字符串的输入输出函数如printf和scanf 讲解字符串的拷贝、连接、比较等操作函数强调字符串处理函数的使用和注意事项7.3 字符串处理的应用实例通过实例演示字符串处理在实际编程中的应用讲解字符串排序、查找和替换等操作强调字符串处理在文本分析和数据处理中的应用第八章:标准库函数8.1 标准输入输出库函数介绍标准输入输出库stdio.h中的常用函数讲解文件读写、数据转换等函数的用法和功能强调标准库函数的使用场景和注意事项8.2 字符串处理库函数介绍字符串处理库string.h中的常用函数讲解字符串比较、查找和替换等函数的用法和功能强调字符串处理库函数的使用和与其他库函数的配合8.3 数学计算库函数介绍数学计算库math.h中的常用函数讲解数学运算、三角函数和指数函数等函数的用法和功能强调数学计算库函数在数学计算和科学计算中的应用第九章:并发编程和同步机制9.1 并发编程的基本概念介绍并发编程的定义和目的解释进程和线程的概念和关系强调并发编程的优势和挑战9.2 并发编程的同步机制介绍互斥锁、条件变量和信号量等同步机制的原理和用法讲解同步机制在多线程编程中的应用和注意事项强调同步机制在避免竞态条件和数据一致性中的重要性9.3 并发编程的应用实例通过实例演示并发编程在实际应用中的优势和挑战讲解多线程的创建、同步和通信等操作强调并发编程在多任务处理和性能优化中的应用第十章:C语言编程实践10.1 编程实践的重要性强调编程实践在学习和掌握C语言中的重要性解释编程实践对于提高编程能力和解决问题的作用强调编程实践中的代码质量和编程规范10.2 编程实践的项目和案例介绍常见的编程实践项目和案例讲解实际编程中的问题解决方法和技巧强调编程实践中的调试和测试的重要性10.3 编程实践的资源和工具介绍编程实践中的常用工具和环境讲解集成开发环境(IDE)的使用和代码管理强调编程实践中的团队合作和代码分享的重要性重点和难点解析重点环节1:C语言的基本概念和特点需要重点关注C语言的历史和发展,以及其特点和应用范围。
进程的内存空间布局
进程的内存空间布局进程的内存布局在结构上是有规律的,具体来说对于 linux 系统上的进程,其内存空间⼀般可以粗略地分为以下⼏⼤段【1】,从⾼内存到低内存排列:1、内核态内存空间,其⼤⼩⼀般⽐较固定(可以编译时调整),但 32 位系统和 64 位系统的值不⼀样。
2、⽤户态的堆栈,⼤⼩不固定,可以⽤ ulimit -s 进⾏调整,默认⼀般为 8M,从⾼地址向低地址增长。
3、mmap 区域,进程茫茫内存空间⾥的主要部分,既可以从⾼地址到低地址延伸(所谓 flexible layout),也可以从低到⾼延伸(所谓 legacy layout),看进程具体情况【2】【3】。
4、brk 区域,紧邻数据段(甚⾄贴着),从低位向⾼位伸展,但它的⼤⼩主要取决于 mmap 如何增长,⼀般来说,即使是 32 位的进程以传统⽅式延伸,也有差不多 1 GB 的空间(准确地说是 TASK_SIZE/3 - 代码段数据段,参看 arch/x86/include/asm/processor.h ⾥的定义)【4】5、数据段,主要是进程⾥初始化和未初始化的全局数据总和,当然还有编译器⽣成⼀些辅助数据结构等等),⼤⼩取决于具体进程,其位置紧贴着代码段。
6、代码段,主要是进程的指令,包括⽤户代码和编译器⽣成的辅助代码,其⼤⼩取决于具体程序,但起始位置根据 32 位还是 64 位⼀般固定(-fPIC, -fPIE等除外【5】)。
以上各段(除了代码段数据段)其起始位置根据系统是否起⽤ randomize_va_space ⼀般稍有变化,各段之间因此可能有随机⼤⼩的间隔,千⾔万语不如⼀幅图(x86-32位下):32位下bash进程的⽰例:【1】【2】understanding the linux kernel, page 819, flexible memory region layout: 【3】【4】【5】。
嵌入式Linux C语言应用开发教程(移动学习版 第2版)
6.3进程间通7.1 TCP/IP 概述
2
7.2网络编程 基本知识
3
7.3网络高级 编程
4 7.4实验内容:
NTP的客户端 实现
5
思考与练习
8.2字符设备驱动 编程
8.1设备驱动编程 基础
8.3基于设备树的 字符驱动程序实例
8.5按键驱动程序 实例
读书笔记
这是《嵌入式Linux C语言应用开发教程(移动学习版 第2版)》的读书笔记模板,可以替换为自己的心得。
精彩摘录
这是《嵌入式Linux C语言应用开发教程(移动学习版 第2版)》的读书笔记模板,可以替换为自己的精彩 内容摘录。
感谢观看
8.4 GPIO驱动程序 实例
思考与练习
9.1嵌入式GUI简介
9.2 Qt/Embedded 开发入门
9.3实验内容:使用 Qt编写“Hello, World”程序
思考与练习
10.1仓库信息处理 系统概述
10.2基本数据结构
10.3功能实现 思考与练习
作者介绍
这是《嵌入式Linux C语言应用开发教程(移动学习版 第2版)》的读书笔记模板,暂无该书作者的介绍。
目录分析
一、我们致力于这样 的发展理念
二、我们致力于提供 这样的学习方式
三、我们致力于提供 这样的服务保障
四、我们期待您的加 入
1.2 ARM处理器硬 件开发平台
1.1嵌入式系统概 述
1.3嵌入式软件开 发流程
1.4实验内容: 使用SD-CARD 烧写EMMC
思考与练习
2.1嵌入式
1
Linux下C语言
概述
2
2.2编辑器vim
3
2.3编译器gcc
linux c语言 实验报告
linux c语言实验报告
《Linux C语言实验报告》
一、实验目的
本实验旨在通过使用Linux操作系统和C语言编程,掌握Linux环境下的C语
言编程技术,加深对Linux系统和C语言的理解和应用。
二、实验环境
本次实验使用的是Ubuntu操作系统,编程语言为C语言。
三、实验过程
1. 熟悉Linux环境:首先,我们需要熟悉Linux环境下的操作和命令,包括文件管理、编译和运行程序等。
2. 编写C语言程序:接着,我们编写了一些简单的C语言程序,包括输出
Hello World、计算器等功能。
3. 编译和运行程序:我们使用gcc编译器对编写的C语言程序进行编译,然后
在Linux环境下运行程序,观察程序的运行结果。
4. 调试程序:在程序运行过程中,我们发现了一些bug,通过调试程序来解决
这些问题,加深了对C语言的理解和掌握。
四、实验结果
通过本次实验,我们成功掌握了Linux环境下的C语言编程技术,能够熟练地
使用gcc编译器对C语言程序进行编译,并在Linux环境下运行程序。
同时,
我们也加深了对C语言的理解和应用,对程序的调试和优化有了更深入的认识。
五、实验总结
本次实验使我们对Linux操作系统和C语言编程有了更深入的了解,提高了我
们的编程能力和解决问题的能力。
同时,也为我们今后在Linux环境下进行软
件开发打下了良好的基础。
通过本次实验,我们不仅学到了很多知识,也提高了我们的动手能力和实际操
作能力。
我们相信,在今后的学习和工作中,这些知识和能力都会派上大用场。
C语言的内存分配详解
堆内存的分配与释放
堆空间申请、释放的方法
在C++中,申请和释放堆中分配的存贮空间, 中 申请和释放堆中分配的存贮空间, 分别使用new和delete的两个运算符来完成: 分别使用 和 的两个运算符来完成: 的两个运算符来完成 指针变量名=new 类型名 初始化式 ; 类型名(初始化式 初始化式); 指针变量名 delete 指针名 指针名; 例如: 例如:1、 int *pi=new int(0); 它与下列代码序列大体等价: 它与下列代码序列大体等价: 2、int ival=0, *pi=&ival; 区别:pi所指向的变量是由库操作符new()分配的 所指向的变量是由库操作符new()分配的, 区别:pi所指向的变量是由库操作符new()分配的, 位于程序的堆区中,并且该对象未命名 该对象未命名。 位于程序的堆区中,并且该对象未命名。
堆的概念
通常定义变量(或对象),编译器在编译时都可 通常定义变量(或对象),编译器在编译时都可 ), 以根据该变量(或对象)的类型知道所需内存空间的大小, 以根据该变量(或对象)的类型知道所需内存空间的大小,从 而系统在适当的时候为他们分配确定的存储空间。 而系统在适当的时候为他们分配确定的存储空间。这种内存分 配称为静态存储分配 静态存储分配; 配称为静态存储分配; 有些操作对象只在程序运行时才能确定, 有些操作对象只在程序运行时才能确定,这样编译时就 无法为他们预定存储空间,只能在程序运行时, 无法为他们预定存储空间,只能在程序运行时,系统根据运行 时的要求进行内存分配,这种方法称为动态存储分配 动态存储分配。 时的要求进行内存分配,这种方法称为动态存储分配。所有动 态存储分配都在堆区中进行。 态存储分配都在堆区中进行。 当程序运行到需要一个动态分配的变量或对象时, 当程序运行到需要一个动态分配的变量或对象时,必须 向系统申请取得堆中的一块所需大小的存贮空间, 申请取得堆中的一块所需大小的存贮空间 向系统申请取得堆中的一块所需大小的存贮空间,用于存贮该 变量或对象。当不再使用该变量或对象时, 变量或对象。当不再使用该变量或对象时,也就是它的生命结 束时, 显式释放它所占用的存贮空间 它所占用的存贮空间, 束时,要显式释放它所占用的存贮空间,这样系统就能对该堆 空间进行再次分配,做到重复使用有限的资源。 空间进行再次分配,做到重复使用有限的资源。
C语言程序设计第三版
c语言程序设计第三版C语言程序设计第三版是一本面向初学者和中级程序员的教材,它不仅涵盖了C语言的基础知识,还深入探讨了高级编程技巧和最佳实践。
这本书的第三版在前两版的基础上进行了更新和改进,以适应现代编程环境和教学需求。
第一章:C语言简介本章介绍了C语言的历史和特点,包括其结构化编程的特性和在操作系统、嵌入式系统等领域的广泛应用。
同时,也简要介绍了C语言的编译和运行过程。
第二章:C语言基础这一章是C语言编程的入门,涵盖了变量、数据类型、运算符和表达式等基本概念。
通过实例代码,读者可以学习到如何声明变量、进行算术运算和逻辑运算。
第三章:控制结构控制结构是程序流程控制的核心,本章详细介绍了条件语句(if、switch)、循环语句(for、while、do-while)以及跳转语句(break、continue、goto)的使用方法和应用场景。
第四章:函数函数是C语言模块化编程的基础,本章介绍了函数的定义、声明、调用以及参数传递。
此外,还探讨了递归函数和内联函数的概念。
第五章:数组和字符串数组是存储多个数据项的集合,而字符串则是特殊的字符数组。
本章讲解了一维数组、多维数组、字符串的声明、初始化和操作,以及字符串处理函数的使用。
第六章:指针指针是C语言中非常强大的特性,它允许程序员直接操作内存地址。
本章深入讲解了指针的基本概念、指针与数组的关系、指针的算术运算以及函数指针。
第七章:结构体和联合体结构体和联合体是C语言中用于创建复杂数据结构的工具。
本章介绍了如何定义和使用结构体、联合体以及枚举类型,以及它们在实际编程中的应用。
第八章:预处理器预处理器是C语言编译过程中的一个阶段,它处理源代码中的宏定义、文件包含和条件编译等指令。
本章解释了预处理器的工作原理和常用指令。
第九章:文件操作文件操作是程序与外部世界交互的一种方式。
本章介绍了文件的打开、关闭、读写和定位等操作,以及文件指针的使用。
第十章:动态内存分配动态内存分配允许程序在运行时分配和释放内存。
c语言中内存分配的几种方式
c语言中内存分配的几种方式
在C语言中,内存的管理是非常重要的。
C语言提供了多种内存分配的方式,可以根据不同情况选择不同的方式进行内存分配。
以下是C语言中内存分配的几种方式。
1. 静态内存分配
静态内存分配是在程序编译时就确定了内存的大小和分配位置,这种方式不需要在程序运行时进行内存分配。
在C语言中,静态内存分配可以通过定义全局变量或静态变量来实现。
2. 栈内存分配
栈内存分配是指在函数内部定义的变量所分配的内存。
当函数被调用时,栈被分配一段内存用来存储函数的局部变量,当函数返回时,这段内存会被释放。
栈内存分配的好处是速度快,但是分配的内存大小受限于栈的大小。
3. 堆内存分配
堆内存分配是指程序在运行时通过malloc()函数或calloc()函数动态分配内存。
堆内存的好处是大小灵活,但是需要手动释放,否则容易出现内存泄漏的问题。
4. 内存映射文件
内存映射文件是指将一个文件映射到内存中,使得程序可以直接访问文件中的数据。
在C语言中,可以使用mmap()函数将文件映射到内存中。
总结
在C语言中,内存的管理是非常重要的。
根据不同的情况可以选择不同的内存分配方式,如静态内存分配、栈内存分配、堆内存分配和内存映射文件等。
合理的内存管理可以提高程序的性能和稳定性。
C语言内存管理堆栈和静态存储区
C语言内存管理堆栈和静态存储区C语言内存管理:堆、栈和静态存储区C语言作为一种高效而强大的编程语言,其内存管理是程序员必须掌握的重要内容之一。
本文将重点介绍C语言中的内存管理中的堆、栈以及静态存储区。
一、堆堆是C语言中用于动态内存分配的一块内存区域。
在程序运行时,可以通过函数malloc()和calloc()来申请堆空间,通过函数free()来释放堆空间。
堆的特点:1. 大小可变:堆中的内存空间大小可以在程序运行时进行动态调整。
2. 生命周期自由控制:通过malloc()或calloc()分配的堆空间,在不再使用后,需要程序员手动调用free()函数进行释放。
堆的使用场景:1. 动态数组:当程序无法预先知道数组大小时,可以使用堆来动态申请空间。
2. 链表:链表结构通常需要通过堆来进行动态内存分配。
二、栈栈是C语言中用于函数调用和局部变量存储的一块内存区域。
在函数调用过程中,栈会记录函数的调用顺序、调用参数以及局部变量等。
栈的特点:1. 后进先出:栈是一种后进先出(LIFO)的数据结构,函数调用时会依次将函数入栈,并在函数返回时依次出栈。
2. 自动管理:栈内存的分配和释放是由编译器自动完成的,程序员无需手动管理。
栈的使用场景:1. 函数调用:栈用于管理函数的调用顺序以及函数内部的局部变量。
2. 递归:递归函数的调用过程涉及到栈的递归压栈和递归出栈。
三、静态存储区静态存储区是C语言中使用static关键字声明的变量所存储的内存区域。
在程序运行期间,静态变量在内存中的位置始终不变,且仅在程序结束时才会释放。
静态存储区的特点:1. 生命周期长:静态变量在程序运行期间都存在,不依赖于函数的调用和返回。
2. 全局可访问:静态变量可以在整个程序中被访问,不受函数作用域的限制。
静态存储区的使用场景:1. 全局变量:使用static关键字声明的全局变量存储在静态存储区中,可以在整个程序中被访问。
2. 共享数据:多个函数之间需要共享的数据可以使用静态变量来实现。
C语言入门教程(精华版)
C语言入门教程(精华版)C语言是一种广泛使用的计算机编程语言,它被广泛应用于操作系统、嵌入式系统、系统软件和应用程序等领域。
C语言具有高效、灵活和可移植性强的特点,是许多高级编程语言的基础。
本教程旨在帮助初学者快速入门C语言编程,我们将从C语言的基本语法、数据类型、运算符、控制结构等方面进行讲解。
通过本教程的学习,你将能够掌握C语言的基础知识,并能够编写简单的C语言程序。
第一部分:C语言的基本语法1. 预处理器指令:用于在程序编译之前执行一些特定的操作,如包含头文件、定义宏等。
2. 主函数:C语言程序的入口点,程序从这里开始执行。
3. 变量声明:用于声明程序中使用的变量,包括变量的类型和名称。
4. 语句:C语言中的执行单元,用于执行特定的操作,如赋值、输入输出等。
5. 函数:用于实现特定的功能,可以重复使用。
在C语言中,每个语句都以分号(;)结束。
C语言中的注释用于解释代码,单行注释以两个斜杠(//)开始,多行注释以/开始,以/结束。
C语言入门教程(精华版)C语言是一种广泛使用的计算机编程语言,它被广泛应用于操作系统、嵌入式系统、系统软件和应用程序等领域。
C语言具有高效、灵活和可移植性强的特点,是许多高级编程语言的基础。
本教程旨在帮助初学者快速入门C语言编程,我们将从C语言的基本语法、数据类型、运算符、控制结构等方面进行讲解。
通过本教程的学习,你将能够掌握C语言的基础知识,并能够编写简单的C语言程序。
第一部分:C语言的基本语法1. 预处理器指令:用于在程序编译之前执行一些特定的操作,如包含头文件、定义宏等。
2. 主函数:C语言程序的入口点,程序从这里开始执行。
3. 变量声明:用于声明程序中使用的变量,包括变量的类型和名称。
4. 语句:C语言中的执行单元,用于执行特定的操作,如赋值、输入输出等。
5. 函数:用于实现特定的功能,可以重复使用。
在C语言中,每个语句都以分号(;)结束。
C语言中的注释用于解释代码,单行注释以两个斜杠(//)开始,多行注释以/开始,以/结束。
LINUXC编程
LINUXC编程Linux C编程是指在Linux系统下使用C语言进行开发和编程的过程。
Linux操作系统是一种开源操作系统,它具有高度的稳定性和可靠性,被广泛应用于嵌入式系统、服务器等领域。
而C语言是一种通用的高级编程语言,它能够以高效的方式进行系统级编程和底层开发。
因此,Linux C编程是一门非常重要的技术,并且在软件开发中起着重要的作用。
一、Linux C编程的基础知识1. Linux系统的特点:Linux是一种开源操作系统,它具有高度的稳定性、安全性和可靠性。
Linux系统使用C语言进行开发,同时还支持其他编程语言。
2. C语言的基础知识:C语言是一种通用的高级编程语言,它是以过程化的方式进行编程。
C语言具有简洁、易读、高效的特点,因此在Linux系统下使用C语言进行开发是非常合适的。
3. 开发环境的搭建:在进行Linux C编程之前,需要搭建好相应的开发环境。
常用的开发环境有GCC编译器、GNU调试器(GDB)等。
4. 基本的编程技巧:在进行Linux C编程时,需要掌握一些基本的编程技巧,例如使用makefile进行程序编译、调试程序等。
二、Linux C编程的常用功能和技术1. 进程管理:Linux是一种多进程的操作系统,因此在Linux C编程中需要掌握进程的创建、销毁、切换等操作。
2. 文件操作:Linux系统下的文件操作是一种常见的编程任务。
在Linux C编程中,可以使用标准C库提供的文件操作函数进行文件的打开、读写、关闭等操作。
3. 网络编程:网络编程是一项重要的技术。
在Linux C编程中,可以使用套接字(socket)进行网络连接、数据传输等操作。
4. 并发编程:Linux系统支持多线程编程和进程间通信(IPC)等机制,因此在Linux C编程中可以使用多线程和IPC进行并发编程。
5. 内存管理:在Linux C编程中,需要正确地进行内存分配和释放,以避免内存泄漏和内存溢出等问题。
嵌入式、C语言位操作的一些技巧汇总
嵌⼊式、C语⾔位操作的⼀些技巧汇总下⾯分享关于位操作的⼀些笔记:⼀、位操作简单介绍⾸先,以下是按位运算符:在嵌⼊式编程中,常常需要对⼀些寄存器进⾏配置,有的情况下需要改变⼀个字节中的某⼀位或者⼏位,但是⼜不想改变其它位原有的值,这时就可以使⽤按位运算符进⾏操作。
下⾯进⾏举例说明,假如有⼀个8位的TEST寄存器:当我们要设置第0位bit0的值为1时,可能会这样进⾏设置:TEST = 0x01;但是,这样设置是不够准确的,因为这时候已经同时操作到了⾼7位:bit1~bit7,如果这⾼7位没有⽤到的话,这么设置没有什么影响;但是,如果这7位正在被使⽤,结果就不是我们想要的了。
在这种情况下,我们就可以借⽤按位操作运算符进⾏配置。
对于⼆进制位操作来说,不管该位原来的值是0还是1,它跟0进⾏&运算,得到的结果都是0,⽽跟1进⾏&运算,将保持原来的值不变;不管该位原来的值是0还是1,它跟1进⾏|运算,得到的结果都是1,⽽跟0进⾏|运算,将保持原来的值不变。
所以,此时可以设置为:TEST = TEST | 0x01;其意义为:TEST寄存器的⾼7位均不变,最低位变成1了。
在实际编程中,常改写为:TEST |= 0x01;这种写法可以⼀定程度上简化代码,是 C 语⾔常⽤的⼀种编程风格。
设置寄存器的某⼀位还有另⼀种操作⽅法,以上的等价⽅法如:TEST |= (0x01 << 0);第⼏位要置1就左移⼏位。
同样的,要给TEST的低4位清0,⾼4位保持不变,可以进⾏如下配置:TEST &= 0xF0;⼆、嵌⼊式中位操作⼀些常见⽤法1、⼀个32bit数据的位、字节读取操作(1)获取单字节:#define GET_LOW_BYTE0(x) ((x >> 0) & 0x000000ff) /* 获取第0个字节 */#define GET_LOW_BYTE1(x) ((x >> 8) & 0x000000ff) /* 获取第1个字节 */#define GET_LOW_BYTE2(x) ((x >> 16) & 0x000000ff) /* 获取第2个字节 */#define GET_LOW_BYTE3(x) ((x >> 24) & 0x000000ff) /* 获取第3个字节 */⽰例:(2)获取某⼀位:#define GET_BIT(x, bit) ((x & (1 << bit)) >> bit) /* 获取第bit位 */⽰例:2、⼀个32bit数据的位、字节清零操作(1)清零某个字节:#define CLEAR_LOW_BYTE0(x) (x &= 0xffffff00) /* 清零第0个字节 */ #define CLEAR_LOW_BYTE1(x) (x &= 0xffff00ff) /* 清零第1个字节 */ #define CLEAR_LOW_BYTE2(x) (x &= 0xff00ffff) /* 清零第2个字节 */ #define CLEAR_LOW_BYTE3(x) (x &= 0x00ffffff) /* 清零第3个字节 */⽰例:(2)清零某⼀位:#define CLEAR_BIT(x, bit) (x &= ~(1 << bit)) /* 清零第bit位 */⽰例:3、⼀个32bit数据的位、字节置1操作(1)置某个字节为1:#define SET_LOW_BYTE0(x) (x |= 0x000000ff) /* 第0个字节置1 */ #define SET_LOW_BYTE1(x) (x |= 0x0000ff00) /* 第1个字节置1 */ #define SET_LOW_BYTE2(x) (x |= 0x00ff0000) /* 第2个字节置1 */ #define SET_LOW_BYTE3(x) (x |= 0xff000000) /* 第3个字节置1 */⽰例:(2)置位某⼀位:#define SET_BIT(x, bit) (x |= (1 << bit)) /* 置位第bit位 */4、判断某⼀位或某⼏位连续位的值(1)判断某⼀位的值举例说明:判断0x68第3位的值。
你知道嵌入式C语言中各变量存储的位置吗?
你知道嵌入式C语言中各变量存储的位置吗?
在举行C/C++编程时,需要程序员对内存的了解比较精准。
常常需要操作的内存可分为以下几个类别:
1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局
部变量的值等。
其操作方式类似于数据结构中的栈。
2、堆区(heap)—普通由程序员分配释放,若程序员不释放,程序
结束时可能由OS回收。
注重它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放
在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
4、文字常量区—常量字符串就是放在这里的。
5、程序代码区—存放函数体的二进制代码。
以下是一段实际解释的程序代码:这是一个前辈写的,十分具体。
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456在常量区,p3在栈上。
static int c =0;全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456放在常量区,编译器可能会将它与p3
第1页共3页。
C语言如何操作内存
C语⾔如何操作内存⼀、⼏个基本概念1.变量1.全局变量(外部变量):出现在代码块{}之外的变量就是全局变量。
2.局部变量(⾃动变量):⼀般情况下,代码块{}内部的变量就是⾃动变量,也可使⽤auto显⽰定义。
3.静态变量:指内存位置在程序执⾏期间⼀直不改变的变量,⽤关键字static修饰。
代码块内部的静态变量只能被这个代码块内部访问,代码块外部的静态变量只能被定义这个变量的⽂件访问。
2.作⽤域通常指的是变量的作⽤域,⼴义上讲,有函数作⽤域和⽂件作⽤域。
⼆、内存四区计算机中的内存是分区来管理的,程序和程序之间的内存是独⽴的,不能互相访问的,⽐如QQ和浏览器分别所占的内存区域是不能相互访问的。
⽽每个程序的内存也是分区管理的,⼀个程序所占的内存空间可以分为很多个区域,我们需要了解的内存主要有四个区域,通常叫内存四区。
1.代码区程序被操作系统加载到内存时,所有的可执⾏代码(程序代码指令、常量字符串等)都加载到代码区,这块内存在程序运⾏期间是不变的。
代码是平⾏的,⾥⾯装的是⼀堆指令,在程序运⾏期间是不能改变的。
函数也是代码的⼀部分,故函数都被放在代码区,包括main函数。
注意:"int a = 0;"语句可拆分成"int a;"和"a = 0",定义变量a的"int a;"语句并不是代码,它在程序编译时就执⾏了,并没有放到代码区,放到代码区的只有"a = 0"这句2.静态区静态区存放程序中所有的全局变量和静态变量3.栈区栈(stack)是⼀种先进后出的内存结构,所有的⾃动变量、函数形参都存储在栈中,这个动作由编译器⾃动完成,我们写程序时不需要考虑。
栈区在程序运⾏期间是可以随时修改的。
当⼀个⾃动变量超出其作⽤域时,⾃动从栈中弹出。
每个线程都有⾃⼰专属的栈;栈的最⼤尺⼨固定,超出则引起栈溢出;变量离开作⽤域后栈上的内存会⾃动释放。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
13.1 C语言程序的存储区域
由C语言源程序形成可执行程序(二进制文件),需要经 过编译、汇编、连接三个阶段
编译:根据C源程序生成汇编程序 汇编:根据汇编程序翻译成二进制机器代码 连接:将各个源文件生成的二进制机器代码组合成一个文件。
C源文件经过编译-汇编-连接后,将形成一个统一的文 件,它由代码段(Code/Text)、只读数据段(RO data) 和读写数据段(RW data)三部分组成。在运行时又会产 生另外三部分:未初始化数据段(BSS)、堆(Heap)和 栈(Stack)。各个部分代表了不同的存储区域。
用const定义“常量”时必须初始化。
13.3
可执行程序的连接
13.3.1 可执行程序的组成
目标文件(.o)的主要组成部分包含代码段、只读数 据段和读写数据段三个段。未初始化数据段、堆和栈 不会占用目标文件的空间。 C语言可执行程序是由各个目标文件经过连接生成。 其主体部分依然是代码段、只读数据段和读写数据段 ,这三个段由各个目标文件(.o)经过“组合”而成。 C语言目标文件到可执行程序的连接如图13-2所示。 由连接器生成的可执行程序包含了各个目标文件的各 个段的内容,并且会附加可执行程序的头信息。在可 执行程序中,各个目标文件的代码段、只读数据段、 读写数据段经过了重新的排列组合。
在C语言中,读写数据段和未初始化数据段中 包含了:
整个程序的全局变量 单个文件内使用的全局变量(函数外部用static修饰 的) 局部静态变量(函数内部用static修饰的)。
13.3.2 各个目标文件的关系
编译时:
编译时只进行函数调用的语法检查。 只要被调用的函数有声明(不需要定义实现),编译 器就可以成功处理。
链接时:
链接时,链接器将各个可执行程序的代码段组合到一 起,有函数调用的地方还需要找到真正的函数定义才 可以完成链接。 链接器会根据实际情况修改编译生成的机器代码,完 成正确的跳转。
1.代码段(code或text)
代码段由程序中可执行的机器代码组成。
2.只读数据段(RO data)
只读数据段是程序中使用的一些不能被更改的数据, 可以用查表的方式使用这些数据。 程序中由const定义的常量、其他的字符串常量将位于 此段中。 由于这些数据不能被更改,因此,这些数据在嵌 入式应用中需要放置在只读存储器中。
第五部分 在嵌入式环境 下的C语言编程
第13章 C语言程序的内存布局 第14章 嵌入式C语言常用语法 第15章 嵌入式C语言编程的技巧
第13章 C语言程序的内存布局
本章介绍C语言程序的内存布局,包括连接过 程中目标程序各个段的组成和运行过程中各个 段加载的情况 主要内容:
C语言程序在内存中各个段的组成 C语言程序连接过程中的特性和常见错误 C语言程序的运行方式
5.堆(heap)
堆内存只在程序运行时出现,通常由程序员分配和 释放。在有操作系统时,如果程序没有释放,操作 系统可能在程序结束后回收内存。
6.栈(stack)
栈内存只在程序运行时出现,在函数内部使用的自 动变量、函数的参数以及返回值将使用栈空间。 由编译器自动分配和释放。
代码段、只读数据段、读写数据段、未初始化 数据段属于静态区域 堆和栈属于动态区域 代码段、只读数据段和读写数据段将在连接后 产生。 未初始化数据段将在程序初始化时开辟。 堆和栈将在程序的运行中分配和释放。
关于const
在C语言中,const是限定一个变量不允许被改变,而不 是真正定义了一个常量,只是定义了一个只读变量。 如:const int N=20;int x[N]是错误的。 使用const在一定程度上可以提高程序的安全性和可靠性 ,另外,在观看别人代码的时候,清晰理解const所起的 作用,对理解对方的程序也有一些帮助。如对函数的参 数加上const限定,可防止参数被无意修改。 理解const的用法
3.读写数据段(RW data)
目标文件中可读可写的数据区,有时也称为已 初始化数据段。 与代码段、只读数据段同属程序的静态区域, 但读写数据段具有可写的特点。 以下变量将放入读写数据段:
已初始化全局(静态)变量 已初始化局部静态变量
放入读写数据段中的变量必须是在程序中进行 初始化了的变量,如果没有初始化,将被放在 未初始化数据段中。
示例1
const char ro[]={"this is readonly data"}; /* 只读数据段 */ static char rw1[]={"this is global readwrite data"}; /* 已初始化读写数据段 */ char bss_1[100]; /* 未初始化数据段 */ const char * ptrconst = "constant data";
可执行程序 目标文件1 Code1 (代码段1) RO Data (只读数据段1) RW Data (读写数据段1) 程序头部 Code1 Code2 …… RO data1 目标文件2 Code1 (代码段2) RO Data (只读数据段2) RW Data (读写数据段2) RO data2 …… RW data1 RW data2 …… 链接过程 读写数 据段 只读数 据段 代码段
char *p1; char *p2 = “123456”;
/* p1在栈上,占用4个字节 */ /* “123456”放置在只读数据存储区 ,占7字节 */ /* p2在栈上,p2指向的内容不能更改。 */ static char rw2[]={"this is local readwrite data"}; /* 局部已初始化读写数据段 */ static char bss_2[100]; /* 局部未初始化数据段 */ static int c = 0; /* 全局(静态)初始化区 */ p1= (char *)malloc(10*sizeof(char)); /* 分配的内存区域在堆区。 */ strcpy(p1, "xxxx"); /* "xxxx"放置在只读数据存储区,占5字节 */ free(p1); /* 使用free释放p1所指向的内存 */ return 0; }
已初始化读写数据段(RW data)
程序中声明的已初始化的全局变量或静态局部变量, 在程序执行时需要位于可读写的内存区域内,以供程 序运行时读写。
4.未初始化数据段(BSS--Block Start by Symbol)
未初始化数据是在程序中声明、但没有被初始化的 全局变量或局部静态变量。 这些变量在程序运行前不需要占用存储器空间。
从上例可知:
只读数据段:包括了程序中定义的const型数据(如 const char ro[])、程序中的字符串常量(如“constant data”)。 读写数据段:包括了已初始化了的全局变量(如static char rw[])和局部静态变量(如static char rw2[]),这 些变量属于静态区,但均可进行读写。 未初始化数据段:包括了未初始化的全局变量和静态局 部变量。 栈:函数内部定义的自动变量,形参、返回值在栈上。 堆:用malloc,calloc,realloc等内存分配函数所分配的 内存空间在堆上
C语言程序的组成分为映像和运行时两种状态:
映像--静态结构:可执行程序加载到内存前的状态 。此时,文件中将只包含代码段、只读数据段和读写 数据段。 在程序加载到内存后、运行之前,将动态生成未初始 化数据段。 在程序的运行过程中将动态生成堆和栈区域。
在静态的映像文件中,各个部分称之为节( Section),而在运行时的各个部分称之为段( Segment)。
在C语言中,变量定义与段的对应关系:
1.在函数体中定义的自动变量是在栈上,不需要在程序中进 行管理,由编译器处理;在函数体中定义的静态变量是在全 局区(静态区):被初始化了的在读写数据段,未初始化的 在未初始化数据段。 2.用malloc,calloc,realloc等内存分配函数所分配的内存空 间在堆上,程序必须保证在使用后用free释放,否则会发生内 存泄漏。 3.所有函数体外定义的是全局变量,加了static修饰符后的变 量不管在函数内部或者外部都存放在全局区(静态区):被 初始化了的在读写数据段,未初始化的在未初始化数据段。 4.使用const定义的变量将放于程序的只读数据段。
图13-2 C语言目标文件到可执行程序的连接
从C语言使用的角度,读写数据段和未初始化 数据段都是可读写的。 在目标文件(*.o)中未初始化数据段和读写数 据段的区别在于:读写数据段占用目标文件的 容量,而未初始化数据段只是一个标识,不需 要占用实际的空间。 可执行程序中读写数据段的大小会等于各个目 标文件读写数据段之和。对于未初始化数据段 上的变量,连接器也将各个目标文件中的信息 相加得到可执行程序的未初始化段的大小,但 是这个段同样不会占用可执行文件的空间。
const int nValue; //nValue是const const char *pContent; //*pContent是const, pContent可变 const (char *) pContent; //pContent是const,*pContent可变 char* const pContent; //pContent是const,*pContent可变 const char* const pContent; //pContent和*pContent都是const
13.2.2 程序中段的使用
C语言程序中的全局区(静态区),实际对应 着下述几个段:
只读数据段:RO Data 读写数据段:RW Data 未初始化数据段:BSS Data
一般来说,未初始化的全局变量在未初始化数 据段,如果该变量有初始化则是在已初始化数 据段(RW Data),加上const修饰符将放置在 只读数据段(RO Data)。