本博文为半摘记性质。
——
声明:知识点引自《全国计算机等级考试-上机考试新版题库 二级C》,部分例程修改自https://www.runoob.com/cprogramming/c-tutorial.html 菜鸟教程,另有部分零散资料转自互联网,内容有改动,并非全文转载。
本人尊重各位的知识成果,大幅引用的文章原文网址已在各小节末尾给出。
0程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分:
1、栈区(stack)— 是一种先进后出的内存结构,所有的自动变量、函数形参都存储在栈中,由编译器自动分配释放。栈区在程序运行期间是可以随时修改的。当一个自动变量超出其作用域时,自动从栈中弹出。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
堆内存的分配和释放涉及内存的动态分配。
3、全局区(静态区)(static)— 静态区存放程序中所有的全局变量和静态变量。
5、代码区—程序被操作系统加载到内存的时候,所有的可执行代码(程序代码指令、常量字符串、函数等)都加载到代码区,这块内存在程序运行期间是不变的。
https://www.cnblogs.com/yif1991/p/5049638.html C语言知识整理(3):内存管理(详细版)
1基础知识
要点:
- 数据类型和常量、变量
- 运算符
——
令牌(tokens):C 程序由各种令牌组成,令牌可以是关键字、标识符、常量、字符串值,或者是一个符号。
转义字符:C语言中定义了一些字母前加""来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为后面的字符,都不是它本来的ASCII字符意思了。
C作用域
作用域是程序中定义的变量所存在的区域,超过该区域变量就不能被访问。
- 局部变量:在某个函数或块的内部声明的变量称为局部变量。它们只能被该函数或该代码块内部的语句使用。
- 全局变量 :全局变量是定义在函数外部,通常是在程序的顶部。全局变量在整个程序生命周期内都是有效的,全局变量可以被任何函数访问。定义全局变量时,系统会自动对其初始化。
定义全局变量时,系统会自动对其初始化。
- 函数的形式参数,被当作该函数内的局部变量,如果与全局变量同名它们会优先使用。
——
全局变量保存在内存的全局存储区中,占用静态的存储单元;
局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。
const和voliate
- const关键字限定一个变量不允许被更新,即令该变量为只读变量,产生静态作用。
- volatile是一个特征修饰符(type specifier)。简单来说其作用是防止编译器对代码进行优化,精确来说其作用是让编译器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份,即获取该变量的最新值。嵌入式常用,例如读取GPIO。
https://www.cnblogs.com/thammer/p/10650750.html C关键字volatile总结
C储存类
存储类定义 C 程序中变量/函数的范围(可见性)和生命周期。这些说明符放置在它们所修饰的类型之前。
- auto:所有局部变量默认的存储类。
- register:用于定义存储在寄存器中而不是 RAM 中的局部变量。不常用,了解即可。
- static:表示编译器在程序的生命周期内保持局部变量的存在。
- extern:用来在另一个文件中声明一个全局变量或函数。
数值类型和常量变量
声明变量的方式:数据类型关键字 变量名列表;
- 常用的基本数据类型主要有:整型(Int、long)、实型(float、double)和字符型(char)。
- 一个变量实质上是代表了内存中的某个数据单元,在程序中对某个变量的的操作实际上就是对这个存储单元的操作。
一个储存单元所代表的字节数对不同数据类型的变量是不同的。
- 变量的初始化不是在编译阶段完成的,而是在程序运行时执行本函数时赋值。
- 变量在使用前必须定义,为赋值的变量其值同定义的位置、操作系统以及和使用的编译器相关,不一定为0。
- 禁止对变量连续赋初值:Int x=y=z=1(×) intx=0,y=0,z=0(√)
- 若x和y都是浮点数,应当避免使用x = = y,因为通常存放在内存的浮点数时有误差的,不可能精确相等,将导致x = = y总是等于0。
- 字符常量是用单引号括起来的一个字符;字符串常量是用一对双引号括起来的字符序列,在字符串末尾要储存一个结束符(\0)。
- 字符量可参与整数运算。
运算符
- 除法(/)运算符的运算对象若均为整型时,结果也为整型,舍去小数;若运算量中有一个为实型,则结果为双精度实型。
- 求余运算符(%)其运算对象只能是整型。
- 对于赋值运算符(=)来讲,左边必为变量而非表达式或常量。
- C语言中唯一 一个三目运算符——条件运算符:
表达式1?表达式2:表达式3
如果表达式值为真,则以表达式2的值作为条件表达式的值,否则以表达式3的值作为条件表达式的值。条件运算符可以取代简单的 if 结构。
2程序设计
要点:
- 顺序程序设计
- if语句及其构成的选择
- switch分支语句
- while循环控制
- do…while循环
- for循环结构
- 中断语句
- 循环的嵌套
顺序程序设计
需包含头文件stdio.h来调用输入和输出函数。
printf(字符串);
or
printf(格式控制,输出项1,输出项2,...);
- 格式说明以 % 开头,格式字符结束。
printf函数常见的格式字符有:
- 格式说明与输出项需一 一对应,格式说明个数若少于输出项个数,则多余的输出项不予输出。
例:
printf ("sum=%d,sum1=%d",sum,sum1);
——
scanf(格式控制,输出项1,输出项2,...);
2.用scanf输入数据时,每行数据在未按下回车键之前可任意修改。
4. 在%和格式字符之间加入一个正整数可指定输入数据所占的宽度。
5. 在%和格式字符之间加*,可以跳过对应数据。
if语句及其构成的选择
if(表达式) 语句
if(表达式) 语句1
else 语句2
- 支持嵌套。
- else子句总是与前面最近的不带else的if相结合,与书写格式无关。因此如果if分支语句内部再单独嵌套一个if语句,需补上花括号。
switch分支语句
switch(表达式)
{
case 表达式1:语句1;
case 表达式2:语句2;
...
default:语句n+1;
}
用switch分支解决的问题也可用if语句嵌套的方式解决,但不够清晰简洁。
- break语句属于流程控制语句,不是switch语句的组成部分,使用break语句可以提前退出case分支流程。使用了break语句后:
switch(表达式)
{
case 表达式1:语句1;break;
case 表达式2:语句2;break;
...
default:语句n+1;break;
}
while循环控制
while(表达式)
循环体
- 当循环体需要无条件循环时,条件表达式的值可以设为1,但在循环体内要有带条件的非正常出口。
do…while循环
do
循环体
while(表达式);
- 该循环语句至少执行一次;而while循环可能一次都不执行。
for 循环结构
for(表达式1;表达式2;表达式3)循环体
- 表达式1 用于设置循环控制变量的初始值;表达式2用于测试循环的条件,以决定是否执行循环过程;表达式3确定每循环一次循环控制变量的增值。
- for (表达式1;表达式2;表达式 3)语句中的三个表达式都可以单独或全部省略,但分号不能省略,即for( ; ; );循环体也可以是空语句(;)。
中断语句
break语句
continue语句
- break语句可跳出switch语句体,也可跳出循环。
- break语句在嵌套循环中,只向外跳一层。
- break在循环时常与if语句连在一起,满足条件时跳出循环;对if-else语句不起作用。
- continue语句仅结束本次循环,立刻进行下一次循环条件判断;而break语句直接跳出循环。
- 在for循环中,遇到continue语句后将跳过循环体余下的语句;再对for语句中的 表达式3 求值(不会跳过表达式3,这点与while和do…while循环不同);然后进行 表达式2 的条件测试,其结果决定for循环是否执行。
循环的嵌套
- for循环、while循环、do-while循环可以互相嵌套,但每层循环在逻辑上必须完整。
- 内层循环要完全包含在外层循环内部。