8.c语言高级编程

  1. gcc编译器

  1. GNU工具

  1. 编译工具:把一个源程序编译为一个可执行程序

  1. 调试工具:能对执行程序进行源码或者汇编级调试

  1. 软件工程工具:用于协助多人开发或者大型软件项目的管理,如make,CVS,Subvision

  1. 其他工具:用于把多个目标文件链接成可执行文件的连接器,或者用做格式转换的工具

  1. GCC简介

  1. 全称为GNU CC,GNU项目中符合ANSI C标准的编译系统

  1. 编译如C,C++,Object C,Java,Fortran,Pascal,Modula-3和Ada等多种语言

  1. GCC是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一般的编译器相比平均效率要高20%~30%

  1. 一个交叉平台编译器,适合在嵌入式领域的开发编译

  1. http://gcc.gnu.org/

  1. gcc所支持后缀名解释

  1. .c c原始程序

  1. .C/.cc/.cxx C++原始程序

  1. .h 预处理文件(头文件)

  1. .i 已经过预处理过的C原始程序

  1. .ii已经过与处理的C++原始程序

  1. .s/.S汇编语言原始程序

  1. .o目标文件

  1. .a/.so编译后的库文件

  1. 编译器的主要组件

  1. 分析器

  1. 分析器将源语言程序代码转换为汇编语言。因为要从一种格式转换为另一种格式(C到汇编),所以分析器需要知道目标机器的汇编语言。

  1. 汇编器

  1. 汇编器将汇编语言代码转换为CPU可以执行字节码

  1. 链接器

  1. 链接器将汇编器生成的单独的目标文件组合成可执行的应用程序。链接器需要知道这种目标格式以便工作

  1. 标准C库

  1. 核心的C函数都有一个主要的C库来提供。如果在应用程序中用到了C库重的函数,这个库就会通过连接器和源代码链接来生成最终的可执行程序

d.GCC的基本用法和选项

e.GCC的错误类型

  1. 第一类:C语法错误

  1. 第二类:头文件错误

  1. 第三类:档案库错误

  1. 第四类:未定义符号

f.GCC编译过程

  1. 预处理(Pre-Processing)

  1. gcc -E test.c -o test.i

  1. 用wc命令,查看这两个阶段代码大小

  1. $ wc test.c test.i

  1. 编译(Compiling)

  1. 检查语法错误,并生成编译文件

  1. -$ gcc -S test.i -o test.s

  1. 汇编(Assembling)

  1. 链接(Linking)

  1. 将目标程序链接库资源,生成可执行程序

  1. gcc test.o -o test

  1. ./test

  1. gdb调试工具

  1. 使用gcc对tes.c进行编译,注意一定加上选项'-g'

  1. gcc -g test.c -o test

  1. gdb test进入调试模式

  1. 输入字母小L查看代码内容

  1. 设置断点输入b命令 eg: b 12

  1. 输入run继续运行代码

  1. p a 查看变量a的值

  1. n是一步步往下执行

  1. 基本命令:

  1. break设置断点

  1. run继续运行

  1. bt展示程序堆栈信息

  1. c继续运行程序

  1. next

  1. edit

  1. list

  1. step

  1. help [name]

  1. quit

  1. 条件编译

  1. 编译器根据条件的真假决定是否编译相关代码

  1. 常见的条件编译有两种方法:

  1. 1.根据宏是否定义,其语法如下:

#ifdef <macro>

......

#else

.......

#endif

  1. 2.根据宏的值,其语法如下

#if <macro>

......

#else

.....

#endif

  1. 结构体

  1. 定义方式以及三种赋值方式以及内存对齐问题:

  1. 结构体数组

  1. 结构体指针

  1. 结构体嵌套结构体

  1. 含义:

  1. 结构体中的成员可以是另一个结构体

  1. 语法:

struct 结构体名{

struct 结构体名 成员名;

};

  1. 结构体大小

  1. 字节对齐主要是针对结构体而言的,通常编译器会自动对其变量进行对齐,以提高数据存取的效率

  1. 字节对齐作用:

  1. 平台原因(移植原因—):不是所有的硬件平台都能访问任意地址上的任意数据的:某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

  1. 性能原因:数据结构(尤其是栈)应该尽可能的在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要做两次内存访问;而对齐的内存访问仅需要一次访问。

  1. 结构体大小的计算方法

  1. 自身对齐

  1. 默认对齐

  1. 有效对齐

  1. 位域

  1. 定义:

  1. 所谓的“位域”是把一个字节中的二进制位分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来

  1. 位域的一般形式:

