C语言基础要点
C语言基础
C程序编译过程
C程序编译步骤
- 预处理:宏定义展开、头文件展开、条件编译等,同时将代码中的注释忽略,此处不检验语法
- 编译:检验语法,将处理后的文件生成汇编文件
- 汇编:将汇编文件生成目标文件(二进制文件)
- 链接:C语言编写的程序需要依赖各种库,所以编译之后还需要把库链接到最终的可执行程序中
例子(gcc编译过程):
分步编译
预处理:gcc -E hello.c -o hello.i
编译: gcc -S hello.i -o hello.s
汇编: gcc -c hello.s -o hello.o
链接: gcc hello.o -o hello
选项 功能 -E 只进行预处理 -S 只进行预处理和编译 -c 只进行预处理、编译和汇编 -o <filename> 指定生成的输出文件名<filename> 简化编译
gcc hello.c -o hello
不带选项,直接源文件编译为可执行文件(二进制文件)
汇编语言
一些汇编语言的操作符
| 操作符 | 作用 |
|---|---|
| mov | 移动 |
| add | 添加 |
| push | 压栈 |
| pop | 出栈 |
| call | 调用 |
eax 32位寄存器
32关键字
数据类型关键字(12)
- unsigned, signed
- short, int, long, float, double, char
- struct, union, enum
- void
存储类型关键字(5)
- auto, static, register, extern, const
控制语句关键字(12)
- if, else, switch, case, default
- for, while, do
- break, continue
- goto, return
其他关键字(3)
- sizeof
- typedef
- volatile
数据类型
基本类型
- 整型:short, int, long
- 字符型:char
- 实型【浮点型】:float,double
构造类型
- 数组类型
- 结构类型:struct
- 联合类型:union
- 枚举类型:enum
指针类型
常量
常量创建的两种方法
define宏定义
#define 标识符 替换列表
define定义的宏在编译后就不存在了【进行了宏展开】,它不占用内存,因为它不是变量
const修饰变量
- const 是 constant 的缩写,意思是“恒定不变的”
- 用 const 定义的变量的值是不允许改变的,即不允许给它重新赋值,即使是赋相同的值也不可以
本质上是变量,只不过值是不允许改变的,所以叫常变量
const 数据类型 变量名;
用 const 修饰的变量,无论是全局变量还是局部变量,生存周期都是程序运行的整个过程
const VS define
define是预编译指令,而const是普通变量的定义
- define定义的宏是在预处理阶段展开的
- const定义的只读变量是在编译运行阶段使用的
const定义的是变量,而define定义的是常量
- define定义的宏在编译后就不存在了,它不占用内存,因为它不是变量,系统只会给变量分配内存
- const定义的常变量本质上仍然是一个变量,具有变量的基本属性,有类型、占用存储单元
- 可以说,常变量是有名字的不变量,而常量是没有名字的。有名字就便于在程序中被引用,所以从使用的角度看
- 除了不能作为数组的长度,用const定义的常变量具有宏的优点,而且使用更方便
因为const定义的对象有数据类型,而宏定义的对象没有数据类型。所以编译器可以对前者进行类型安全检查,而对后者只是机械地进行字符替换,没有类型安全检查。这样就很容易出问题,即“边际问题”或者说是“括号问题”
结论:所以编程时在使用const和define都可以的情况下尽量使用常变量来取代宏
补充:const 可以通过指针变相修改【C可以,C++不行】
const int num = 520;
int *p = #
p = 1314;
size程序
类型限定
extern 声明变量,在变量未赋值前不占用空间
const 定义常变量【存储值不能修改的变量】
volatile 防止编译器优化代码
register 定义寄存器变量
goto语句
goto语句原则供参考
使用goto语句只能goto到同一函数内
goto的始与终
应是函数内一段小功能的结束处
函数内另外一段小功能的开始处
不能从一段复杂的执行状态中的位置goto到另外一个位置
应该避免像两个方向跳转
指针
野指针
指针变量指向一个未知的空间【无法确定其内容的空间】
操作系统将0~255作为系统占用空间,不允许访问操作
空指针
空指针是指内存空间编号为0的空间
万能指针
万能指针可以接收任意类型变量的内存地址
注意:如果需要改变变量值,需要转换对应类型
指针和字符串
char str[] = "hello world"; // 栈区字符串
char* ptr = "hello world"; // 数据区常量区字符串
// ch[2] = 'm'; // 通过
// p[2] = 'm'; // err
// *(p + 2) = 'm'; // err
作用域
| 变量类型 | 作用域 | 生命周期 | 存储位置 |
|---|---|---|---|
| 局部变量 | 函数内部 | 到函数结束 | 栈区 |
| 全局变量 | 项目中所有文件 | 到程序销毁 | 数据区 |
| 静态局部变量 | 函数内部 | 到程序销毁 | 数据区 |
| 静态全局变量 | 定义所在文件中 | 到程序销毁 | 数据区 |
函数
全局函数和静态函数
- 在C语言中默认全部是全局函数,使用关键字static可以将函数声明为静态
- 声明为静态意味着只能在创建函数的文件中使用
内存
代码区【text】
- 可执行文件的二进制代码(函数)
共享,只读
数据区【全局区静态区】
- 未初始化数据区【bss】
- 初始化数据区【data】
- 文字常量区【data】
栈区【stack】
系统为每一个程序分配一个临时空间
- 局部变量,函数信息,函数参数,数组...
栈区大小为:1M
- 可扩展【windows 10M】【Linux 16M】
堆区【heap】
存储大型数据【图片,音乐,视频】
操作需求:
手动开辟 malloc
手动释放 free
用于动态内存分配
进程内存结构
高地址 ↓
- 栈区【向下增长】
- 堆区【向上增长】
- 未初始化全局变量【BSS区,用零初始化】
- 已初始化全局变量、静态变量、常量数据【数据区】
- 可执行代码【代码区】
低地址 ↑
可执行文件结构
- 未初始化全局变量【BSS区,用零初始化】
- 已初始化全局变量、静态变量、常量数据【数据区】
- 可执行代码【代码区】
内存处理常见问题
数组下标越界
堆空间开辟野指针
- int* p = (int*)malloc(0);
- int* p = (int*)malloc(10); // 与整型不符,10/4
堆空间不允许多次释放【空指针可以】
开辟所用指针迷失,释放出错
联合体
- 共用体占用的内存应足够存储共用体中最大的成员
- 同一时间只使用一个变量【以最后一次赋值为基准】
文件指针
typedef struct {
short level; // 缓冲区“满”或者“空”的程度
unsigned flags; // 文件状态标志
char fd; // 文件描述符
unsigned char hold; // 如无缓冲区不读取字符
short bsize; // 缓冲区的大小
unsigned char *buffer; // 数据缓冲区的位置
unsigned ar; // 指针,当前指向
unsigned istemp; // 临时文件,指示器
short token; // 用于有效性的检查
} FILE;
C语言基础要点的更多相关文章
- c语言基础知识要点
C语言程序的构成 与C++.Java相比,C语言其实很简单,但却非常重要.因为它是C++.Java的基础.不把C语言基础打扎实,很难成为程序员高手. 一.C语言的结构 先通过一个简单的例子,把C语言的 ...
- JavaScript基础---语言基础(1)
写在前面: 通过四篇博客把JS基础中的基础整理一下,方便自己查阅,这些内容对于实际项目开发中也许并不会在意,但是作为JS的语言基础,自觉还是应该熟悉.在完成这三篇博客(JavaScript基础---语 ...
- T-SQL语言基础(1)之理论背景
从学校就开始接触和使用 SQL 了,但一直没有怎么细细去了解它,最近入职的公司比较重 T-SQL 部分,所以就准备系统的学习一下. 买了一本<Microsoft SQL Server 2008 ...
- 20165234 预备作业2 学习基础和C语言基础调查
学习基础和C语言基础调查 一.技能学习经验及体会 你有什么技能比大多人(超过90%以上)更好? 看到这个问题,我仔细想了想,好像的确没有什么特别出众的技能,但是我想到了许多我个人的爱好. 我从小喜欢五 ...
- 20165207 学习基础与C语言基础调查反馈
文章阅读体会与学习调查反馈 文章阅读体会 我在娄老师的文章里了解到了"做中学"的概念.并且通过娄老师慷慨地分享的相关经验,我对于它有了进一步的理解以及体会.以下是我收获以及我的感想 ...
- Java实例 Part2:Java语言基础
Part2:Java语言基础 ** Example01:从控制台接收输入字符 ** 运行结果: 实现代码: import java.util.Scanner; public class Example ...
- C语言基础知识-数据类型
C语言基础知识-数据类型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.常量与变量 1>.关键字 C的关键字共有32个. >.数据类型关键字(12个) char,s ...
- 《MSSQL2008技术内幕:T-SQL语言基础》读书笔记(下)
索引: 一.SQL Server的体系结构 二.查询 三.表表达式 四.集合运算 五.透视.逆透视及分组 六.数据修改 七.事务和并发 八.可编程对象 五.透视.逆透视及分组 5.1 透视 所谓透视( ...
- 《MSSQL2008技术内幕:T-SQL语言基础》读书笔记(上)
索引: 一.SQL Server的体系结构 二.查询 三.表表达式 四.集合运算 五.透视.逆透视及分组 六.数据修改 七.事务和并发 八.可编程对象 一.SQL Server体系结构 1.1 数据库 ...
- C#语言基础
第一部分 了解C# C#是微软公司在2000年7月发布的一种全新且简单.安全.面向对象的程序设计语言,是专门为.NET的应用而开发的.体现了当今最新的程序设计技术的功能和精华..NET框架为C#提供了 ...
随机推荐
- Linux搭建ESP-IDF开发环境
下载esp-gitee-tools git clone git@gitee.com:EspressifSystems/esp-gitee-tools.git 替换github网址 cd esp-git ...
- skipped: maximum number of running instances reached (1)
apscheduler定时任务报错skipped: maximum number of running instances reached (1) 原因是默认max_instances最大定时任务是1 ...
- Qt一键部署配置(Qt程序打包)
Qt一键部署配置(Qt程序打包) 1.版本 系统版本:windows10 Qt版本:5.15.2 2.设置可执行程序输出路径 打开.pro文件,输入DESTDIR = $$PWD/../bin,这 ...
- NOIP模拟98(多校30)
T1 构造字符串 解题思路 不算特别难的题,但是有一点细节... 首先需要并茶几缩一下点,然后判断一下是否合法,由于我们需要字典序最小的,因此我们应当保证一个联通块中标号较小的点为根节点. 那么对于所 ...
- 运行报错:找不到或无法加载主类 com.xxx.Application
springboot 项目下载到本地,用 idea 运行报错找不到或无法加载主类. 原因 项目内还没有编译,所以找不到主类文件,需要先编译项目. 解决方案 执行 mvn 编译命令: mvn compi ...
- webpack externals忽略不打入的包
例如项目中使用从 CDN 引入 jQuery,而不是把它打包进来使用 import $ from 'jquery' webpack.config.js externals: { jquery: 'jQ ...
- 设置双击ps1脚本直接用Powershell打开
设置双击ps1脚本直接用Powershell打开. 默认.ps1 文件双击是不能打开的,只能右键运行. 解决方法: 1.按windows+R打开运行,输入regedit,打开注册表 2.找到HKEY_ ...
- java线程的park unpark方法
标签(空格分隔): 多线程 park 和 unpark的使用 park和unpark并不是线程的方法,而是LockSupport的静态方法 暂停当前线程 LockSupport.park();//所在 ...
- 【解决方案】Java 互联网项目中消息通知系统的设计与实现(上)
目录 前言 一.需求分析 1.1发送通知 1.2撤回通知 1.3通知消息数 1.4通知消息列表 二.数据模型设计 2.1概念模型 2.2逻辑模型 三.关键流程设计 本篇小结 前言 消息通知系统(not ...
- MySQL bit类型增加索引后查询结果不正确案例浅析
昨天同事遇到的一个案例,这里简单描述一下:一个表里面有一个bit类型的字段,同事在优化相关SQL的过程中,给这个表的bit类型的字段新增了一个索引,然后测试验证 时,居然发现SQL语句执行结果跟不加索 ...