|
第二章 C 程序的结构
◎ C 程序的结构:
┌─────────────────────────┐
│hello.c │←─ 范例文件名
├─────────────────────────┤
1│#include│←─ 范例原始码
2│main() │
3│{ │
4│ printf("Hello!"); │
5│} │
├─────────────────────────┤
│Hello! │←─ 范例执行结果
└─────────────────────────┘
第一列: #include
是用来定义一些函式的原型(prototype)、数据结构(struct)或是常数(constant)。C 在使用变量之前,该变量都要先行宣告(declear)才可使用,而使用函式也是一样,必须先宣告它的原型才可以。宣告函式的原型是为了让 C 能在编辑时作数据的型别检查,以减少错误的发生。 内建的函式原型定义都放在 INCLUDE\*.H 中,用 #include
就会将 INCLUDE\stdio.h 这个档引含。 stdio.h 由档名可知道是跟标准输出入(standard I/O)有关,档内定义了档案输出入、屏幕输出、键盘输入等相关函式的原型、数据结构及常数。 本例中的 printf() 就属于标准输出的函式。 引含 .h 档并不会让你的执行档变大或是变慢,而且还能让编辑器作正确的型别检查,所以要养成写 #include 的习惯。 ☆虽然在某些状况下,不加 #include <> 所产生的执行档,一样可以正常的执行。
第二列: main()
main() 就是主程序。程序在执行时,就是由这个函式开始执行。 在 C 语言中,内定的型别是 int ,所以原来的 main() 相当于是 int main(int)
★ 在这里正确的写法应该是 void main(void), 因为在这个简单的程序中,没有回传值,也没有输入参数。
☆ 回传值,是指一个函式在执行后传回的数值。
☆ 输入参数,是指一个函式可由参数决定执行的结果,这个部分在第八章中有详细的说明。
第三列: {
第五列: }
在第三列及第五列之间,属于 main() 函式的程序代码。
{ 表示程序由此开始, } 表示程序到此结束。
第四列: printf("Hello!");
是本程序要求系统做动作的指令,称之为「叙述」。在 C 语言中,每一叙述都以分号(;)做为结束。 在这个程序中,利用缩排的方式,使程序的层次分明,增加可读性。
在 C 语言中,调位字符( 如:空白(space)、定位(tab)及换列字符 )在编译时都会被忽略,所以可适时加入调位字符,使程序好看一点。 要注意的是,别把一个完整的个体拆开,如:main、printf 等,这些字本身是一个完整的个体,不可予以拆开。而在各个个体之间,可以任意加入调位字符。
☆ C 语言中的英文字母是有分大小写的,printf() 与 PrintF() 不同, 内建的函式大多是小写的,你自己写的函式,则可以用大写来做区隔。
◎ printf 的功用
printf() 的功用是在屏幕上输出数据。在 TC 中,在编辑区内输入printf ,再将光标移到 printf 这个字上,按下 Ctrl + F1 就会看到以下Help画面:
┌───────────────────── Help ─────────────────────┐← 这是 TC 的 Help 窗口
│ │
│ printf: formatted output to stdout │← printf 是将格式化的
│ │ 数据输出到 stdout
│ int printf(const char *format, ...); │← printf 的语法
│ │
│ Prototype in stdio.h │← 要用 printf 应该
│ │ #include 的檔
│ Print formats a variable number of arguments │← 使用说明:不同的格式
│ according to the format, and sends the output │ 须要不同的参数,这些
│ to stdout. Returns the number of bytes output. │ 数据会送到stdout。传
│ In the event of error, it returns EOF. │ 回值是输出的byte数,
│ │ 若发生错误则传回 EOF
│ See also ecvt fprintf putc │← 可参考相关指令:
│ puts scanf vprintf │ ecvt,fprintf,putc,
│ │ puts,scanf,vprintf
└────────────────────────────────────────────────┘
在用 TC 的整合环境中,只要将光标移到想进一步了解的指令或内建的函式上,按下 Ctrl + F1 就可以叫出 TC 的 Help 说明窗口,得到该指令或函式的相关说明。
printf 的语法:int printf(const char *format, ...);
其中 const char *format 指的是一个格式化的字符串。 const 是常数的意思,在此表示 format 这个字符串指针传入 printf 函式后,它的值不会被改变。
...指的是不定参数,参数的数目取决于 format 字符串的内容,这些参数,通常是一些你要秀出来的变量。 简单来说: printf( "输出格式(含控制字符串)" , 要印出的数据 );
在 C 语言中是用双引号(")来引含字符串,也就是在双引号内的数据,是一个字符串。本章只介绍 %d 这个控制字符串,其它的控制字符串在第四章会讲到。 %d 表示以整数 10 进位的方式秀出数据。在输出格式(含控制字符串) 内有几个%d ,在要印出的数据内就要有几个整数来对应。
┌────────────────────────────────────────────────────────────────┐
│arith.c │
├────────────────────────────────────────────────────────────────┤
1│#include│
2│void main(void) │
3│{ │
4│ printf("%d + %d = %d\n", 8 , 2 , 8+2 ); │
5│ printf("%d - %d = %d\n", 8 , 2 , 8-2 ); │
6│ printf("%d * %d = %d\n", 8 , 2 , 8*2 ); │
7│ printf("%d / %d = %d\n", 8 , 2 , 8/2 ); │
8│} │
├────────────────────────────────────────────────────────────────┤
│8 + 2 = 10 │
│8 - 2 = 6 │
│8 * 2 = 16 │
│8 / 2 = 4 │
└────────────────────────────────────────────────────────────────┘
我们以第四列的叙述作说明:
printf("%d + %d = %d\n", 8 , 2 , 8+2 );
↑ ↑ ↑ │ │ │
│ │ └────────│─────│─────┘
│ └───────────│─────┘
└────────────────┘
在 输出格式(含控制字符串) 内有 3 个 %d ,所以在 要印出的数据 的部分有8 , 2 , 及 8+2 三个整数对应,所以输出来的结果就是
8 + 2 = 10
在 输出格式(含控制字符串) 的最后有 \n 符号,这是一个控制字符,表示要更换到下一列,其它的控制字符在第四章会提到。若将本例中的 \n 都删除,那秀出的结果会像这样子:
8 + 2 = 108 - 2 = 68 * 2 = 168 / 2 = 4
◎ C 的四则运算
计算机语言用的四则运算符号几乎都是相同的:
四则运算符号 意 义 范 例 结 果
============ ===================== ============== ==========
+ 加法 4 + 2 6
- 减法 ( 或代表负号 ) 4 - 2 2
* 乘法 4 * 2 8
/ 除法 4 / 2 2
============ ===================== ============== ==========
相关运算符号 意 义 范 例 结 果
============ ===================== ============== ==========
++ 变数值加 1 i++ 或 ++i i 值加 1
-- 变数值减 1 i-- 或 --i i 值减 1
% 整数除法的余数 4 % 2 0
============ ===================== ============== ==========
在书中提到 C 语言没有提供次方的功能,指的是在某些计算机语言可以用 ** 表示次方,如: 2 ** 3 ,表示 2 的 3 次方;有的用 ^ 表示,如: 2 ^ 8 ,表示2 的 8 次方。在 C 语言,没有运算符号可以表示次方,但是 C 语言有提供次方的函式: pow(), pow( 2 , 3 ) 表示 2 的 3 次方。
一个式子如果有多个运算的话,C 是以先乘除后加减的方法来运算,当然我们也可以用括号 ( ) 来改变这个法则,只要有括号,就优先运算。另外,在 C 语言内中括号 [ ] 及 大括号 { } 是有其它的用途,所以在作数学运算时,只要用括号,就只能用小括号 ( ),小括号可以多层,C 在运算时,是由最内层开始运算。
范例: ( 1 + 2 * ( 3 + 4 ) ) * 5 - 6 * 7 / 2 + 8
= ( 1 + 2 * ( 7 ) ) * 5 - 6 * 7 / 2 + 8
= ( 15 ) * 5 - 6 * 7 / 2 + 8
= 75 - 42 / 2 + 8
= 75 - 21 + 8
= 62
◎ 批注(Comments)
通常老师会要求初学者在程序的每一列加上批注,这是为了让初学者知道自己在写些什么程序代码,了解为什么要这样写,而不只是照著书 Keyin 程序。写批注有助于自己了解程序的内容,便于日后的修改。但写批注对于某些程序设计师而言可说是一种噩梦,因为写批注所花的时间可能会与写程序的时间相去不远,认为写批注只是在浪费时间。 对一个相当好的程序设计师而言,也许写批注真的是浪费时间,因为好的程序代码本身就已经隐含了批注,这也是写程序相当高的境界。 对一般的程序设计师而言,写一些批注还是比较好的作法,特别是某些程序代码是你花了一段时间才想到的「特殊」方法,加上一些批注,说明一下这个「特殊」的方法,以后要修改才能快速进入状况,否则,你可能会佩服自己当时是如何想到的这个方法,又再花一段时间才知道自己在写些什么程序代码。 讲了这么多批注的正反面(正面居多)论调,在 C 语言中要如何写批注呢? 只要用 /* 和 */ 将你要的批注内容包起来就可以了。C 在编译时,会将 /* */ 内的数据略去,就如同调位字符一样。唯一的例外是:当 /* */ 在一组双引号 " 内时,它们就属于这组双引号所包含的字符串。 在 C++ 语言中则可用//当批注.
┌────────────────────────────────────────────────────────────────┐
│comments.c or comments.cpp │
├────────────────────────────────────────────────────────────────┤
1│#include/* prototype : printf() */ │
2│void main(void) // main program │
3│{ │
4│/* 所有的程序代码都变成批注,所以这个程序目前是空的 */ │
5│/* printf("%d + %d = %d\n", 8 , 2 , 8+2 ); */ │
6│/* printf("%d - %d = %d\n", 8 , 2 , 8-2 ); │
7│ printf("%d * %d = %d\n", 8 , 2 , 8*2 ); │
8│ printf("%d / %d = %d\n", 8 , 2 , 8/2 ); // division │
9│*/ │
10│} // end of program │
├────────────────────────────────────────────────────────────────┤
└────────────────────────────────────────────────────────────────┘
◎ 巢状批注(Nested Comments)
┌────────────────────────────────────────────────────────────────┐
│nestcom0.c │
├────────────────────────────────────────────────────────────────┤
1│#include/* prototype : printf() */ │
2│void main(void) │
3│{ │
4│/* 这个程序必须把巢状批注的设定打开,才不会有错误 */ │
5│/* │
6│ printf("%d + %d = %d\n", 8 , 2 , 8+2 ); │
7│/* printf("%d - %d = %d\n", 8 , 2 , 8-2 ); */ │
8│ printf("%d * %d = %d\n", 8 , 2 , 8*2 ); │
9│ printf("%d / %d = %d\n", 8 , 2 , 8/2 ); │
10│*/ │
11│} │
├────────────────────────────────────────────────────────────────┤
└────────────────────────────────────────────────────────────────┘
上面的例子,有四组批注 /* */ ,其中第三组及第四组的批注之间有部分重迭。想要 Compile 没有错误,必须第 5 列的 /* 与 第 10 列的 */ 配,也就是第 5 列到第 10 列都是批注;另外第 7 列的 /* 与 第 7 列的 */ 配,也就是第 7 列是批注。这种批注方式,我们称之为巢状批注。Turbo C 内定是不可使用巢状批注的,上面的例子会是第 5 列的 /* 与 第 7 列的 */ 配,结果在第 10 列的 */ 会变成是多余的,造成 Compile 错误。
打开巢状批注的方法:
按下 F10 → Options → Compiler → Source → Nested comments Off
将 Off 设为 On 就可以了。
◎ 巢状批注的使用时机
在前面的例子只是为了说明巢状批注,也许你会觉得这样的用法是自找麻烦,但是以下的例子,你就会认为有巢状批注的功能还是比较好的。在 nestcom1.c 中,每一列的 printf(); 后面都加上了批注。若要把这几列程序变成批注,不使用巢状批注,就会像 nestcom2.c 一样,必须在每一列的 printf(); 前后再加上 /* */,若是使用巢状批注,就像 nestcom3.c 一样,只要在这几列的前后加 /* */ 就可以了。
┌────────────────────────────────────────────────────────────────┐
│nestcom1.c │
├────────────────────────────────────────────────────────────────┤
1│#include/* prototype : printf() */ │
2│void main(void) │
3│{ │
4│ /* 这个程序在每一个叙述后都加上了批注 */ │
5│ │
6│ printf("%d + %d = %d\n", 8 , 2 , 8+2 ); /* 8 + 2 = 10 */ │
7│ printf("%d - %d = %d\n", 8 , 2 , 8-2 ); /* 8 - 2 = 6 */ │
8│ printf("%d * %d = %d\n", 8 , 2 , 8*2 ); /* 8 * 2 = 16 */ │
9│ printf("%d / %d = %d\n", 8 , 2 , 8/2 ); /* 8 / 2 = 4 */ │
10│ │
11│} │
├────────────────────────────────────────────────────────────────┤
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│nestcom2.c │
├────────────────────────────────────────────────────────────────┤
1│#include/* prototype : printf() */ │
2│void main(void) │
3│{ │
4│/* 这个程序不用把巢状批注的设定打开,也不会有错误 */ │
5│ │
6│/* printf("%d + %d = %d\n", 8 , 2 , 8+2 ); */ /* 8 + 2 = 10 */ │
7│/* printf("%d - %d = %d\n", 8 , 2 , 8-2 ); */ /* 8 - 2 = 6 */ │
8│/* printf("%d * %d = %d\n", 8 , 2 , 8*2 ); */ /* 8 * 2 = 16 */ │
9│/* printf("%d / %d = %d\n", 8 , 2 , 8/2 ); */ /* 8 / 2 = 4 */ │
10│ │
11│} │
├────────────────────────────────────────────────────────────────┤
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│nestcom3.c │
├────────────────────────────────────────────────────────────────┤
1│#include/* prototype : printf() */ │
2│void main(void) │
3│{ │
4│/* 这个程序也必须把巢状批注的设定打开,才不会有错误 */ │
5│/* │
6│ printf("%d + %d = %d\n", 8 , 2 , 8+2 ); /* 8 + 2 = 10 */ │
7│ printf("%d - %d = %d\n", 8 , 2 , 8-2 ); /* 8 - 2 = 6 */ │
8│ printf("%d * %d = %d\n", 8 , 2 , 8*2 ); /* 8 * 2 = 16 */ │
9│ printf("%d / %d = %d\n", 8 , 2 , 8/2 ); /* 8 / 2 = 4 */ │
10│*/ │
11│} │
├────────────────────────────────────────────────────────────────┤
└────────────────────────────────────────────────────────────────┘
单片机教程,五系列(55讲)电子书全集下载论坛精选:
■ 单片机c语言,10小时学会C 语言 (一)
第一章 C 语言简介与Turbo C 的使用
■ 单片机c语言,10小时学会C 语言 (二)
第二章 C 程序的结构
■ 单片机c语言,10小时学会C 语言 (三)
第三章 常数与变数
■ 单片机c语言,10小时学会C 语言 (四)
第四章 基本输出入函式
■ 单片机c语言,10小时学会C 语言 (五)
第五章 流程图与抉择指令
■ 单片机c语言,10小时学会C 语言 (六)
第六章 循环与自动重复
■ 单片机c语言,10小时学会C 语言 (七)
第七章 数组与指针
■ 单片机c语言,10小时学会C 语言 (八)
第八章 函数与呼叫
■ 单片机c语言,10小时学会C 语言 (九)
第九章 档案存取
无内容
jgf
看看咋样
DSDFS
ok
ok
What is chip select
gan
好
trh
hao
无内容
无内容
]p
fd
njhsdsd
:)
jhkjhkjh
q
/..
dddddddddddddddd
xie xie
d
kankan!
kankan!
ddddddddddddddddddddddddddddd
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
dddddddddddddddddddddddddddddddddddddd