struct位域结构体名

{

位域列表;

};

  1. 其中位域列表的形式为:

类型说明符 位域名:位域长度表示。

  1. 共用体以及typedef

  1. 共用体概念

  1. 在c语言中,不同数据类型的数据可以使用共同的存储区域,这种数据构造类型称为共用体,简称共用,又称联合体。共用体在定义、说明和使用形式上与结构体相似。两者本质上的不同仅在于使用内存的方式上。

  1. 定义一个共用体类型的一般形式为:

union 共用体名

{

成员列表;

};

共用体大小计算也是按照最大字节来内存对其

  1. typedef

  1. 在c语言中,允许使用关键字typedef定义新的数据类型

  1. 其语法如下:

typedef <已有数据类型> <新数据类型>;

typedef int INTEGER;

这里定义了数据类型INTEGER,其等价于int

INTEGER i; <==> int i;

指针方式:

  1. 枚举

  1. c语言中构造类型之一,在开发中,有些变量只有几种可能的取值,比如:一周有七天、一年有四季、在枚举的定义中,会将变量一一列出来。

  1. 枚举定义:

  1. 语法:

enum 枚举名

{

枚举成员列表

};

  1. 枚举的使用

  1. enum 枚举名 变量名

  1. enum 枚举名 变量名 = 枚举常量

  1. 定义枚举时顺便创建变量

  1. 枚举的特点

  1. 默认第一个成员从0开始,后面成员依次+1

  1. 有特定值的成员后面,从特定值开始依次+1

  1. 同一个枚举类型中,成员值可以相同

  1. 不同的枚举类型中,成员名不可以一样

  1. 内存管理

  1. 内存管理的意义:

  1. 不同区域存放的数据,赋予不同的生命周期,带来了更大的灵活编程

  1. C/C++定义了4个内存区间:

  1. 代码区:

  1. 存放函数体的二进制代码,由操作系统进行管理(cpu执行的机器指令,共享只读)

  1. 全局区(全局变量和静态变量区)

  1. 存放全局变量和静态变量以及常量(包含const)

  1. 特点是生命周期比较长

  1. 栈区(局部变量区)

  1. 由编译器自动分配释放,存放函数的参数值,局部变量等

  1. 堆区(动态存储区):

  1. 由程序员分配和释放,若程序员不释放程序结束时由操作系统回收

  1. 静态存储分配

  1. 通常定义变量,编译器在编译时都可以根据该变量的类型知道所需内存空间的大小,从而系统在适当的时候为他们分配确定的存储空间。

  1. 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

  1. 动态存储分配

  1. 有些操作对象只有在程序运行时才能确定,这样编译器在编译时就无法为他们预定存储空间,只能在程序运行时,系统根据运行时的要求进行内存分配,这种方法称为动态分配。

  1. 所有动态存储分配都在堆区中进行。

  1. 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc申请任意多少的的内存,程序员自己负责在何时用free释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也多。

  1. 堆内存的分配与释放

  1. 当程序运行到需要一个动态分配的变量或对象时,必须向系统申请取得堆中的一块所需大小的存储空间,用于存储该变量或对象。当不再使用该变量或对象时,也就是他的生命结束时,要显式释放它所占用的存储空间,这样系统就能对该堆空间进行再次分配,做到重复使用有限的资源。

  1. 堆区是是不会自动在分配时做初始化的(包括清零),所以必须用初始化(initializer)来现实初始化

  1. 动态分配内存

  1. 内存泄漏(memory leak)

  1. 是指申请的内存空间使用完毕之后未回收。一次内存泄露危害可以忽略,但若一直泄漏,无论有多少内存,迟早都会被占用光,最终导致程序crash。(因此,开发中我们要尽量避免内存泄漏的出现)

  1. 内存溢出(out of memory)

  1. 是指程序在申请内存时,没有足够的内存空间供其使用。通俗理解就是内存不够用了,通常在运行大型应用或游戏时,应用或游戏所需要的内存远远超出了你主机内安装的内存所承受大小,就叫内存溢出。最终导致机器重启或者程序crash

  1. malloc/free

void * malloc(size_t num)

