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

  1. define是预编译指令,而const是普通变量的定义

    • define定义的宏是在预处理阶段展开的
    • const定义的只读变量是在编译运行阶段使用的
  2. const定义的是变量,而define定义的是常量

    • define定义的宏在编译后就不存在了,它不占用内存,因为它不是变量,系统只会给变量分配内存
    • const定义的常变量本质上仍然是一个变量,具有变量的基本属性,有类型、占用存储单元
    • 可以说,常变量是有名字的不变量,而常量是没有名字的。有名字就便于在程序中被引用,所以从使用的角度看
    • 除了不能作为数组的长度,用const定义的常变量具有宏的优点,而且使用更方便

因为const定义的对象有数据类型,而宏定义的对象没有数据类型。所以编译器可以对前者进行类型安全检查,而对后者只是机械地进行字符替换,没有类型安全检查。这样就很容易出问题,即“边际问题”或者说是“括号问题”

结论:所以编程时在使用const和define都可以的情况下尽量使用常变量来取代宏

补充:const 可以通过指针变相修改【C可以,C++不行】

const int num = 520;
int *p = &num;
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语言基础要点的更多相关文章

  1. c语言基础知识要点

    C语言程序的构成 与C++.Java相比,C语言其实很简单,但却非常重要.因为它是C++.Java的基础.不把C语言基础打扎实,很难成为程序员高手. 一.C语言的结构 先通过一个简单的例子,把C语言的 ...

  2. JavaScript基础---语言基础(1)

    写在前面: 通过四篇博客把JS基础中的基础整理一下,方便自己查阅,这些内容对于实际项目开发中也许并不会在意,但是作为JS的语言基础,自觉还是应该熟悉.在完成这三篇博客(JavaScript基础---语 ...

  3. T-SQL语言基础(1)之理论背景

    从学校就开始接触和使用 SQL 了,但一直没有怎么细细去了解它,最近入职的公司比较重 T-SQL 部分,所以就准备系统的学习一下. 买了一本<Microsoft SQL Server 2008 ...

  4. 20165234 预备作业2 学习基础和C语言基础调查

    学习基础和C语言基础调查 一.技能学习经验及体会 你有什么技能比大多人(超过90%以上)更好? 看到这个问题,我仔细想了想,好像的确没有什么特别出众的技能,但是我想到了许多我个人的爱好. 我从小喜欢五 ...

  5. 20165207 学习基础与C语言基础调查反馈

    文章阅读体会与学习调查反馈 文章阅读体会 我在娄老师的文章里了解到了"做中学"的概念.并且通过娄老师慷慨地分享的相关经验,我对于它有了进一步的理解以及体会.以下是我收获以及我的感想 ...

  6. Java实例 Part2:Java语言基础

    Part2:Java语言基础 ** Example01:从控制台接收输入字符 ** 运行结果: 实现代码: import java.util.Scanner; public class Example ...

  7. C语言基础知识-数据类型

    C语言基础知识-数据类型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.常量与变量 1>.关键字 C的关键字共有32个. >.数据类型关键字(12个) char,s ...

  8. 《MSSQL2008技术内幕:T-SQL语言基础》读书笔记(下)

    索引: 一.SQL Server的体系结构 二.查询 三.表表达式 四.集合运算 五.透视.逆透视及分组 六.数据修改 七.事务和并发 八.可编程对象 五.透视.逆透视及分组 5.1 透视 所谓透视( ...

  9. 《MSSQL2008技术内幕:T-SQL语言基础》读书笔记(上)

    索引: 一.SQL Server的体系结构 二.查询 三.表表达式 四.集合运算 五.透视.逆透视及分组 六.数据修改 七.事务和并发 八.可编程对象 一.SQL Server体系结构 1.1 数据库 ...

  10. C#语言基础

    第一部分 了解C# C#是微软公司在2000年7月发布的一种全新且简单.安全.面向对象的程序设计语言,是专门为.NET的应用而开发的.体现了当今最新的程序设计技术的功能和精华..NET框架为C#提供了 ...

随机推荐

  1. ObjectArx 创建一个自定义实体项目步骤

    我使用的环境是cad2018+objectarx2018+vs2015+win10.先要安装desk向导程序,用向导创建项目对于初学者来说是很方便的,然后在配置程序编译链接的环境,最后就可以写一个项目 ...

  2. Python 潮流周刊#52:Python 处理 Excel 的资源

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...

  3. C#简易商城收银系统v1.1简单工厂实现(2-2)

    C#简易商城收银系统v1.1简单工厂实现(2-2) 当初: C#简易商城收银系统v1.0 现在: 用之前的工厂模式对商城收银系统v1.0进行升级 可以参考之前的 C#简易商城收银系统v1.0 随笔  ...

  4. 电源电路E24系列反馈电阻计算表格

    可调电源,包括DCDC.LDO电路的设计中,经常需要计算反馈电阻进行选型.为了提高效率,优化选型采购,抽空做了个表格进行快速计算. 1.一般反馈电阻电路如下. 输出电压公式为:Vout=Vfb*(Rh ...

  5. LLM 大模型学习必知必会系列(十二):VLLM性能飞跃部署实践:从推理加速到高效部署的全方位优化[更多内容:XInference/FastChat等框架]

    LLM 大模型学习必知必会系列(十二):VLLM性能飞跃部署实践:从推理加速到高效部署的全方位优化[更多内容:XInference/FastChat等框架] 训练后的模型会用于推理或者部署.推理即使用 ...

  6. zoxide更新后 (cd)异常

    关于zoxide github地址:https://github.com/ajeetdsouza/zoxide 简单来说 zoxide是一个cd的强化版.它会记录你曾经cd过的目录,在你使用cd的时候 ...

  7. ssh 端口转发实验

    为什么会使用端口转发 端口转发的优点: 安全性:通过隐藏实际服务(在这种情况下是监听在22端口的SSH服务)的真实端口号,增加了一层安全性.攻击者可能不知道真正的服务端口号,因此更难进行有针对性的攻击 ...

  8. Typora编写博客并发布

    (1)工具安装:下载博主xhznl开发的的工具,并按照说明进行正确的配置. EasyBlogImageForTypora使用说明:https://www.cnblogs.com/xhznl/p/132 ...

  9. 解决java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone

    错误描述: 使用JDBC连接数据库是产生错误 应该是数据库时区问题,在url配置时设置serverTimezone = GMT即可 url = "jdbc:mysql://localhost ...

  10. 使用 openssl 从cer公钥证书中导出公钥pem

    使用 openssl 从cer公钥证书中导出公钥pem ---------- "der 公钥证书"转 "base64 公钥证书"openssl x509 -in ...