求dac0832与单片机连接52单片机单极性缓冲联结的c程序

求大神解答 通过单片机控制DAC0832输出锯齿波,让实验板上发光【c语言吧】_百度贴吧 &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力! 本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张 关注:574,378贴子: 求大神解答 通过单片机控制DAC0832输出锯齿波,让实验板上发光收藏 #include®52.h&#include&absacc.h&#define dac0832 XBYTE[0xDFFF]void delay(){ while(!TF0); TF0=0;}main(){ TMOD=0X01; for(i=0;i&255;i++) for(i=255;i&0;i--){ 我的程序对吗?我在单片机运行成这样了 登录百度帐号51单片机C语言简介 &&&&51单片机 单片机c 第7章 51单片机c语言简介7.1 c语言的基本知识7.2 7.3 7.4 7.5 7.6c51程序设计的基本语法 c51程序设计的基本语法 c51程序设计 c51程序设计 函数 模块化程序设计 c51编程实例 c51编程实例 c语言的基本知识 7.1 c语言的基本知识7.1.1 c语言的特点与程序结构 语言的特点与程序结构 以前计算机的系统软件主要是用汇编语言编写的, 以前计算机的系统软件主要是用汇编语言编写的 , 对于 单片机应用系统来说更是如此。 单片机应用系统来说更是如此。由于汇编语言程序的可读性和 可移植性都较差, 可移植性都较差,采用汇编语言编写单片机应用系统程序的周 期长,而且调试和排错也比较困难。 期长,而且调试和排错也比较困难。为了提高编制计算机系统 和应用程序的效率,改善程序的可读性和可移植性, 和应用程序的效率,改善程序的可读性和可移植性,最好采用 高级语言编程。 语言既具有一般高级语言的特点 语言既具有一般高级语言的特点, 高级语言编程。c语言既具有一般高级语言的特点,又能直接 对计算机的硬件进行操作,并且采用c语言编写的程序能够很 对计算机的硬件进行操作,并且采用c语言编写的程序能够很 容易地在不同类型的计算机之间进行移植。 容易地在不同类型的计算机之间进行移植。与其它计算机高级 语言相比, 语言具有它自身的特点 语言具有它自身的特点: 语言相比,c语言具有它自身的特点: 1.语言简洁,使用方便灵活。 .语言简洁,使用方便灵活。 2.可移植性好。 .可移植性好。 3.表达能力强。 .表达能力强。 4.可进行结构化程序设计。 .可进行结构化程序设计。 5.可以直接操作计算机硬件。 .可以直接操作计算机硬件。 6.生成的目标代码质量高 。 . 尽管c语言具有很多的优点, 尽管 语言具有很多的优点,但和其它任何一种程序设计 语言具有很多的优点 语言一样,也有其自身的缺点, 不能自动检查数组的边界, 语言一样,也有其自身的缺点,如不能自动检查数组的边界, 各种运算符的优先级别太多,某些运算符具有多种用途等。 各种运算符的优先级别太多,某些运算符具有多种用途等。 c语言程序是由若干个函数单元组成的,每个函数都是 语言程序是由若干个函数单元组成的, 语言程序是由若干个函数单元组成的 完成某个特殊任务的子程序段。 完成某个特殊任务的子程序段。组成一个程序的若干个函数 可以保存在一个源程序文件中, 可以保存在一个源程序文件中,也可以保存语言源程序文件 的文件名由程序设计人员根据某种俗成规则自己确定, 的文件名由程序设计人员根据某种俗成规则自己确定,其扩 展名统一为“.c”。如a1-1.c、a2-1.c。 展名统一为“ 。 、 。 c语言程序的开始部分通常是预处理命令,如程序中通 语言程序的开始部分通常是预处理命令 语言程序的开始部分通常是预处理命令, 常遇到的# 命令。 常遇到的#include命令。这个预处理命令通知编译器在对程 命令 序进行编译时,将所需要的头文件读入后再一起进行编译。 序进行编译时,将所需要的头文件读入后再一起进行编译。 一般在“头文件”中包含有程序在编译时的一些必要的信息, 一般在“头文件”中包含有程序在编译时的一些必要的信息, 通常c语言编译器都会提供若干个不同用途的头文件 语言编译器都会提供若干个不同用途的头文件。 通常 语言编译器都会提供若干个不同用途的头文件。头文件 的读入是在对程序进行编译时才完成的。 的读入是在对程序进行编译时才完成的。 c语言程序是由函数所组成的。 一个完整的 语言程序应 语言程序是由函数所组成的。一个完整的c语言程序应 语言程序是由函数所组成的 包含一个主函数 主函数main()和若干个其它功能的函数。函数之间 包含一个主函数 ( 和若干个其它功能的函数。 可以相互调用, 可以相互调用,但main()函数只能调用其它的功能函数,而 ( 函数只能调用其它的功能函数, 不能被其它函数所调用。功能函数可以是c语言编译器提供的 不能被其它函数所调用。功能函数可以是 语言编译器提供的 库函数,也可以由用户按实际需要自行编写的函数。不管main 库函数,也可以由用户按实际需要自行编写的函数。不管 函数处于程序中的什么位置,程序总是从main()函数开 ()函数处于程序中的什么位置,程序总是从 ( 始执行。一个函数必须预先定义或声明后才能调用。 始执行。一个函数必须预先定义或声明后才能调用。 函数定义或声明位于源程序的预处理命令之后的开始位置。 函数定义或声明位于源程序的预处理命令之后的开始位置。 函数定义部分包括有函数的存储类型、返回值数据类型、 函数定义部分包括有函数的存储类型、返回值数据类型、函数 名、形式参数说明等,函数名后面必须跟一个圆括弧(),形 形式参数说明等,函数名后面必须跟一个圆括弧( 式参数说明在圆括弧( 内进行。函数也可以没有形式参数, 式参数说明在圆括弧()内进行。函数也可以没有形式参数, 如main( )。函数的位置比较自由。可以由程序设计人员安排在 。函数的位置比较自由。 函数定义后的任意位置。 函数由函数名和一对花括弧“ 组 函数定义后的任意位置 。 函数由函数名和一对花括弧 “ {}”组 里面的内容就是函数体, 成 , 在 “ {}”里面的内容就是函数体 , 如果一个函数有多个 里面的内容就是函数体 为函数体的范围。 “{}”,则最外面的一对“{}”为函数体的范围。 ,则最外面的一对“ 为函数体的范围 函数体的内容为若干条语句,一般有两类语句, 函数体的内容为若干条语句,一般有两类语句, 一类为说明语句, 一类为说明语句 , 用来对函数中将要用到的变量进行 定义;另一类为执行语句, 定义 ; 另一类为执行语句 , 用来完成一定的功能或算 法处理。有的函数体仅有一对“ , 法处理。有的函数体仅有一对“{}”,其中既没有变量 定义语句, 也没有执行语句, 这也是合法的, 定义语句 , 也没有执行语句 , 这也是合法的 , 称为 空函数” “空函数”。 c语言源程序可以采用任何一种编辑器来编写, 语言源程序可以采用任何一种编辑器来编写, 语言源程序可以采用任何一种编辑器来编写 既可以是windows环境下的编辑器,如记事本 环境下的编辑器, 既可以是 环境下的编辑器 ),也可以是 (notepad)或写字板(wordpad),也可以是 )或写字板( ), dos环境下的编辑器,如edit或pe等。c语言程序的 环境下的编辑器, 环境下的编辑器 或 等 语言程序的 书写格式十分自由。一条语句可以写成一行, 书写格式十分自由。一条语句可以写成一行,也可以 写成几行;还可以在一行内写多条语句; 写成几行;还可以在一行内写多条语句;但是需要注 意的是,每条语句都必须以分号“ 作为结束符。 意的是,每条语句都必须以分号“;”作为结束符。 另外, 语言区分大小写字母 语言区分大小写字母, 语言编译器在对程序进 另外,c语言区分大小写字母,c语言编译器在对程序进 行编译时, 行编译时 ,对于程序中同一个字母的大小写作为不同的变量 来处理。 虽然c语言程序不要求具有固定的格式 语言程序不要求具有固定的格式, 来处理 。 虽然 语言程序不要求具有固定的格式 , 但我们在 实际编写程序时还是应该遵守一定的规则, 实际编写程序时还是应该遵守一定的规则, 一般应按程序的 功能以“缩格”形式来写程序, 功能以“ 缩格 ” 形式来写程序,同时还应在适当的地方加上 必要的注释。注释对于比较大的程序来说是十分重要的, 必要的注释。 注释对于比较大的程序来说是十分重要的 , 这 有利于修改与读懂程序。 有利于修改与读懂程序。 c语言本身没有输入输出功能 , c语言程序的输入和输 语言本身没有输入输出功能, 语言程序的输入和输 语言本身没有输入输出功能 出是通过函数调用来实现的。 出是通过函数调用来实现的 。 franklin c51编译器提供的输 编译器提供的输 入输出库函数 scanf和 printf是通过 8051单片机的串行口实现 和 是通过 单片机的串行口实现 在程序中使用这种输入输出库函数之前必须先对8051单 的 , 在程序中使用这种输入输出库函数之前必须先对 单 片机的串行口进行初始化。但是对于单片机应用系统来说, 片机的串行口进行初始化。但是对于单片机应用系统来说 , 由于具体要求的不同,应用系统的输入输出方式多种多样, 由于具体要求的不同,应用系统的输入输出方式多种多样 , 不可能一律采用串行口作输入和输出。 不可能一律采用串行口作输入和输出。 因此应该根据实际需 要 , 由 应用系统的研制人员自己来编写满足特定需要的输入 输出函数, 输出函数 ,这一点对于单片机应用系统的开发研制人员来说 是十分重要的。 是十分重要的。 7.1.2 c语言的标识符和关键字 语言的标识符和关键字c语言的标识符是用来标识源程序中某个对象名字的。 语言的标识符是用来标识源程序中某个对象名字的。 语言的标识符是用来标识源程序中某个对象名字的 这些对象可以是函数、变量、常量、数组、数据类型、 这些对象可以是函数、变量、常量、数组、数据类型、存储 方式、语句等。一个标识符由字符串、数字和下划线等组成, 方式、语句等。一个标识符由字符串、数字和下划线等组成, 第一个字符必须是字母或下划线, 第一个字符必须是字母或下划线,通常以下划线开头的标识 符是编译系统专用的,因此在编写c语言源程序时 语言源程序时一般不要 符是编译系统专用的, 因此在编写 语言源程序时一般不要 使用以下划线开头的标识符,而将下划线用作分段符。 使用以下划线开头的标识符 , 而将下划线用作分段符 。 c51 编译器规定标识符最长可达 最长可达255个字符 , 但只有前面 个字 个字符, 编译器规定标识符 最长可达 个字符 但只有前面32个字 符在编译时有效, 符在编译时有效,因此在编写源程序时标识符的长度不要超 32个字符 程序中对于标识符的命名应当简洁明了, 个字符。 过 32个字符。程序中对于标识符的命名应当简洁明了,含义 清晰, 便于阅读理解, 如用标识符“ 表示最大值, 清晰 , 便于阅读理解 , 如用标识符 “ max”表示最大值 , 用 表示最大值 表示定时器0等 “timer0”表示定时器 等。 表示定时器 关键字是一类具有固定名称和特定含义的特殊标识符, 关键字是一类具有固定名称和特定含义的特殊标识符, 保留字。 又称为保留字 在编写c语言源程序时一般不允许将关键字 又称为 保留字 。 在编写 语言源程序时一般不允许将关键字 另作别用,换句话说就是对于标识符的命名不要与关键字相 另作别用,换句话说就是对于标识符的命名不要与关键字相 语言中, 标准一共规定了32个关键字 同 。 在 c语言中 , ansi c标准一共规定了 个关键字 , 表 语言中 标准一共规定了 个关键字, 7.1按用途列出了 ansi c标准的关键字。 标准的关键字。 按用途列出了 标准的关键字 表 7.1 ansi c标准的关键字 . 标准的关键字 关键字auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while用 途存储类说明 程序语句 程序语句 数据类型说明 存储类型说明 程序语句 程序语句 程序语句 数据类型说明 程序语句 数据类型说明 存储种类说明 数据类型说明 程序语句 程序语句 程序语句 数据类型说明 数据类型说明 存储种类说明 程序语句 数据类型说明 数据类型说明 运算符 存储种类说明 数据类型说明 程序语句 数据类型说明 数据类型说明 数据类型说明 数据类型说明 数据类型说明 程序语句说明用以说明局部变量 退出最内层循环 switch语句中的选择项 语句中的选择项 单字节整型数或字符型数据 在程序执行过程中不可能修改的变量值 转向下一个循环 switch语句中的失败选择项 语句中的失败选择项 构成do... ...while循环结构 构成 ... 循环结构 双精度浮点数 ...else选择结构 构成 if... ... 选择结构 枚举 在其它程序模块中说明了的全局变量 单精度浮点数 构成for循环结构 构成 循环结构 构成goto转移结构 构成 转移结构 构成if... ...else选择结构 构成 ... 选择结构 基本整型数 长整型数 使用cpu内部寄存器的变量 使用 内部寄存器的变量 函数返回 短整型数 有符号数, 有符号数,二进制数据的最高位为符号位 计算表达式或数据类型的字节数 静态变量 结构类型数据 构成switch选择结构 构成 选择结构 重新进行数据类型定义 联合数据类型 无符号数据 无符号数据 说明该变量在程序执行中可被隐含地改变 构成while和do... ...while循环结构 构成 和 ... 循环结构 编译器除了支持ansi 标准关键字以外, c51编译器除了支持ansi c标准关键字以外,还扩展了如 51编译器除了支持 所示的关键字: 表7.2所示的关键字: 51编译器的扩展关键字 表7.2 c51编译器的扩展关键字关键字 用 途 说 明bit sbit sfr sfr16 data bdata idata pdata xdata code interrupt using reetrant位标量声明 位标量声明 特殊功能寄存器声明 特殊功能寄存器声明 存储器类型声明 存储器类型声明 存储器类型说明 存储器类型说明 存储器类型说明 存储器类型说明 中断函数说明 寄存器组定义 再入函数声明声明一个位标量或位类型的函数 声明一个可位寻址变量 声明一个特殊功能寄存器( 位 声明一个特殊功能寄存器(8位) 声明一个16位的特殊功能寄存器 声明一个 位的特殊功能寄存器 直接寻址的 直接寻址的8051内部数据存储器 内部数据存储器 可位寻址的 可位寻址的8051内部数据存储器 内部数据存储器 间接寻址的 间接寻址的8051内部数据存储器 内部数据存储器 分页”寻址的8051外部数据存储 “分页”寻址的 外部数据存储 器 8051外部数据存储器 外部数据存储器 外部 8051程序存储器 程序存储器 定义一个中断函数 定义8051工作寄存器组 定义 工作寄存器组 定义一个再入函数 单片机c51 c51程序的编译连接与调试 7.1.3 单片机c51程序的编译连接与调试franklin c51交叉编译器是专为 交叉编译器是专为8051系列单片机设计的 交叉编译器是专为 系列单片机设计的 c语言编译器, 它能在 语言编译器, 及其兼容机上运行, 语言编译器 它能在ibm pc及其兼容机上运行, 使用非 及其兼容机上运行 常方便。为了保证编译器能正常工作, 机应具有 机应具有512k以 常方便 。为了保证编译器能正常工作, pc机应具有 以 上的内存、一个软盘驱动器、一个硬盘,采用msdos 3.0以 上的内存、一个软盘驱动器、一个硬盘,采用 以 上版本的操作系统。 以软件包的形式提供, 上版本的操作系统。franklin c51以软件包的形式提供,软 以软件包的形式提供 件包中主要有c51交叉编译器、a51交叉汇编器、l51连接定 交叉编译器、 交叉汇编器、 件包中主要有 交叉编译器 交叉汇编器 连接定 位器、 位器 、 ohs51代码转换器和 dscope一51软件仿真调试器以 代码转换器和 一 软件仿真调试器以 及其它一些实用软件程序。 如果在pc机的硬盘 机的硬盘c: 及其它一些实用软件程序 。 如果在 pc 机的硬盘 c : 上安装 c51编译器 在安装之前应对pc机的配置文件 c51编译器,在安装之前应对pc机的配置文件config.sys 编译器, 机的配置文件config.sys 和自动批处理文件autoexec.bat作如下修改: 作如下修改: 和自动批处理文件 作如下修改 config.sys: fiels = 20 : buffer = 20 autoexec.bat: set c51lib=c:\ :\c51\lib : :\ \ set c51inc= c:\ :\csi\inc = :\ \ set path=c:\ :\c51\bin :\ \ 这样修改之后, 这样修改之后 , c51编译器会当头文件不在当前目录 编译器会当头文件不在当前目录 能从c:\ :\c51\ inc子目录中找到头文件 ; l51连接 子目录中找到头文件; 时 , 能从 :\ \ 子目录中找到头文件 连接 器会自动为所有的编译模式及算术( 尤其是浮点运算) 器会自动为所有的编译模式及算术 ( 尤其是浮点运算 ) 功 能从c:\ :\c51\lib于目录中找到所需要的库文件。 于目录中找到所需要的库文件。 能从 :\ \ 于目录中找到所需要的库文件 c51编译器可根据不同的硬件环境由 个文件做出修改。 编译器可根据不同的硬件环境由4个文件做出修改 编译器可根据不同的硬件环境由 个文件做出修改。 下列配置文件包括在c51软件包中: 软件包中: 下列配置文件包括在 软件包中 startup.a51:c51编译器的启动程序, 所有的栈指 编译器的启动程序, : 编译器的启动程序 针和存贮器,只要需要,将被初始化。 针和存贮器,只要需要,将被初始化。 int.a51:在文件中已明确初始化了的变量作初始化。 :在文件中已明确初始化了的变量作初始化。 如果系统装了“看门狗” 该文件可包含附加的“看门狗” 如果系统装了“看门狗”,该文件可包含附加的“看门狗” 刷新。 刷新。 putchar.c: 函数“ printf”、 “ puts”等的字符输出 : 函数 “ 、 等的字符输出 该程序可根据用户硬件加以修改( 核心程序 , 该程序可根据用户硬件加以修改 ( 如 lcd显 显 示)。 getkey.c:函数“getchar”、“scanf”等的字符输入 :函数“ 、 等的字符输入 核心程序,该程序可根据硬件加以修改(如矩阵键盘) 核心程序,该程序可根据硬件加以修改(如矩阵键盘) 所有文件都包含在c运行库中,因此, 所有文件都包含在 运行库中,因此,不能在 运行库中 连接时指定调用。如果用户改变一个文件, 连接时指定调用。如果用户改变一个文件,可将其 编译后与其它目标文件一起连接, 编译后与其它目标文件一起连接,因而不必改动运 行库。库中原文件自动忽略。 行库。库中原文件自动忽略。 例:l51 mymodul1.obj,mymodul2.obj , , startup.obj,putchar.obj , 上 例 将 用 户 建 立 的 startup.obj 和 putchar.obj连接起来。 连接起来。 连接起来 语言编写的程序必须通过编译和连接之后, 用c语言编写的程序必须通过编译和连接之后, 语言编写的程序必须通过编译和连接之后 才能生成可执行代码。 编译器由命令“ 启动, 才能生成可执行代码。c51编译器由命令“c51”启动, 编译器由命令 启动 例如以exi2.c为文件名的程序编译命令如下; 为文件名的程序编译命令如下; 例如以 为文件名的程序编译命令如下 c51 exi2.c code debug(回车) (回车) c51是编译器启动命令, exi2.c是程序文件名, 是编译器启动命令, 是程序文件名, 是编译器启动命令 是程序文件名 code和 debug是编译控制指令 。 输入完命令后 是编译控制指令。 和 是编译控制指令 回车,即可进人编译过程。 回车,即可进人编译过程。如果编译过程中未发现 错误,屏幕上会显示出: 错误,屏幕上会显示出: c51 compilation compilete , 0 waring(s), 0 error(s) ( ) ( ) 并产生列表文件 exi2.lst和目标文件 exi2.obj。 和目标文件 。 如果编译中发现任何错误,则不产生目标文件, 如果编译中发现任何错误,则不产生目标文件,而 将所有的错误信息都在列表文件中表示出来。编译 将所有的错误信息都在列表文件中表示出来。 控制指令code使列表文件的后面附加一个汇编语 控制指令 使列表文件的后面附加一个汇编语 言文件。 编译控制指令debug使目标文件中包含 使目标文件中包含 言文件 。 编译控制指令 有进行源程序调试时需要的各种符号信息。 有进行源程序调试时需要的各种符号信息。目标文 件中还包含有可再定位的目标码, 件中还包含有可再定位的目标码,以供 l51连接器 连接器 作进一步的处理。 作进一步的处理 。 c51编译器提供了许多不同控制 编译器提供了许多不同控制 指令可以完成各种编译控制功能。 指令可以完成各种编译控制功能。 c51程序设计的基本语法 7.2 c51程序设计的基本语法c语言是一种程序设计语言,采用c语言进行 语言是一种程序设计语言,采用 语言进行 语言是一种程序设计语言 程序设计时,需要遵循一定的语法规则。 程序设计时,需要遵循一定的语法规则。7.2.1 c语言的数据类型 语言的数据类型c语言的数据结构是以数据类型出现的, 数据类型可 语言的数据结构是以数据类型出现的, 语言的数据结构是以数据类型出现的 分为基本数据类型和复杂数据类型, 分为基本数据类型和复杂数据类型, 复杂数据类型由基本 数据类型构造而成。 语言中的基本数据类型有 语言中的基本数据类型有char, int, 数据类型构造而成 。 c语言中的基本数据类型有 , , short, long, float和 double。 对于c51编译器来说 , short , , 和 。 对于 编译器来说, 编译器来说 型与int型相同 型相同, 型与float型相同。分别说明如下: 型相同。 型与 型相同, double型与 型与 型相同 分别说明如下: 1. char 字符类型。有 signed char和 unsigned char 字符类型。 . 和 之分, 型数据, 之分,默认值为 signed char。对于 signed char型数据,其 。 型数据 字节中的最高位表示该数据的符号, 表示正数, 字节中的最高位表示该数据的符号 , “ 0”表示正数, “ l” 表示正数 表示负数。 负数用补码表示。 表示负数 。 负数用补码表示 。 所能表示的数值范围是 128~127;unsigned char型数据,是无符号字符型数据, 型数据, ~ ; 型数据 是无符号字符型数据, 其字节中的所有位均用来表示数据的数值, 其字节中的所有位均用来表示数据的数值, 所表示的数值 范围是 0~255。 ~ 。 2. int 整型。有signed int和unsigned nit之分, . 整型。 之分, 和 之分 默认值为signed int。signed int是有符号整型数,字 是有符号整型数, 默认值为 。 是有符号整型数 节中的最高位表示数据的符号, 表示正数, 节中的最高位表示数据的符号 , “ 0”表示正数 , 表示正数 表示负数。 “ 1”表示负数 。 所能表示的数值范围是 -32768~ 表示负数 ~ 是无符号整型数, +32767。unsigned int是无符号整型数,所表示的数 。 是无符号整型数 值范围是0~ 值范围是 ~65535。 。 3. long 长整型 。 有 signed long和 unsigned 长整型。 . 和 long之分 , 默认值为 之分, 之分 默认值为signed long。 它们的长度均为 。 四个字节。 是有符号的长整型数据, 四个字节。 singed long是有符号的长整型数据, 字 是有符号的长整型数据 节中的最高位表示数据的符号, 表示正数, 节中的最高位表示数据的符号 , “ 0”表示正数 , 表示正数 表示负数。 “ 1”表示负数 。 数值的表示范围是 ~ 表示负数 数值的表示范围是 ~ ; unsigned long是无符号长整型数据, 是无符号长整型数据, ; 是无符号长整型数据 数值的表示范围是0~ 数值的表示范围是 ~。 。 4.float 浮点型。它是符合 . 浮点型。它是符合ieee—754标准的 标准的 单精度浮点型数据,在十进制中具有7位有效数字 位有效数字。 单精度浮点型数据,在十进制中具有 位有效数字。 float型数据占用四个字节( 2位二进制数)。 需要 型数据占用四个字节( 位二进制数 位二进制数)。 型数据占用四个字节 指出的是,对于浮点型数据除了有正常数值之外, 指出的是,对于浮点型数据除了有正常数值之外, 还可能出现非正常数值。根据ieee标准,当浮点型 标准, 还可能出现非正常数值。根据 标准 数据取以下数值(16进制数 时即为非正常值: 进制数) 数据取以下数值(16进制数)时即为非正常值: ffffffffh非数(nan);7f800000h正溢出(+ 非数( 正溢出( 非数 ) 正溢出 inf);ff800000h负溢出(-inf); 负溢出( ) 负溢出 ) 另外, 由于8051单片机不包括捕获浮点运算错 另外 , 由于 单片机不包括捕获浮点运算错 误的中断向量, 误的中断向量 , 因此必须由用户自己根据可能出现 的错误条件用软件来进行适当的处理。 的错误条件用软件来进行适当的处理。 5.* 指针型。指针型数据不同于以上四种基 . 指针型。 本数据类型, 它本身是一个变量, 本数据类型 , 它本身是一个变量 , 但在这个变量 中存放的不是普通的数据而是指向另一个数据的 地址。指针变量也要占据一定的内存单元,在c51 地址。指针变量也要占据一定的内存单元, 中指针变量的长度一般为1 个字节。 中指针变量的长度一般为1~3个字节。指针变量 个字节 也具有类型,其表示方法是在指针符号“ ” 也具有类型,其表示方法是在指针符号“*”的前 面冠以数据类型符号。 面冠以数据类型符号 。 如 char *pointl; 表示 ; pointl是一个字符型的指针变量。指针变量的类型 是一个字符型的指针变量。 是一个字符型的指针变量 表示该指针所指向地址中数据的类型。 表示该指针所指向地址中数据的类型 。 使用指针 型变量可以方便地对 型变量可以方便地 对 8051单片机的各部分物理地 单片机的各部分物理地 址直接进行操作。 址直接进行操作。 6.bit 位标量。这是 51编译器的一种扩充 位标量。这是c 编译器的一种扩充 . 数据类型, 利用它可定义一个位标量, 数据类型 , 利用它可定义一个位标量 , 但 不能定 义位指针,也不能定义位数组。 义位指针,也不能定义位数组。 7 . sfr 特殊功能寄存器。 这也是c 51编译器 特殊功能寄存器 。 这也是 c 51 编译器 的一种扩充数据类型, 利用它可以访问 8051单片机 可以访问8051 的一种扩充数据类型 , 利用它 可以访问 8051 单片机 的所有内部特殊功能寄存器。sfr型数据占用一个内 的所有内部特殊功能寄存器。sfr型数据占用一个内 存单元,其取值范围0 255。 存单元,其取值范围0~255。 sfr16 16位特殊功能寄存器 位特殊功能寄存器。 8 . sfr16 16 位特殊功能寄存器 。 它占用两个 内存单元,取值范围是0 65535。 内存单元,取值范围是0~65535。 可寻址位 这也是c51编译器的一种 9 . sbit 可寻址 位 。 这也是 c51 编译器的一种 扩充数据类型,利用它可以访8051单片机内部ram中 可以访8051单片机内部ram 扩充数据类型,利用它可以访8051单片机内部ram中 的可寻址位或特殊功能寄存器中的可寻址位。 的可寻址位或特殊功能寄存器中的可寻址位。 在c语言程序中的表达式或变量赋值运算中,有 语言程序中的表达式或变量赋值运算中, 时会出现运算对象的数据不一致的情况, 运算对象的数据不一致的情况 时会出现运算对象的数据不一致的情况,c语言允许 任何标准数据类型之间的隐式转换 隐式转换。 任何标准数据类型之间的隐式转换。隐式转换按以下 优先级别自动进行: 优先级别自动进行: bit char int long float signed unsigned 转换时由低向高进行,而不是数据转换时的顺序。 转换时由低向高进行,而不是数据转换时的顺序。 一般来说,如果有几个不同类型的数据同时参加运算, 一般来说,如果有几个不同类型的数据同时参加运算, 先将低级别类型的数据转换成高级别类型, 先将低级别类型的数据转换成高级别类型,再作运算 处理,并且运算结果为高级别类型数据。 处理,并且运算结果为高级别类型数据。 c51编译器除了能支持以上这些基本数据之外, c51编译器除了能支持以上这些基本数据之外, 编译器除了能支持以上这些基本数据之外 还能支持一些复杂的构造型数据,如结构类型、 还能支持一些复杂的构造型数据,如结构类型、联合 类型等。 类型等。 7.2.2 常量常量是在程序执行过程中其值不能改变的量。 常量是在程序执行过程中其值不能改变的量。常量的 数据类型有整型、浮点型、字符型和字符串型等, 51编 数据类型有整型、浮点型、字符型和字符串型等,c51编 译器还扩充了一种位(bit)标量。分别说明如下: 译器还扩充了一种位(bit)标量。分别说明如下: 1.整型常量 整型常量就是整型常数, 可表示为以下几种形式: 整型常量就是整型常数 , 可表示为以下几种形式 : 十进制整数;十六进制整数: 十进制整数;十六进制整数:以 0x开头的数是十六进制 标准规定十六进制数的数字为0 数 , ansi c 标准规定十六进制数的数字为 0 ~ 9 , 再加字 长整数:在数字后面加一个字母l 母a~f;长整数:在数字后面加一个字母l就构成了长整 数。 2.浮点型常量 浮点型常量有十进制表示形式和指数表示形式。 浮点型常量有十进制表示形式和指数表示形式。 十进制表示形式又称定点表示形式, 十进制表示形式又称定点表示形式 , 由数字和小数 点组成。 3141、 31.41、 314. 点组成 。 如 0.3141 、 31.41 、 314.1 及 0.0 都是十进制数 表示形式的浮点型常量。 表示形式的浮点型常量。 在这种表示形式中,如果整数或小数部分为0 在这种表示形式中,如果整数或小数部分为0可以 省略不写,但必须有小数点。 省略不写,但必须有小数点。 指数表示形式为: 指数表示形式为: 数字[ 数字] [±] 数字[.数字]e [±] 数字 其中,[]中的内容为可选项,可有可无, ,[]中的内容为可选项 其中,[]中的内容为可选项,可有可无,但其余 部分必须有。 部分必须有。 3.字符型常量 字符型常量是单引号内的字符, 字符型常量是单引号内的字符 , 如 ‘ a’、 ‘ b’等 。 、 等 对于不可显示的控制字符 不可显示的控制字符, 对于 不可显示的控制字符 , 可以在该字符前面加一个 反斜杠字符“ 组成专用转义字符。 反斜杠字符 “ \ ” 组成专用转义字符 。 利用转义字符 可以完成一些特殊功能和输出时的格式控制。 可以完成一些特殊功能和输出时的格式控制。 4.字符串型常量 字符串型常量由双引号“”内的字符组成 双引号“”内的字符组成。 字符串型常量由双引号“”内的字符组成。当双 引号内的字符个数为0 称为空串常量。 引号内的字符个数为0时,称为空串常量。需要注意的 是 , 字符串常量首尾的双引号是界限符, 当需要表示 字符串常量首尾的双引号是界限符 , 双引号字符串时 , 可用转义字符 ‘ \ ’ 来表示为 : “\“\””。 ””。 say:\ goodbye! ””——字符串为 i say : :\“ 字符串为i 如 : “ i say :\ “ goodbye ! \ ”” 字符串为 say: goodbye! “goodbye!” 另外, 另外 , c 语言将字符串常量作为一个字符类型数组来处 在存储字符串常量时, 理,在存储字符串常量时,要在字符串的尾部加一个转义字 作为该字符串常量的结束符。 符 \ 0 作为该字符串常量的结束符 。 因此不要将字符常量与 字符串常量混淆。 字符串常量混淆。 5.位标量 这是c51编译器的一种扩充数据类型 编译器的一种扩充数据类型。 这是c51编译器的一种扩充数据类型。位标量用关键字 bit”来定义 它的值是一个二进制位。 来定义, “bit 来定义,它的值是一个二进制位。一个函数中可以包 bit”类型的参数 函数的返回值也可为“ bit”型 类型的参数, 含 “ bit 类型的参数 , 函数的返回值也可为 “ bit 型 。 另 不能定义位指针,也不能定义位数组。 外,不能定义位指针,也不能定义位数组。 7.2.3 变量及其存储模式 和常量相比,变量是另一种量, 和常量相比, 变量是另一种量, 在程序执行过程中其值 能不断变化。 能不断变化。每一个变量都必须有一个标识符作为它的变量 在使用一个变量之前,必须先对该变量进行定义, 名。在使用一个变量之前,必须先对该变量进行定义,指出 它的数据类型和存储模式, 它的数据类型和存储模式,以便编译系统为它分配相应的存 储单元。 51中对变量进行定义的格式如下 中对变量进行定义的格式如下: 储单元。在c51中对变量进行定义的格式如下: [存储种类]数据类型[存储器类型]变量名表; 存储种类]数据类型[存储器类型]变量名表; 其中, 存储种类” 存储器类型”是可选项。 其中 , “ 存储种类 ” 和 “ 存储器类型 ” 是可选项 。 变 量的存储种类有四种:自动(auto) 外部(extern) 量的存储种类有四种 : 自动 ( auto ) 、 外部 ( extern ) 、 静态(static)和寄存器(register) 静态 ( static ) 和寄存器 ( register ) 。 在定义一个变量 时如果省略存储种类选项,则该变量将为自动(auto) 时如果省略存储种类选项, 则该变量将为自动 ( auto ) 变 量。 定义一个变量时除了需要说明其数据类型之外, 51编 定义一个变量时除了需要说明其数据类型之外,c51编 译器还允许说明变量的存储器类型。 51对于每 译器还允许说明变量的存储器类型。 franklin c51对于每 个变量可以准确地赋予其存储器类型, 个变量可以准确地赋予其存储器类型 , 从而可使之能够在 单片机系统内准确地定位。 单片机系统内准确地定位。 定义变量时如果省略“存储器类型”选项, 定义变量时如果省略 “存储器类型 ” 选项, 则按编译 模式small、compact或large所规定的默认存储器类型确定 模式small、compact或large所规定的默认存储器类型确定 small 变量的存储区域, 变量的存储区域, 不能位于寄存器中的参数传递变量和过 程变量也保存在默认的存储器区域。 51编译器的三种存储 程变量也保存在默认的存储器区域。c51编译器的三种存储 器模式(默认的存储器类型)对变量的影响如下: 器模式(默认的存储器类型)对变量的影响如下: 8051单片机的内部数据存储器 1. small 变量被定义在 8051单片机的内部数据存储器 因此对这种变量的访问速度最快。另外,所有的对象, 中,因此对这种变量的访问速度最快。另外,所有的对象, 包括堆栈,都必须嵌入内部数据存储器, 包括堆栈,都必须嵌入内部数据存储器,而堆栈的长度是很 重要的,实际栈长取决于不同函数的嵌套深度。 重要的,实际栈长取决于不同函数的嵌套深度。 变量被定义在分页外部数据存储器中 2. compact 变量被定义在分页外部数据存储器 中 , 外 部数据段的长度可达256字节。 256字节 部数据段的长度可达256 字节 。 这时对变量的访问是通过寄 存器间接寻址( ri)进行的,堆栈位于单片机 存器间接寻址 ( movx @ ri) 进行的 , 堆栈位于 8051 单片机 内部数据存储器中。采用这种编译模式时, 内部数据存储器中。采用这种编译模式时,变量的高 8位地 口确定。因此,在采用这种模式的同时, 址由 p2 口确定 。 因此, 在采用这种模式的同时,必须适当 改 变 启 动 程 序 startup . a51 中 的 参 数 : pdatastart 和 pdatalen;用l51进行连接时还必须采用连接控制命令pdata pdatalen; 51进行连接时还必须采用连接控制命令pdata 进行连接时还必须采用连接控制命令 来对p 口地址进行定位,这样才能确保p 口为所需要的高8 来对 p2口地址进行定位, 这样才能确保p2 口为所需要的高8 位地址。 位地址。 变量被定义在外部数据存储器中( 3. large 变量被定义在外部数据存储器中 ( 最大可达 64k字节) 使用数据指针dptr来间接访问变量。 dptr来间接访问变量 64k 字节 ) , 使用数据指针dptr来间接访问变量 。 这种访问 数据的方法效率是不高的,尤其是对于2 数据的方法效率是不高的, 尤其是对于 2个或多个字节的变 用这种数据访问方法相当影响程序的代码长度。 量,用这种数据访问方法相当影响程序的代码长度。另外一 个不方便之处是这种数据指针不能对称操作。 个不方便之处是这种数据指针不能对称操作。 需要特别指出的是, 需要特别指出的是,变量的存储种类与存储器类型是完 全无关的。例如: 全无关的。例如: ;/* static unsigned char data x ;/* 在内部数据 存储器中定义一个静态无符 号字符型变量x 号字符型变量x */ 定义一个自动整型变量y int y; /* 定义一个自动整型变量y,它的存储器 类型由编译模式确定 */ 为了能够直接访问这些特殊功能寄存器, 51编译器扩充 为了能够直接访问这些特殊功能寄存器,c51编译器扩充 sfr和 sfr16 利用这种扩充关键字可以在c 16, 了关键字 sfr和 sfr16,利用这种扩充关键字可以在c语言源 程序中直接对8051单片机的特殊功能寄存器进行定义。 8051单片机的特殊功能寄存器进行定义 程序中直接对 8051 单片机的特殊功能寄存器进行定义。 定义 方法如下: 方法如下: 地址常数; sfr 特殊功能寄存器名 = 地址常数; 例如:sfr p0 = 0x80;/* 定义 i/o口 p0,其地址为 例如: 80;/* ;/ 80h 80h */ 这里需要注意的是,在关键字sfr后面必须是一个名字, 这里需要注意的是,在关键字sfr后面必须是一个名字, sfr后面必须是一个名字 名字可任意选取,但应符合一般习惯。等号后面必须是常数, 名字可任意选取,但应符合一般习惯。等号后面必须是常数, 不允许有带运算符的表达式, 不允许有带运算符的表达式,而且该常数必须在特殊功能寄 存器的地址范围之内(80h~0ffh)。 存器的地址范围之内(80h~0ffh)。 在新一代的8051单片机中 在新一代的 8051单片机中, 特殊功能寄存器经常组合 8051 单片机中, 16位来使用 为了有效地访问这种16 位来使用。 16位的特殊功能寄存 成16位来使用。为了有效地访问这种16位的特殊功能寄存 可采用关键字sfr16。 sfr16 器,可采用关键字sfr16。 8051单片机应用系统中经常需要访问特殊功能寄存 在 8051 单片机应用系统中经常需要访问特殊功能寄存 器中的某些位, 器中的某些位 , c51 编译器为此提供了一种扩充关键字 sbit,利用它可以访问可位寻址对象。 sbit,利用它可以访问可位寻址对象。使用方法有如下三 种: 1. sbit 位变量名 = 位地址; 位地址; 这种方法将位的绝对地址赋给位变量, 这种方法将位的绝对地址赋给位变量,位地址必须位 80h offh之间 例如: 之间。 于80h~offh之间。例如: xd2 sbit ov = 0xd2; 特殊功能寄存器名位位置; 2. sbit 位变量名 = 特殊功能寄存器名位位置; 当可寻址位位于特殊功能寄存器中时可采用这种方法, 当可寻址位位于特殊功能寄存器中时可采用这种方法, 位位置” 是一个0 之间的常数。 例如sbit “ 位位置 ” 是一个 0 ~ 7 之间的常数 。 例如 sbit cy = psw7 psw7; 字节地址位位置; 3.sbit 位变量名 = 字节地址位位置; 这种方法以一个常数(字节地址)作为基址, 这种方法以一个常数(字节地址)作为基址,该常数 必须在80 80h offh之间 之间。 位位置”是一个0 之间的常数。 必须在80h~offh之间。“位位置”是一个0~7之间的常数。 例如: 例如: xd07 07; sbit cy = 0xd07; 需要注意的是, sbit是一个独立的关键字 是一个独立的关键字, 需要注意的是 , sbit 是一个独立的关键字 , 不要将它 与关键字bit相混淆。 bit相混淆 与关键字bit相混淆。 当位对象位于单片机内部存储器的可位寻址区时 当位对象位于 8051 单片机内部存储器的可位寻址区时 称之为“可位寻址对象” 51编译器提供了一个 bdata存 称之为“可位寻址对象”。c51编译器提供了一个 bdata存 储器类型, bdata类型的对象放入 8051单片机 储器类型,允许将具有 bdata类型的对象放入 8051单片机 内部可位寻址区。例如: 内部可位寻址区。例如: int bdata ibase /* 在位寻址区定义一 个整型变量 ibase */ char bdata array[4] ; / * 在位寻址区定义一 array[4 个数组 array [4] */ 使用关键字sbit可以独立访问可位寻址对象中的某一位。 sbit可以独立访问可位寻址对象中的某一位 使用关键字sbit可以独立访问可位寻址对象中的某一位。 例如: 例如: ary37 array[3 sbit ary37 = array[3]7; 采用这种方法定义可位寻址变量时要求基址对象的存储器 类型为bdata 操作符“” bdata, “”后面的位值的最大值取决于指定的 类型为 bdata , 操作符 “” 后面的位值的最大值取决于指定的 基址类型,对于char char来说是 对于int int来说是 15; 基址类型 , 对于 char 来说是 0 ~ 7 ; 对于 int 来说是 0 ~ 15 ; 对于long来说是0 long来说是 31。 对于long来说是0~ 31。 typedef重新定义数据类型 定义的方法如下: 重新定义数据类型, 用typedef重新定义数据类型,定义的方法如下: 新的数据类型名 typedef 已有的数据类型 已有的数据类型是指c 语言的所有数据类型, 已有的数据类型是指 c 语言的所有数据类型 , 新的数据类 型可按用户自己的习惯或根据任务需要决定。 型可按用户自己的习惯或根据任务需要决定。7.2.4 运算符与表达式运算符按其在表达式中所起的作用,可分为赋值运算符、 运算符按其在表达式中所起的作用,可分为赋值运算符、 算术运算符、增量与减量运算符、关系运算符、逻辑运算符、 算术运算符、增量与减量运算符、关系运算符、逻辑运算符、 位运算符、复合赋值运算符、逗号运算符、条件运算符、 位运算符、复合赋值运算符、逗号运算符、条件运算符、指针 和地址运算符、强制类型转换运算符、sizeof运算符等 运算符等。 和地址运算符、强制类型转换运算符、sizeof运算符等。运算 符按其在表达式中与运算对象的关系,又可分为单目运算符、 符按其在表达式中与运算对象的关系,又可分为单目运算符、 双目运算符、三目运算符等。单目运算符需要一个运算对象, 双目运算符、三目运算符等。单目运算符需要一个运算对象, 双目运算符要求二个运算对象,三目运算符要求三个运算对象。 双目运算符要求二个运算对象,三目运算符要求三个运算对象。 1.赋值运算符 赋值语句的格式: 赋值语句的格式: 表达式; 变量 = 表达式; 符号“ 赋值运算符, 符号 “ = ” 是 赋值运算符 , 其作用是将一个数据的值赋 给一个变量。 给一个变量 。 利用赋值运算符将一个变量与一个表达式连接 起来的式子称为赋值表达式,后面加“ 构成赋值语句。 起来的式子称为赋值表达式,后面加“;”构成赋值语句。 2.算术运算符 语言中的算术运算符有: c语言中的算术运算符有: +:加或取正值运算符 -:减或取负值运算符 加或取正值运算符, 减或取负值运算符; +:加或取正值运算符,-:减或取负值运算符; 乘运算符,/:除运算符 除运算符, * :乘运算符,/:除运算符,%:取余运算符 用算术运算符将运算对象连接起来的式子称为算术表达 式。 算术表达式的一般形式为:表达式1 表达式2 算术表达式的一般形式为:表达式1 算术运算符 表达式2 语言中规定了运算符的优先级和结合性。 c语言中规定了运算符的优先级和结合性。在求一个表 达式的值时, 按运算符的优先级别进行。 达式的值时 , 要 按运算符的优先级别进行 。 算术运算符中 取负值( 的优先级最高,其次是乘法( 除法( 取负值(-)的优先级最高,其次是乘法(*)、除法(/) 和取余( 运算符,加法( 和减法( 和取余 ( % ) 运算符 , 加法 ( + ) 和减法 ( - ) 运算符的 优先级最低。 需要时可在算术表达式中采用圆括号来改变 优先级最低 。 需要时可 在算术表达式中采用圆括号来改变 运算符的优先级。 运算符的优先级。 如果在一个表达式中各个运算符的优先 级别相同, 则计算时按规定的结合方向进行。 例如: 级别相同 , 则计算时按规定的结合方向进行 。 例如 : 由于 ’和 ’优先级别相同 计算时按“从左至右” 优先级别相同, ‘+’和‘-’优先级别相同,计算时按“从左至右”的结合方 这种“从左至右” 的结合方向称为“ 左结合性” 向 , 这种 “ 从左至右 ” 的结合方向称为 “ 左结合性 ” , 而 从右至左”的结合方向称为“右结合性” “从右至左”的结合方向称为“右结合性”。 3.增量和减量运算符 语言中除了基本的加、 除运算符之外, c 语言中除了基本的加 、 减 、 乘 、 除运算符之外 , 还 提供一种特殊的运算符: 提供一种特殊的运算符: ++:增量运算符 ++:增量运算符 -- :减量运算符 增量和减量是c语言中特有的一种运算符, 增量和减量是c语言中特有的一种运算符,它们的作用 分别是对运算对象作加1和减l运算。例如:++ :++i 分别是对运算对象作加1和减l运算。例如:++i,i++, --j --等 --j,j--等。 看起来++i ++的作用都是使变量 的值加1 看起来 ++i和 i ++的作用都是使变量 i 的值加1 , 但是 ++ 由于运算符++所处的位置不同,使变量i ++所处的位置不同 由于运算符++所处的位置不同,使变量i加1的运算过程也不 ++i --i 是先执行i 操作, 同。 ++ i(或-- i)是先执行i+1( 或i-1) 操作,再使 的值, ++( 是先使用i的值,再执行i 用i的值,而 i++(或i-- )是先使用i的值,再执行i + 操作。 1(或i-1)操作。 增量运算符‘++’和减量运算符‘--’只能用于变量, 增量运算符‘++’和减量运算符‘--’只能用于变量, 不能用于常数或表达式。 不能用于常数或表达式。 printf函数的一般形式: printf函数的一般形式: 函数的一般形式 printf(格式控制,输出参数表) printf(格式控制,输出参数表) 格式控制又称为转换控制字符串, 格式控制又称为转换控制字符串,它是用双引号括起来的 一些字符串,通常这些字符由格式说明、 一些字符串,通常这些字符由格式说明、普通字符和转义字符 三部分组成。 三部分组成。 需要说明的是:允许作为库函数printf printf参量的总字节数 需要说明的是 : 允许作为库函数 printf 参量的总字节数 51编译器中函数库的限制 由于8051 编译器中函数库的限制。 8051单片机存储器结构有 受 c51 编译器中函数库的限制 。 由于8051 单片机存储器结构有 small和 编译模式下,最多可传递15 15个字节的 限,在 small和compact 编译模式下,最多可传递15个字节的 参数( 个指针, 个指针和3个长字) large编译模式 参数(即5个指针,或1个指针和3个长字),在large编译模式 最多可传递40个字节的参数。 40个字节的参数 下,最多可传递40个字节的参数。 另外,在采用printf输出时,printf函数中输出参数表的每 printf输出时 另外,在采用printf输出时,printf函数中输出参数表的每 个输出参数的数据类型必须与程序中定义的变量类型一致, 个输出参数的数据类型必须与程序中定义的变量类型一致,否则 会使输出的数据不对,这一点在使用库函数printf printf时是必须予以 会使输出的数据不对,这一点在使用库函数printf时是必须予以 注意。 注意。 4.关系运算符 语言中有6 种关系运算符:> 大于) :>( 小于) c 语言中有 6 种关系运算符 :> ( 大于 ) 、 < ( 小于 ) 、 > = 大于等于) 小于等于) 等于) (大于等于)、<=(小于等于)、 = =(等于) 、 !=( 不等 于)。 种关系运算符具有相同的优先级, 前 4 种关系运算符具有相同的优先级 , 后两种关系运算符也 具有相同的优先级;但前4种的优先级高于后2 具有相同的优先级;但前4种的优先级高于后2种。用关系运算符 将两个表达式连接起来即成为关系表达式。 将两个表达式连接起来即成为关系表达式。 关系表达式的一般形式为: 关系表达式的一般形式为:. 表达式1 表达式2 表达式1 关系运算符 表达式2 例如: a、 b、( 、(x 3) 例如:x & a、x + y & b、(x = 3)& (y = 4) 都是合法 的关系表达式。 的关系表达式。 关系运算符通常用来判别某个条件是否满足, 关系运算符通常用来判别某个条件是否满足,关系运算的结 果只有0 两种值。当所指定的条件满足时结果为 条件满足时结果为1 果只有0和 1两种值。 当所指定的条件满足时结果为1, 条件不满 足时结果为0。 足时结果为0 scanf函数的一般形式: scanf函数的一般形式: 函数的一般形式 scanf(格式控制,指针参数表) scanf(格式控制,指针参数表) 其中指针参数是指指针变量或者用取地址运算符“ 获 其中指针参数是指指针变量或者用取地址运算符“&”获 取普通变量的地址。 scanf函数中的每个参数都必须为指针 函数中的每个参数都必须为指针, 取普通变量的地址 。 scanf 函数中的每个参数都必须为指针 , 并且指针参数所指向的数据类型必须与格式控制串中所指定 的格式相匹配,否则scanf函数输入的数据将不正确。 scanf函数输入的数据将不正确 的格式相匹配,否则scanf函数输入的数据将不正确。 5.逻辑运算符 语言中有3 种逻辑运算符:|| 逻辑或) &&( :||( c 语言中有 3 种逻辑运算符 :|| ( 逻辑或 ) 、 && ( 逻 辑与) 逻辑非) 辑与)、 !(逻辑非) 逻辑运算符用来求某个条件式的逻辑值, 逻辑运算符用来求某个条件式的逻辑值, 用逻辑运算符 将关系表达式或逻辑量连接起来就是逻辑表达式。 将关系表达式或逻辑量连接起来就是逻辑表达式。逻辑表达 式的一般形式为: 式的一般形式为: 逻辑与:条件式1 条件式2 逻辑与:条件式1 && 条件式2 逻辑或:条件式1 条件式2 逻辑或:条件式1|| 条件式2 逻辑非:!条件式 逻辑非: 当连接的两个条件式都为真时, 逻辑与的结果为真( 当连接的两个条件式都为真时 , 逻辑与的结果为真 ( 1 ) , 否则为假( 否则为假(0)。 当连接的两个条件式之中有一个为真时, 当连接的两个条件式之中有一个为真时,逻辑或的结果为 否则为假( 真(1),否则为假(0)。 当条件式的结果为真时,逻辑非的结果为假,反之, 当条件式的结果为真时,逻辑非的结果为假,反之,则为 真。 逻辑运算符的优先级为( 由高至低) 逻辑运算符的优先级为 ( 由高至低 ) : ! ( 非 ) , && ||( (与),||(或)。 6.位运算符 语言有6种位运算符: c语言有6种位运算符: 按位取反) 按位与) ~(按位取反) &(按位与) <<(左移) >>(右移) <<(左移) >>(右移) 按位异或) 按位或) ^(按位异或) | (按位或) 运算符的作用是按位对变量进行运算, 运算符的作用是按位对变量进行运算,并不改变参与运算 的变量的值。若希望按位改变运算变量的值, 的变量的值。若希望按位改变运算变量的值,则应利用相应的 赋值运算。另外位运算符不能用来对浮点型数据进行操作。 赋值运算。另外位运算符不能用来对浮点型数据进行操作。 位运算符的优先级从高到低依次是: 位运算符的优先级从高到低依次是: 按位取反(~)、左移(<<)和右移(>>)、按位与 按位异或( 按位或( (&)、按位异或(^)、按位或(|)。 位运算符的一般形式如下: 位运算符的一般形式如下: 变量1 变量1 位运算符 变量 2 按位取反( 按位与( 按位或( 按位取反 ( ~ ) 、 按位与 ( & ) 、 按位或 ( | ) 、 按位异或 操作的运算取值关系如表7 所示。 (^)操作的运算取值关系如表7.3所示。 按位取反、按位与、按位或、 表7.3 按位取反、按位与、按位或、按位异或操作运算取值关系x 0 0 1 1 y 0 1 0 1 ~x 1 1 0 0 ~y 1 0 1 0x&yx|y 0 1 1 1x^y 0 1 1 00 0 0 1 7.复合赋值运算符 在赋值运算符“ 的前面加上其它运算符, 在赋值运算符“=”的前面加上其它运算符,就构成了所 谓复合赋值运算符: 谓复合赋值运算符: += 加法赋值,>>= 右移位赋值,-=减法赋值 &= 逻辑与赋值 * = 乘法赋值 , |= 逻辑或赋 值 , /= 除法 赋值 ^= 逻辑异或赋值 取模赋值, ~=逻辑非赋值 逻辑非赋值, % = 取模赋值 , ~= 逻辑非赋值 , <<= 左移位 赋值。 赋值。 复合赋值运算首先对变量进行某种运算, 复合赋值运算首先对变量进行某种运算,然后将运算的结 果赋给该变量。复合运算的一般形式为: 果赋给该变量。复合运算的一般形式为: 变量 复合赋值运算符 表达式 采用这种复合赋值运算符,可以使程序简化, 采用这种复合赋值运算符,可以使程序简化,同时还可以 提高程序的编译效率。 提高程序的编译效率。 8.逗号运算符 语言中符号“ 是一个特殊的运算符, 在c语言中符号“,”是一个特殊的运算符,可以用它将 两个(或多个)表达式连接起来,称为逗号表达式。 两个(或多个)表达式连接起来,称为逗号表达式。逗号表 达式的一般形式为: 达式的一般形式为: 表达式1 表达式2 表达式n 表达式1,表达式2,… ,表达式n 程序运行时对于逗号表达式的处理,是从左至右依次计 程序运行时对于逗号表达式的处理, 算出各个表达式的值, 算出各个表达式的值,而整个逗号表达式的值是最右边表达 即表达式n 的值。例如: 式(即表达式n)的值。例如:s = ( x = 4,y = 5,z = 6, 10) 执行这条命令的结果是x 分别赋值4 10) ; 执行这条命令的结果是 x 、 y 、 z 、 s 分别赋值 4 、 5 、 10。 6 、10。 9.条件运算符 条件运算将“ 语言中唯一的一个三目运算符, 条件运算将“:”是c 语言中唯一的一个三目运算符, 它要求有三个运算对象, 它要求有三个运算对象,用它可以将三个表达式连接构成一 个条件表达式。条件表达式的一般形式如下: 个条件表达式。条件表达式的一般形式如下: 表达式1 表达式2 逻辑表达式 表达式1 :表达式2 其功能是首先计算逻辑表达式,若其值为真( 其功能是首先计算逻辑表达式 , 若其值为真 ( 非 0 值 ) , 的值作为整个条件表达式的值; 将表达式 1的值作为整个条件表达式的值; 当逻辑表达式的 值为假( 将表达式2的值作为整个条件表达式的值。 值为假 (0值) 时,将表达式2的值作为整个条件表达式的值。 例如: 例如:max = ( a & b ) a :b;执行这条命令的结果是把 两个数a 中的最大值赋给max max。 两个数a、b中的最大值赋给max。 10. 10.指针和地址运算符 指针是c 语言中一个十分重要的概念,在 c 语言的数 指针是c 语言中一个十分重要的概念, 据类型中专门有一种指针类型。 据类型中专门有一种指针类型。变量的指针就是该变量的地 址 , 可以定义一个指向某个变量的指针变量。为了表示指针 可以定义一个指向某个变量的指针变量。 变量和它所指向的变量地址之间的关系, 变量和它所指向的变量地址之间的关系,c语言提供了两个专 门的运算符: 门的运算符: 取内容, * 取内容, & 取地址 取内容和取地址运算的一般形式分别为: 取内容和取地址运算的一般形式分别为: 变量 = * 指针变量 指针变量 = & 目标变量 指针变量 = & 目标变量 取内容运算的含义是将指针变量所指向的目标变量的值 赋给左边的变量; 赋给左边的变量; 取地址运算的含义是将目标变量的地址赋 给左边的指针变量。需要注意的是, 给左边的指针变量 。需要注意的是,指针变量中只能存放地 即指针型数据) 址 ( 即指针型数据) , 不要将一个非指针类型的数据赋值给 一个指针变量。 一个指针变量。 11. 11.强制类型转换运算符 语言中的圆括号“ 也可作为一种运算符使用, c语言中的圆括号“()”也可作为一种运算符使用,这 就是强制类型转换运算符 强制类型转换运算符, 就是 强制类型转换运算符, 它的作用是将表达式或变量的类 型强制转换成为所指定的类型。 语言程序中进行算术运算时, 型强制转换成为所指定的类型。c语言程序中进行算术运算时, 需要注意数据类型的转换。有两种数据类型转换方式, 需要注意数据类型的转换。 有两种数据类型转换方式, 即隐 式转换和显式转换。 式转换和显式转换 。 隐式转换是在对程序进行编译时由编译 器自动处理的。 器自动处理的。 在 c 语言中只有基本数据类型 ( 即 char 、 int 、 long 和 float)可以进行隐式转换。 float)可以进行隐式转换。其余的数据类型不能进行隐式转 强制类型转换运算符来进行显式转换。 换 。 强制类型转换运算符来进行显式转换。 强制类型转换运 算符的一般使用形式为: 算符的一般使用形式为: (类型)= 表达式 类型) 例如:需要在外部存储器(xdata) 例如 : 需要在外部存储器(xdata)中定义一个字符型 xc000 指 针 变 量 xp , 并 赋 初 值 0xc000 , 可 以 写 成 : xp = (char xc000 000; xdata * )0xc000 ; 这种方法特别适合于用标识符来存取地 址。 12.sizeof运算符 12.sizeof运算符 语言中提供了一种用于求取数据类型、 c 语言中提供了一种用于求取数据类型 、 变量以及表达 式的字节数的运算符: sizeof, 式的字节数的运算符: sizeof,该运算符的一般使用形 式为: 式为: sizeof(表达式) sizeof(数据类型) sizeof(表达式)或sizeof(数据类型) 应该注意的是,sizeof是一种特殊的运算符 是一种特殊的运算符, 应该注意的是, sizeof是一种特殊的运算符,不要错误 地认为它是一个函数。实际上, 地认为它是一个函数。实际上,字节数的计算在程序编译时 就完成了,而不是在程序执行的过程中才计算出来的。例如: 就完成了,而不是在程序执行的过程中才计算出来的。例如: sizeof(float); 执行这条命令的结果是把4 int a = sizeof(float) ; 执行这条命令的结果是把 4 赋给 了整型变量a 这意味着一个单精度数存储时占有4 了整型变量a,这意味着一个单精度数存储时占有4个字节内 存。 7.3 c51 程序设计7.3.1 表达式语句语言是一种结构化的程序设计语言, c 语言是一种结构化的程序设计语言 , 它提供了十分丰 富的程序控制语句。表达式语句是最基本的一种语句。 富的程序控制语句。表达式语句是最基本的一种语句。在表 达式的后边加一个分号“ 就构成了表达式语句。 达式的后边加一个分号“;”就构成了表达式语句。 表达式语句也可以仅由一个分号“ 组成, 表达式语句也可以仅由一个分号“;”组成,这种语句 称为空语句。空语句是表达式语句的一个特例。 称为空语句。空语句是表达式语句的一个特例。空语句在程 序设计中有时是很有用的,当程序在语法上需要有一个语句, 序设计中有时是很有用的,当程序在语法上需要有一个语句, 但在语义上并不要求有具体的动作时,便可以采用空语句。 但在语义上并不要求有具体的动作时,便可以采用空语句。 空语句通常有两种用法: 空语句通常有两种用法: 1 . 在程序中为有关语句提供标号,用以标记程序执行 在程序中为有关语句提供标号, 的位置。 的位置。 在用while语句构成的循环语句后面加一个分号, while语句构成的循环语句后面加一个分号 2.在用while语句构成的循环语句后面加一个分号,形 成一个不执行其它操作的空循环体。 成一个不执行其它操作的空循环体。 7.3.2 复合语句复合语句是由若干条语句组合而成的一种语句, 复合语句是由若干条语句组合而成的一种语句,它是用 一个大括号“{}”将若干条语句组合在一起而形成的一种功 一个大括号 “{} 将若干条语句组合在一起而形成的一种功 能块。复合语句不需要以分号“ 结束, 能块。复合语句不需要以分号“;”结束,但它内部的各条 单语句仍需以分号“ 结束。复合语句的一般形式为: 单语句仍需以分号“;”结束。复合语句的一般形式为: { 局部变量定义; 局部变量定义; 语句1 语句1; 语句2 语句2; 。。。。。。。。。 语句n 语句n; } 复合语句在执行时,其中的各条单语句依次顺序执行。 复合语句在执行时,其中的各条单语句依次顺序执行。 整个复合语句在语法上等价于一条单语句,因此在c 整个复合语句在语法上等价于一条单语句,因此在c语言程 序中可以将复合语句视为一条单语句。复合语句允许嵌套, 序中可以将复合语句视为一条单语句。复合语句允许嵌套, 即在复合语句内部还可以包含别的复合语句。 即在复合语句内部还可以包含别的复合语句。 通常复合语句都出现在函数中, 实际上, 通常复合语句都出现在函数中 , 实际上 , 函数的执行部分 即函数体)就是一个复合语句。 (即函数体)就是一个复合语句。复合语句中的单语句一般 是可执行语句,此外还可以是变量的定义语句( 是可执行语句,此外还可以是变量的定义语句(说明变量的 数据类型) 用复合语句内部变量定义语句所定义的变量, 数据类型)。用复合语句内部变量定义语句所定义的变量, 称为该复合语句中的局部变量, 称为该复合语句中的局部变量,它仅在当前这个复合语句中 有效。利用复合语句将多条单语句组合在一起, 有效。利用复合语句将多条单语句组合在一起,以及在复合 语句中进行局部变量定义是c语言的一个重要特征。 语句中进行局部变量定义是c语言的一个重要特征。7.3.3 流程控制语句1.选择结构 if语句 ① if语句 if语句有三种形式 单分支选择if语句、双分支选择if 语句有三种形式: if语句 if语 if语句有三种形式:单分支选择if语句、双分支选择if语 句和多分支选择if语句。 if语句 句和多分支选择if语句。 (1)单分支选择语句 if ( 条件表达式 ) 语句 其含义为:若条件表达式的结果为真( 其含义为 : 若条件表达式的结果为真 ( 非 0 值 ) , 就执行 了后面的语句;反之,若条件达式的结果为假( 了后面的语句 ; 反之 , 若条件达式的结果为假 ( 0 值 ) , 就不 执行后面的语句。这里的语句也可以是复合语句。 执行后面的语句。这里的语句也可以是复合语句。这种条件语 句的执行过程如图7 所示。 句的执行过程如图7.3(a)所示。 (2)双分支选择语句 if(条件表达式) if(条件表达式) 语句 1; else 语句2; 语句2 其含义为:若条件表达式的结果为真( ),就执行 其含义为:若条件表达式的结果为真(非0值),就执行 语句1 反之,若条件表达式的结果为假( ),就执行语句 语句1;反之,若条件表达式的结果为假(0值),就执行语句 这里的语句1和语句2均可以是复合语句。 2。这里的语句1和语句2均可以是复合语句。这种条件语句的 执过程如图7.3 7.3( 所示。 执过程如图7.3(b)所示。(a) 图7.3条件语句的执行 条件语句的执行(b) (3) 多分支选择语句 if(条件表达式1 if(条件表达式1) 语句 1; if(条件式表达2 else if(条件式表达2) 语句 2; if(条件式表达3 else if(条件式表达3) 语句 3; …… …… if( else if(条件表达式 n) 语句 n 语句n+ n+1 else 语句n+1; 这种条件语句常用来实现多方向条件分支, 这种条件语句常用来实现多方向条件分支,其执行过 程如图7.4所示。 7.4所示 程如图7.4所示。 例3.1 利用条件语句求一元二次方程的根&stdio. #include &stdio.h& &math. #include &math.h& main( ) { float a,b,c,x1,x2; float r,s; b*b- *a*c; a = 2.0;b = 3.0;c = 4.0;r = b*b-4.0*a*c; if ( r & 0.0 ) { (r); s = sqrt (r); s)/ *a); x1 = (-b+s)/(2.0*a); s)/ *a); x2 = (-b-s)/(2.0*a); printf(“real 15. 15. printf( real : x1 = %15.7f , x2 = %15.7f ” , x1 , x2); } else if (r = = 0.0) printf(“double: ,x2 15. *a)); printf( double:x1,x2 = %15.7 ”,-b/(2.0*a)); double , else { *a); x1 = -b/(2.0*a); sqrt(-r)/ *a); x2 = sqrt(-r)/(2.0*a); printf(“complex complex: 15. 15. printf( complex:re = %15.7f,im = %15.7f ”,x1,x2); , } }序 执行结 果 程 序执 行结果 : complex : re = - 0.7500000 , im = 1.1989580 这种条件语句常用来实现多方向条件分支, 这种条件语句常用来实现多方向条件分支,其执行过 程如图7 所示。 程如图7.4所示。 switch语句 ② switch语句 开关语句也是一种用来实现多方向条件分支的语句。 开关语句也是一种用来实现多方向条件分支的语句。 开关语句可直接处理多分支选择,使程序结构清晰,使 开关语句可直接处理多分支选择,使程序结构清晰, 用方便。开关语句是用关键字switch构成的, switch构成的 用方便。开关语句是用关键字switch构成的,它的一般 形式如下: 形式如下: switch(表达式) switch(表达式) { 常量表达式1 break; case 常量表达式1 : 语句 1; break; 常量表达式2 语句2 break; case 常量表达式2 : 语句2; break; …… …… 常量表达式n 语句n break; case 常量表达式n : 语句n; break; default: 语句n+ n+1 default: 语句n+1; }图7.5 开关语句的执行过程 2.循环结构 语言程序中用来构成循环控制的语句有:while语句 语句、 在 c 语言程序中用来构成循环控制的语句有 : while 语句 、 do-while语句 for语句以及goto语句 分述如下: 语句、 语句以及goto语句, do-while语句、for语句以及goto语句,分述如下: while语句 ① while语句 采用while语句构成循环结构的一般形式如下: 采用while语句构成循环结构的一般形式如下: while语句构成循环结构的一般形式如下 条件表达式) 语句; while (条件表达式) 语句; 其意义为,当条件表达式的结果为真( 其意义为,当条件表达式的结果为真(非0值)时,程序 就重复执行后面的语句, 就重复执行后面的语句,一直执行到条件表达式的结果变化 为假( 时为止。 为假(0值)时为止。这种循环结构是先检查条件表达式所给 出的条件,再根据检查的结果决定是否执行后面的语句。 出的条件 ,再根据检查的结果决定是否执行后面的语句 。 如 果条件表达式的结果一开始就为假, 果条件表达式的结果一开始就为假,则后面的语句一次也不 会被执行。这里的语句可以是复合语句。 所示为while 会被执行 。 这里的语句可以是复合语句。 图 7.6 所示为while 语句的执行过程。 语句的执行过程。 do-while语句 ② do-while语句 采用do while语句构成循环结构的一般形式如下 do一 语句构成循环结构的一般形式如下: 采用do一while语句构成循环结构的一般形式如下: while(条件表达式) do 语句 while(条件表达式); 这种循环结构的特点是先执行给定的循环体语句, 这种循环结构的特点是先执行给定的循环体语句 , 然后再检查条件表达式的结果。 然后再检查条件表达式的结果 。 当多件表达式的值为真 则重复执行循环体语句, (非0值)时,则重复执行循环体语句,直到条件表达式 的值变为假( 值时为止。 因此, 用如do while语句构 do一 的值变为假 ( 0 值时为止 。 因此 , 用如 do 一 while 语句构 成的循环结构在任何条件下, 成的循环结构在任何条件下 , 循环体语句至少会被执行 一次。图7.7绘出了这种循环结构的流程图。 一次。 绘出了这种循环结构的流程图。图7.6 while语句的执行过程 . 语句的执行过程图7.7 do—while循环结构的流 . 循环结构的流 while语句计算 -100的累加和 语句计算1 例:3.2 while语句计算1--100的累加和 &stdio. #include &stdio.h& main( ) { int i = 1,s = 0; 100) while (i &= 100) s+i;i++; { s = s+i;i++;} d/n”,s); printf (“s = %d/n ,s); s } do-while语句计算 100的累加和 语句计算1 例3.3 do-while语句计算1-100的累加和 &stdio. #include &stdio.h& main( ) { int i = 1,s = 0; do s+i;i++; {s = s+i;i++;} 100) while ( i &= 100) d/n”,s) ,s); printf (“s = %d/n ,s); s } for语句 ③ for语句 采用for语句构成循环结构的一般形式如下: for语句构成循环结构的一般形式如下 采用for语句构成循环结构的一般形式如下: for([ 初值设定表达式] ([初值设定表达式 循环条件表达式] for ([ 初值设定表达式 ] ; [ 循环条件表达式 ] ; 更新表达式]) ])语句 [更新表达式])语句 for语句的执行过程是 语句的执行过程是: for语句的执行过程是:先计算出初值设定表达式的值 作为循环控制变量的初值,再检查循环条件表达式的结果, 作为循环控制变量的初值, 再检查循环条件表达式的结果, 当满足循环条件时就执行循环体语句并计算更新表达式, 当满足循环条件时就执行循环体语句并计算更新表达式 , 然后再根据更新表达式的计算结果来判断循环条件是否满 一直进行到循环条件表达式的结果为假( 足 ……一直进行到循环条件表达式的结果为假( 0值 ) 时 , 一直进行到循环条件表达式的结果为假 退出循环体。for语句的执行过程如图 所示。 退出循环体。for语句的执行过程如图 7.8所示。 在c语言程序的循环结构中,for语句的使用最为灵活, 语言程序的循环结构中,for语句的使用最为灵活, 语句的使用最为灵活 它不仅可以用于循环次数已经确定的情况, 它不仅可以用于循环次数已经确定的情况,而且可以用于循 环次数不确定而只给出循环结束条件的情况。另外,for语 环次数不确定而只给出循环结束条件的情况。另外,for语 句中的三个表达式是相互独立的, 句中的三个表达式是相互独立的,并不一定要求三个表达式 之间有依赖关系。 for语句中的三个表达式都可能缺省 语句中的三个表达式都可能缺省, 之间有依赖关系。并且 for语句中的三个表达式都可能缺省, 但无论缺省哪一个表达式,其中的两个分号都不能缺省。 但无论缺省哪一个表达式,其中的两个分号都不能缺省。一 般不要缺省循环条件表达式,以免形成死循环。 般不要缺省循环条件表达式,以免形成死循环。 语句计算自然数1 100的累积和 例3.4 用for 语句计算自然数1 ~ 100的累积和 #include &stdio.h& &stdio. main( ) { int i = 1,s = 0; 100; for( ;i &= 100;) { s+i; s = s+i; i++; i++; } printf (“s = %d ”,s); s ,s); }图7.8 for语句的执行过程 语句的执行过程 3.非结构化语句 goto语句 ①goto语句 goto语句是一个无条件转向语句 它的一般形式为: 语句是一个无条件转向语句, goto语句是一个无条件转向语句,它的一般形式为: goto 语句标号; 语句标号; 其中语句标号是一个带冒号 “ : ” 的标识符 。 将 goto语句和if语句一起使用 可以构成一个循环结构。 语句和if语句一起使用, goto语句和if语句一起使用,可以构成一个循环结构。但更 常见的是在c语言程序中采用goto语句来跳出多重循环, goto语句来跳出多重循环 常见的是在 c 语言程序中采用goto 语句来跳出多重循环, 需 要注意的是只能用goto语句从内层循环跳到外层循环, goto语句从内层循环跳到外层循环 要注意的是只能用goto语句从内层循环跳到外层循环,而不 允许从外层循环跳到内层循环。 允许从外层循环跳到内层循环。 对于多重循环的情况,break语句只能跳出它所处的那 对于多重循环的情况,break语句只能跳出它所处的那 一层循环,而不象goto语句可以直接从最内层循环中跳出来。 goto语句可以直接从最内层循环中跳出来 一层循环,而不象goto语句可以直接从最内层循环中跳出来。 由此可见,要退出多重循环时,采用goto语句比较方便。 goto语句比较方便 由此可见,要退出多重循环时,采用goto语句比较方便。需 要指出的是,break语句只能用于开关语句和循环语句之中 语句只能用于开关语句和循环语句之中, 要指出的是,break语句只能用于开关语句和循环语句之中, 它是一种具有特殊功能的无条件转移语句。另外还要注意, 它是一种具有特殊功能的无条件转移语句。另外还要注意, 在进行实际程序设计时,为了保证程序具有良好的结构, 在进行实际程序设计时,为了保证程序具有良好的结构,应 当尽可能地少采用goto语句,以使程序结构清晰易读。 goto语句 当尽可能地少采用goto语句,以使程序结构清晰易读。 continue语句 ② continue语句 continue语句是一种中断语句 它一般用在循环结构中, 语句是一种中断语句, continue 语句是一种中断语句 , 它一般用在循环结构中 , 其功能是结束本次循环, 其功能是结束本次循环,即跳过循环体中下面尚未执行的语 把程序流程转移到当前循环语句的下一个循环周期, 句,把程序流程转移到当前循环语句的下一个循环周期,并 根据循环控制条件决定是否重复执行该循环体。 根据循环控制条件决定是否重复执行该循环体。 continue语句的一般形式为 语句的一般形式为: continue语句的一般形式为: continue; continue; continue语句通常和条件语句一起用在由 while、do— continue语句通常和条件语句一起用在由 while、do while和 for语句构成的循环结构中 语句构成的循环结构中, while和 for语句构成的循环结构中,它也是一种具有特殊 功能的无条件转移语句, break语句不同 语句不同, 功能的无条件转移语句,但它与 break语句不同,continue 语句并不跳出循环体, 语句并不跳出循环体,而只是根据循环控制条件确定是否继 续执行循环语句 ③返回语句 返回语句用于终止函数的执行, 返回语句用于终止函数的执行,并控制程序返回到调 用该函数时所处的位置。返回语句有两种形式: 用该函数时所处的位置。返回语句有两种形式: (l)return(表达式); return(表达式) return; (2)return; 如果return语句后边带有表达式, return语句后边带有表达式 如果return语句后边带有表达式,则要计算表达式 的值,并将表达式的值作为该函数的返回值。 的值,并将表达式的值作为该函数的返回值。若使用不带 表达式的第2种形式,则被调用函数返回主调用函数时, 表达式的第2种形式,则被调用函数返回主调用函数时, 函数值不确定。一个函数的内部可以含有多个return语句, return语句 函数值不确定。一个函数的内部可以含有多个return语句, 但程序仅执行其中的一个return语句而返回主调用函数。 return语句而返回主调用函数 但程序仅执行其中的一个return语句而返回主调用函数。 一个函数的内部也可以没有return语句,在这种情况下, return语句 一个函数的内部也可以没有return语句,在这种情况下, 当程序执行到最后一个界限符“ 处时 处时, 当程序执行到最后一个界限符“}”处时,就自动返回主调 用函数。 用函数。 7.4函数函数是c语言中的一种基本模块,实际上一个c语言程序 函数是c 语言中的一种基本模块, 实际上一个c 就是由若干个模块化的函数所构成的。前面我们已经看到, 就是由若干个模块化的函数所构成的。前面我们已经看到, main( 开始,main( c语言程序总是由主函数 main()开始,main()函数是一 个控制程序流程的特殊函数,它是程序的起点。 个控制程序流程的特殊函数,它是程序的起点。在进行程序 设计的过程中,如果所设计的程序较大,一般应将其分成若 设计的过程中,如果所设计的程序较大,一般应将其分成若 干个子程序模块,每个子程序模块完成一种特定的功能。在 干个子程序模块, 每个子程序模块完成一种特定的功能。 语言中, 子程序是用函数来实现的。 c 语言中 , 子程序是用函数来实现的 。 对于一些需要经常使 用的子程序可以按函数来设计, 用的子程序可以按函数来设计,并且可以将自己所设计的功 能函数做成一个专门的函数库,以供反复调用。 此外, 能函数做成一个专门的函数库 , 以供反复调用 。 此外 , c51 编译器还提供了丰富的运行库函数 提供了丰富的运行库函数, 编译器还提供了丰富的运行库函数,用户可以根据需要随时 调用。这种模块化的程序设计方法,可以大大提高编程效率。 调用。 这种模块化的程序设计方法, 可以大大提高编程效率。 7.4.1函数的定义从用户的角度来看,有两种函数: 从用户的角度来看,有两种函数:标准库函数和用户 自定义函数。 标准库函数是c51编译器提供的 编译器提供的, 自定义函数 。 标准库函数是 c51 编译器提供的 , 不需要用 户进行定义,可以直接调用。 户进行定义,可以直接调用。用户自定义函数是用户根据 自己的需要编写的能实现特定功能的函数, 自己的需要编写的能实现特定功能的函数,它必须先进行 定义之后才能调用。 定义之后才能调用。 函数定义的一般形式为: 函数定义的一般形式为: 函数类型 函数名(形式参数表) 函数名(形式参数表) 形式参数说明; 形式参数说明; { 局部变量定义; 局部变量定义; 函数体语句; 函数体语句; } 其中, 函数类型”说明了自定义函数返回值的类型。 其中,“函数类型”说明了自定义函数返回值的类型。 “函数名”是自定义函数的名字。 函数名”是自定义函数的名字。 函数名 形式参数表” “ 形式参数表 ” 中列出的是在主调用函数与被调用函 数之间传递数据的形式参数, 数之间传递数据的形式参数,形式参数的类型必须要加以说 明。ansi c标准允许在形式参数表中对形式参数的类型进行 说明。如果定义的是无参函数,可以没有形式参数表, 说明。如果定义的是无参函数,可以没有形式参数表,但圆 括号不能省略。 括号不能省略。 “ 局部变量定义” 是对在函数内部使用的局部变量进 局部变量定义 ” 行定义。 行定义。 函数体语句” “ 函数体语句 ” 是为完成该函数的特定功能而设置的 各种语句。 各种语句。 如果定义函数时只给出一对花括号{} {}而不给出其局部变 如果定义函数时只给出一对花括号{}而不给出其局部变 量和函数体语句,则该函数为所谓“空函数” 量和函数体语句,则该函数为所谓“空函数”,这种空函数 也是合法的。在进行c语言模块化程序设计时, 也是合法的 。 在进行c 语言模块化程序设计时, 各模块的功 能可通过函数来实现。开始时只设计最基本的模块, 能可通过函数来实现。开始时只设计最基本的模块,其它作 为扩充功能在以后需要时再加上。 为扩充功能在以后需要时再加上。编写程序时可在将来准备 扩充的地方写上一个空函数,这样可使程序的结构清晰, 扩充的地方写上一个空函数,这样可使程序的结构清晰,可 读性好,而且易于扩充。 读性好,而且易于扩充。 7.4.2函数的调用形式1.调用形式 语言程序中函数是可以互相调用的。 c 语言程序中函数是可以互相调用的 。 所谓函数调用就 是在一个函数体中引用另外一个已经定义了的函数, 是在一个函数体中引用另外一个已经定义了的函数, 前者 称为主调用函数,后者称为被调用函数。 称为主调用函数, 后者称为被调用函数。 主调用函数调用 被调用函数的一般形式为: 被调用函数的一般形式为: 函数名(实际参数表) 函数名(实际参数表); 其中, 函数名”指出被调用的函数。 其中,“函数名”指出被调用的函数。 实际参数表” 中可以包含多个实际参数, “ 实际参数表 ” 中可以包含多个实际参数 , 各个参数 之间用逗号隔开。 之间用逗号隔开 。 实际参数的作用是将它的值传递给被调 用函数中的形式参数。需要注意的是, 用函数中的形式参数 。 需要注意的是 , 函数调用中的实际 参数与函数定义中的形式参数必须在个数、 参数与函数定义中的形式参数必须在个数、 类型及顺序上 严格保持一致, 严格保持一致 ,以便将实际参数的值正确地传递给形式参 否则在函数调用时会产生意想不到的结果。 数 。 否则在函数调用时会产生意想不到的结果 。 如果调用 的是无参函数,则可以没有实际参数表, 的是无参函数 , 则可以没有实际参数表, 但圆括号不能省 略。 在c语言中可以采用三种方式完成函数的调用: 语言中可以采用三种方式完成函数的调用: 函数语句。在主调函数中将函数调用作为一条语句。 (1)函数语句。在主调函数中将函数调用作为一条语句。 函数表达式。 (2)函数表达式。在主调函数中将函数调用作为一个运算 象直接出现在表达式中。 象直接出现在表达式中。 函数参数。 (3)函数参数。在主调函数中将函数调用作为另一个函数用 的实际参数。 的实际参数。 2.函数的参数和函数的返回值 函数通常在进行函数调用时, 函数通常在进行函数调用时, 主调用函数与被调用函数 之间具有据传递关系。 之间具有据传递关系 。 这种数据传递是通过函数的参数实现 在定义一个函数时, 的 。 在定义一个函数时 , 位于函数名后圆括号中的变量名称 形式参数” 而在调用函数时, 为 “ 形式参数 ” , 而在调用函数时 , 函数名后面括号中的表 达式称为“ 实际参数” 形式参数在未发生函数调用之前, 达式称为 “ 实际参数 ” 。 形式参数在未发生函数调用之前 , 不占用内存单元, 因而也是没有值的只有在发生函数调用时 不占用内存单元 , 因而也是没有值的 只有在发生函数调用时 它才被分配内存单元, 它才被分配内存单元 , 同时获得从主调用函数中实际参数传 递过来的值。 递过来的值。 函数调用结束后,它所占用的内存单元也被释放。 函数调用结束后 , 它所占用的内存单元也被释放 。 实际 参数可以是常数,也可以是变量或表达式, 参数可以是常数, 也可以是变量或表达式,但要求它们具有 确定的值。进行函数调用时, 确定的值 。 进行函数调用时, 主调用函数将实际参数的值传 递给被调用函数中的形式参数。为了完成正确的参数传递, 递给被调用函数中的形式参数。 为了完成正确的参数传递 , 实际参数的类型必须与形式参数的类型一致。 实际参数的类型必须与形式参数的类型一致。 3.实际参数的传递方式 在进行函数调用时, 必须用主调函数中的实际参数来替 在进行函数调用时, 换被调函数中的形式参数,这就是所谓的参数传递。 换被调函数中的形式参数,这就是所谓的参数传递。在c语言 中 , 对于不同类型的实际参数,有三种不同的参数传递方式: 对于不同类型的实际参数, 有三种不同的参数传递方式: (1)基本类型的实际参数传递 当函数的参数是基本类型的变量时, 当函数的参数是基本类型的变量时,主调函数将实际参 值传递。 数的值传递给被调函数中的形式参数,这种方式称为值传递 数的值传递给被调函数中的形式参数,这种方式称为值传递。 前面讲过,函数中的形式参数在未发生数调用之前是不占用 前面讲过,函数中的形式参数在未发生数调用之前是不占用 内存单元的, 内存单元的,只有在进行函数调用时才为其分配临时存储单 而函数的实际参数是要占用确定的存储单元的。 元。而函数的实际参数是要占用确定的存储单元的。 值传递方式是将实际参数的值传递到为被调函数中形式参数 分配的临时存储单元中,函数调用结束后, 分配的临时存储单元中,函数调用结束后,临时存储单元被 释放,形式参数的值也就不复存在, 释放,形式参数的值也就不复存在,但实际参数所占用的存 储单元保持原来的值不变。 储单元保持原来的值不变。这种参数传递方式在执行被调函 数时,如果形式参数的值发生变化 形式参数的值发生变化, 数时,如果形式参数的值发生变化,可以不必担心主调函数 中实际参数的值会受到影响。因此值传递是一种单向传递 值传递是一种单向传递。 中实际参数的值会受到影响。因此值传递是一种单向传递。 (2)数组类型的实际参数传递 当函数的参数是数组类型的变量时,主调函数将实际参 当函数的参数是数组类型的变量时,主调函数将实际参 数数组的起始地址传递到被调函数中形式参数的临时存储单 这种方式称为地址传递 地址传递。 元,这种方式称为地址传递。地址传递方式在执行被调函数 形式参数通过实际参数传来的地址, 时,形式参数通过实际参数传来的地址,直接到主调函数中 去存取相应的数组}

我要回帖

更多关于 dac0832双极性输出 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信