void free(void *p)

  1. malloc函数本身并不识别要申请的内存是什么类型,它只关心内存的总字节数。

  1. malloc申请到的是一块连续的内存,有时可能会比所申请的空间大。有时会申请不到内存,返回NULL.

  1. malloc返回值类型是void *,所以在调用malloc时要显式地进行类型转换,将void*转换成所需要的指针类型。

  1. 如果free的参数是NULL的话,没有任何效果。

  1. 释放一块内存中的一部分是不被允许的。

  1. malloc/free注意事项:

  1. 删除一个指针p(free(p);),实际意思是删除了p所指向的目标(变量或对象等),释放了他所占的堆空间,而不是删除p本身,释放堆空间后,p成了空悬指针

  1. 动态分配失败。返回一个空指针(NULL),表示发生了异常,堆资源不足,分配失败。

  1. malloc和free是配对使用的,free只能释放堆空间。如果malloc返回的指针值丢失,则所分配的堆空间无法回收,称内存泄漏,同一空间重复释放也是危险的,因为该空间可能已另分配,所以必须妥善保存malloc返回的指针,以保证不发生内存泄漏,也必须保证不会重复释放堆内存空间。

  1. 野指针:不是NULL指针,是指向“垃圾”内存的指针。

  1. 野指针是很危险的。

  1. 野指针的成因主要有两种

  1. 指针变量没有被初始化。

  1. 指针p被free之后,没有置为NULL,让人误以为p是个合法指针。指针操作超越了变量的作用范围。这种情况让人防不胜防。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言高级编程与实例剖析》随书源码 第1章 内存管理 1. 1.1 预备知识 1 1.1.1 PC存储器结构 1 1.1.2 CPU地址线宽度 3 1.1.3 内存管理方式 5 1.1.4 内存编译模式 6 1.1.5 堆概念和结构 9 1.1.6 堆管理函数 10 1.2 高速分配内存技巧 15 1.2.1 类型声明及变量定义 15 1.2.2 函数剖析 16 1.2.3 归纳总结 18 1.3 学生信息数据库实例 18 1.3.1 需求分析 19 1.3.2 源代码解析 19 1.3.3 运行结果 23 1.3.4 归纳总结 23 1.4 巧用内存管理创建通信录 25 1.4.1 需求分析 25 1.4.2 源代码解析 25 .1.4.3 程序运行结果 31 1.4.4 归纳总结 32 1.5 小结 32 第2章 文本屏幕界面设计 33 2.1 文本方式的控制 33 2.1.1 文本方式控制函数 33 2.1.2 文本方式颜色控制函数 34 2.1.3 字符显示亮度控制函数 36 2.1.4 实例解析 36 2.2 窗口设置和文本输出函数 38 2.2.1 窗口设置函数 38 2.2.2 控制台文本输出函数 38 2.2.3 实例解析 38 2.3 清屏和光标操作函数 40 2.3.1 清屏函数 40 2.3.2 光标操作函数 41 2.3.3 实例解析 41 2.4 屏幕文本移动与存取函数 43 2.4.1 屏幕文本移动函数 43 2.4.2 屏幕文本存取函数 43 2.4.3 实例解析 44 2.5 状态查询函数 46 2.5.1 状态查询函数 46 2.5.2 实例解析 47 2.6 创建弹出式菜单实例 48 2.6.1 需求分析 48 2.6.2 源代码解析 49 2.6.3 运行结果 55 2.6.4 归纳总结 55 2.7 文本方式下创建下拉式菜单 56 2.7.1 需求分析 56 2.7.2 源代码解析 56 2.7.3 运行结果 61 2.7.4 归纳总结 62 2.8 综合应用 62 2.8.1 需求分析 62 2.8.2 源代码解析 63 2.8.3 运行结果 66 2.8.4 归纳总结 66 2.9 小结 67 第3章 文件高级操作 68 3.1 文件的基本概念 68 3.2 标准文件的输入输出操作 68 3.2.1 标准文件输入输出 70 3.2.2 标准文件打开函数fopen() 71 3.2.3 标准文件关闭函数fclose() 74 3.2.4 标准文件的读写 75 3.2.5 文件的随机读写函数 78 3.2.6 实例解析 82 3.3 文件的加密与解密 83 3.3.1 移位加密法 83 3.3.2 伪随机数加密法 84 3.3.3 命令加密法 86 3.3.4 逐字节异或加密法 88 3.4 文件分割程序 91 3.4.1 操作方法 91 3.4.2 源代码解析 91 3.4.3 运行结果 94 3.4.4 归纳总结 94 3.5 文件合并程序 94 3.5.1 操作方法 94 3.5.2 源代码解析 95 3.5.3 运行结果 97 3.5.4 归纳总结 97 3.6 小结 97 第4章 图形图像 98 4.1 图形显示基本概念 98 4.1.1 图形显示的坐标 98 4.1.2 像素 99 4.2 图形函数 99 4.2.1 图形系统的初始化 99 4.2.2 恢复显示方式和清屏函数 102 4.2.3 基本图形函数 102 4.3 颜色控制函数 107 4.3.1 颜色设置函数 108 4.3.2 调色板颜色设置 110 4.4 画线的线型函数 114 4.4.1 设定线型函数 115 4.4.2 得到当前画线信息的函数 117 4.5 填色函数及相关作图函数 118 4.5.1 填色函数 118 4.5.2 用户自定义填充函数 119 4.5.3 得到填充模式和颜色的函数 121 4.5.4 与填充函数有关的作图函数 121 4.5.5 可对任意封闭图形填充的函数 124 4.6 屏幕操作函数 125 4.6.1 屏幕图像存储和显示函数 125 4.6.2 设置显示页函数 127 4.7 图形方式下的文本输出函数 130 4.7.1 文本输出函数 131 4.7.2 文本输出字符串函数 133 4.7.3 定义文本字型函数 135 4.8 动画技术 137 4.8.1 动态开辟图视口的方法 137 4.8.2 利用显示页和编辑页交替变化 138 4.8.3 利用画面存储再重放的方法 139 4.8.4 直接对图像动态存储器进行操作 141 4.9 菜单生成技术 141 4.10 图形程序使用环境 142 4.10.1 BGI使用 143.. 4.10.2 图形方式下字符输出的条件 144 4.10.3 BGI图形驱动 145 4.11 直接存储存取 145 4.11.1 BIOS中断在显示中的应用 147 4.11.2 VGA寄存器 149 4.11.3 屏幕图形与VRAM地址的关系 151 4.11.4 VRAM的位面结构 151 4.11.5 将VRAM位面信息存入文件 152 4.11.6 将文件图像信息写入VRAM位面 153 4.11.7 VGA标准图形模式12H编程 154 4.11.8 VGA标准图形模式13H编程 157 4.12 SVGA编程 157 4.12.1 SVGA显卡的检测 158 4.12.2 SVGA模式信息的获取与模式操作 160 4.12.3 SVGA的直接存储器显示与内存控制 162 4.13 综合应用实例 163 4.13.1 用户自定义图模填充长方框图像 163 4.13.2 画圆饼图程序 165 4.13.3 画条形图程序 167 4.13.4 画函数曲线 169 4.14 图形图像综合应用——用动画演示排序算法 171 4.14.1 程序介绍 171 4.14.2 源代码解析 172 4.14.3 运行结果 183 4.14.4 归纳总结 184 4.15 小结 184 第5章 中断 185 5.1 中断的基本概念 185 5.1.1 BIOS 185 5.1.2 中断和异常 186 5.1.3 BIOS功能调用 189 5.2 鼠标中断编程的应用实例 191 5.2.1 鼠标中断的基本概念 191 5.2.2 程序功能分析 198 5.2.3 源代码解析 199 5.2.4 归纳总结 202 5.3 键盘中断编程的应用实例 203 5.3.1 键盘中断的基本概念 203 5.3.2 键盘操作函数bioskey() 207 5.4 鼠标与键盘的综合应用实例 208 5.4.1 需求分析 208 5.4.2 源代码解析 208 5.4.3 运行结果 212 5.4.4 归纳总结 213 5.5 中断应用——菜单制作程序剖析 213 5.5.1 需求分析 213 5.5.2 源代码解析 214 5.5.3 运行结果 227 5.5.4 归纳总结 227 5.6 小结 228 第6章 通信技术 229 6.1 概述 229 6.2 Winsock编程基础 230 6.2.1 Winsock基本概念 230 6.2.2 Winsock基本API 230 6.2.3 关于Winsock的异步模式 234 6.3 Cscoket编程技术 238 6.4 串口编程 238 6.4.1 概念 239 6.4.2 串行接口 239 6.4.3 串行通信方式及异步通信协议 240 6.4.4 串口针脚功能 243 6.5 并口编程 244 6.5.1 概念 244 6.5.2 并行接口 244 6.5.3 并口针脚功能 245 6.6 串并口操作的输入/输出函数 246 6.6.1 输入函数 246 6.6.2 输出函数 246 6.7 双机连接的方法 247 6.8 双机并口通信实例 248 6.8.1 源代码解析 249 6.8.2 归纳总结 280 6.9 网络通信编程——聊天室实例 281 6.9.1 需求分析 281 6.9.2 聊天室服务器端程序分析 282 6.9.3 聊天室客户端程序分析 290 6.10 小结 297 第7章 基本总线接口编程 298 7.1 ISA总线 298 7.1.1 ISA总线简介 298 7.1.2 ISA引脚介绍 299 7.2 PCI总线 302 7.2.1 PCI总线简介 302 7.2.2 PCI引脚介绍 303 7.3 中断控制操作 306 7.3.1 软件中断 307 7.3.2 硬件中断 307 7.4 PCI总线配置 308 7.4.1 PCI总线配置空间及配置机制 308 7.4.2 用I/O命令访问PCI总线配置空间 309 7.5 采用中断方式的信号采集程序 311 7.5.1 功能分析 311 7.5.2 源代码解析 311 7.6 小结 316 第8章 游戏开发 317 8.1 游戏开发概述 317 8.2 BMP图像格式 318 8.3 TC环境下的256色显示 324 8.3.1 VGA的DAC色彩寄存器知识 324 8.3.2 置256色图形模式 324 8.3.3 访问显存 325 8.3.4 显示卡换页 326 8.3.5 硬件无关屏幕初始化 327 8.4 魔方游戏开发程序剖析 329 8.4.1 功能分析 330 8.4.2 鼠标驱动程序 330 8.4.3 主函数模块 344 8.4.4 初始化图形to_graphic_mode模块 347 8.4.5 初始化鼠标initialize模块 347 8.4.6 显示程序的作者word模块 348 8.4.7 显示游戏标题title模块 350 8.4.8 绘制游戏主窗口的draw_win模块 352 8.4.9 建立魔方游戏界面body模块 353 8.4.10 显示魔方游戏showcube模块 362 8.4.11 清除键盘缓冲区clr_kb_buff模块 363 8.4.12 返回鼠标按下操作键值getmousech模块 363 8.4.13 处理用户对功能热键的操作handle模块 364 8.5 小结 377 第9章 综合开发实例——信息管理系统 378 9.1 问题定义 378 9.2 算法设计 378 9.2.1 主函数算法 379 9.2.2 各模块算法 379 9.3 流程图设计 381 9.3.1 主函数模块的流程图 381 9.3.2 其他各模块的流程图 382 9.4 编写程序代码 392 9.4.1 基本介绍 392 9.4.2 信息管理系统程序代码 392 9.5 测试与调试 410 9.5.1 基本介绍 410 9.5.2 信息管理系统测试与调试 411 9.6 整理文档 412 9.7 系统维护 412 9.8 归纳总结 412...
