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#提供了 ...
随机推荐
- redis cluaster (redis分布式集群 redis分片集群)
redis cluaster (redis分布式集群) 高可用: 在搭建集群时,会为每一个分片的主节点,对应一个从节点,实现slaveof的功能,同时当主节点down,实现类似于sentinel的自动 ...
- nginx四层负载nginx七层负载,nginx基于nginx-sticky会话保持.
1. nginx负载均衡实战 nginx提供了 4 7层负载均衡. 可根据业务需求选择不同负载均衡策略. 1.1.1 nginx四层负载均衡[网络层TCP负载] 不支持动静分离,但支持 http my ...
- 大厂边缘组VS小厂核心组,要怎么选?
有问必答 最近有粉丝提问:大厂边缘组VS小厂核心组,怎么选? 这确实是个好问题,读者老爷们可以先问下自己:如果有一份月薪2W在大厂边缘组打螺丝的Offer且不加班,另外还有一份月薪2W5,在小厂核心组 ...
- tab切换中嵌套swiper轮播
今天在做官网的时候需要用到swiper多图轮播的功能,但是得嵌套在tab切换中,就在我把砖都搬完后,发现了个问题,就是我在进行tab切换后,发现原本设置的swiper的自动轮播竟然失效了,而且样式也是 ...
- 记录工作中常用的 JS 数组相关操作
工作中难免会遇到各种各样的数据结构,较为全面的了解数组操作,对于复杂数据结构的处理会非常有用且节省时间 所以想在这里总结一下工作中常用的数组操作,都是一些非常基础的知识,大家看个乐就好~ 目录 工作中 ...
- cors解决跨域 服务器代理方式
// cors 方法 // 后端程序员通过定义后端程序,让跨域访问,可以正常执行,可以获取响应体内容 // 前端程序员不需要做任何的调整 // 后端程序 ...
- 基于 Easysearch kNN 搭建即时图片搜索服务
环境准备 启动 Easysearch 服务: # Make sure your vm.max_map_count meets the requirement sudo sysctl -w vm.max ...
- 实战分析Java的异步编程,并通过CompletableFuture进行高效调优
一.写在开头 在我们一开始讲多线程的时候,提到过异步与同步的概念,这里面我们再回顾一下: 同步:调用方在调用某个方法后,等待被调用方返回结果:调用方在取得被调用方的返回值后,再继续运行.调用方顺序执行 ...
- nexus服务启动/关闭命令
nexus服务启动/关闭命令history | grep nexus # 查看服务器上面的历史请求命令ps -ef | grep nexus 查看进程及目录find / -name 'nexus' # ...
- svn服务端安装和使用
首先去官网下载安装包 点我下载 下载完了以后选择安装路径然后一直next就可以了 安装完了以后在开始菜单里面找到svn 打开 如何使用? 这里是创建代码管理的存储库 点击 repositories ...