C语言是一门广泛应用于计算机编程高级编程语言,它提供了许多强大的功能和特性,使编写高级代码变得更加简单和高效。 以下是一个C语言高级编程代码范例,展示了如何实现一个简单的图书馆管理系统: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> struct Book { char title[50]; char author[50]; int year; }; void addBook(struct Book *library, int *bookCount) { printf("请输入书名:"); scanf("%s", library[*bookCount].title); printf("请输入作者名:"); scanf("%s", library[*bookCount].author); printf("请输入出版年份:"); scanf("%d", &library[*bookCount].year); (*bookCount)++; printf("图书添加成功!\n"); } void displayLibrary(struct Book *library, int bookCount) { printf("图书馆中的图书有:\n"); for (int i = 0; i < bookCount; i++) { printf("书名:%s\n", library[i].title); printf("作者:%s\n", library[i].author); printf("出版年份:%d\n", library[i].year); printf("------------\n"); } } int main() { struct Book library[100]; int bookCount = 0; int choice; while (1) { printf("图书馆管理系统\n"); printf("1. 添加图书\n"); printf("2. 显示图书\n"); printf("3. 退出\n"); printf("请输入选项:"); scanf("%d", &choice); switch(choice) { case 1: addBook(library, &bookCount); break; case 2: displayLibrary(library, bookCount); break; case 3: exit(0); default: printf("无效的选项!\n"); } } return 0; } ``` 这段代码使用了结构体来表示图书的相关信息,实现了添加图书和显示图书的功能。在添加图书时,用户可以输入书名、作者和出版年份,系统会将图书添加到图书馆中。在显示图书时,系统会遍历图书馆中的所有图书并打印出它们的信息。 该代码范例展示了C语言中结构体、函数、循环、条件语句等的使用,以及如何进行用户输入和输出。通过这个简单的图书馆管理系统,我们可以看到C语言高级编程技巧和代码组织方式。当然,这只是一个简单的示例,实际应用中可能会更加复杂和完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值