2 c语言基本概念

2.1 编写一个简单地c程序

2.1.1 程序:显示双关语

注意:编译器往往要求文件的扩展名为.c

1
2
3
4
5
# include <stdio.h>
int main()
{

printf("To c, or not to c:that is the question.\n");
}

2.1.2 编译和链接

预处理器(processor):类似编辑器,它可以给程序添加内容,也可以对程序进行修改。
指令(directive):#开头的命令,由预处理器执行为程序文件添加内容。
目标代码(object code):编译生成的机器指令(需要链接才能运行)
编译器(complier):在编译阶段将程序翻译成目标代码。比如UNIX下的cc
链接器(linker):把编译产生的目标代码和任何其它附加代码整合在一起,生成可执行文件。

1
2
3
4
5
6
7
8
st=>start: 编写程序
e=>end: 执行

op1=>operation: 预处理:执行指令,引入相关代码
op2=>operation: 编译:将预处理后的代码翻译为目标代码
op3=>operation: 链接:整合目标代码和附加代码(包括库函数),生成完全可执行的程序

st->op1->op2->op3->e

cc

-o 允许为含有可执行程序的文件命名

使用技巧

  • 自动链接:使用cc进行编译时,系统会自动进行链接操作,不需要单独的链接命令
  • 可执行文件命名:默认为文件名.out
1
$ cc -o pun pun.c# 可执行文件名为pun

gcc(GNU C Complier)

-Wall 使gcc比平常更彻底地检查程序并警告可能发生的问题

简介:UNIX系统中最常用的编译器之一。
自由软件基金会(Free Software Foundation, FSF):Richard M.Stallman创建,旨在对抗UNIX正版软件的使用限制和高额费用。重写了大量UNIX软件并免费发布。

1
$ gcc -Wall -o pun pun.c

2.2 简单程序的通用形式

一般形式:

1
2
3
4
指令
main(){
语句
}

3个关键语言特性:指令 函数 语句

2.2.1 指令

头文件:都包含一些标准库的内容
语法:

  1. 所有的指令都以#开始,用以和c程序的其它代码进行区分
  2. 默认情况下指令是一行
  3. 在每条指令的结尾既没有分号也没有其它特殊标记

2.2.2 函数

定义:一系列组合在一起并且赋予了名字的语句
分2类:

  • 程序员编写的函数
  • 编译器提供的库函数(library function)

main函数

简介:c程序可以包含多个函数,但前置规定必须有一个main函数
特点:

  • 在执行程序时系统会自动调用main函数
  • 名字main是至关重要的,不能改写为begin start,甚至MAIN

注意:建议在main函数末尾用一条return结束语句,Q&A如果不这样做,某些编译器可能会产生一条警告信息。

2.2.3 语句

定义:程序运行时执行的命令
语法:

  • 除复合语句和指令除外,每条语句都要用;结尾

2.2.4 显示字符串

字符串字面量:用一对双引号保卫的一系列字符
printf:不会自动跳转到下一行(除非在末尾添加\n

1
2
printf("To, or not to c:");
printf("that is the question.\n:");

2.3 注释

语法:/**/,可以出现在程序的任何位置,单独占行或和其它程序放在同一行。

2.3.1 文档说明

2.3.1.1 举个栗子

1
2
3
4
5
6
7
8
9
10
11
/* Name:	pun.c 			 */
/* Purpose: Prints a bad pun */
/* Author: K. N. King */
/* Date written: 5/21/95 */

# include <stdio.h>
int main()
{

printf("To c, or not to c:that is the question.\n");
return 0;
}

2.3.1.2 其它形式

1
2
3
4
5
6
/******************************
* Name: pun.c *
* Purpose: Prints a bad pun *
* Author: K. N. King *
* Date written: 5/21/95 *
* ****************************/

1
2
3
4
5
6
/*
* Name: pun.c
* Purpose: Prints a bad pun
* Author: K. N. King
* Date written: 5/21/95
*/

2.3.2 翼型注释

1
main()/* Beginning of main program */

2.4 变量和赋值

2.4.1 类型

简介:类型用来寿命变量所存储的数据的种类。类型会影响变量的存储方式,所以选择合适的类型非常关键。

intfloat

类型 说明 速度 存储 取值特点 备注
int 整数 较快 占用少 取值范围小
float 浮点数 较慢 占用多 取值范围大 存储的数值往往只是数值的近似值,存在摄入误差

2.4.2 声明

语法:

  • 每条声明都要以;结尾
  • 声明多个相同类型的变量时,中间用,隔开

建议:在声明和语句之间留出空白。
注意:main 函数包含声明时,必须把声明放置在语句之前。

1
2
3
4
main(){
声明
语句
}

2.4.3 赋值

语法:变量 = 表达式
表达式:赋值运算的右侧的包含常量、变量和运算符的公式。

2.4.4 显示变量的值

方式:通过printf

1
printf("Height: %d Length: %d\n", height, length);

2.4.5 程序:计算箱子的空间重量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* Name:	pun.c 			 */
/* Purpose: Prints a bad pun */
/* Author: K. N. King */
/* Date written: 5/21/95 */

# include <stdio.h>
int main()
{

int height, length, width, volume, weight;

height = 8;
length = 12;
width = 10;
volume = height * length * width;
weight = (volume + 165) / 166;

printf("Dimensions: %dx%dx%d\n", length, width, height);
printf("volume(cubic inches):%d\n", volume);
printf("Dimensional weight (pounds):%d\n", weight);

return 0;
}
1
2
3
4
5
$ gcc -Wall -o pun pun.c
$ ./pun
Dimensions: 12x10x8
volume(cubic inches):960
Dimensional weight (pounds):6

2.4.6 初始化

初始化式(initializer):在变量声明中加入初始值。
注意:程序开始执行时,默契热情况下某些变量会自动设置为零,而大多数变量则不会。

1
int height, length = 12, width = 12;/*其中第一个个变量的值未知*/

2.4.7 显示表达式的值

在任何需要数值的地方,都可以使用具有相同类型的表达式。

1
prinf("%d\n", height * length * width);

2.5 读入输入

scanf:和printf相对应的c库函数。

1
2
scanf("%d", &i);/*读入一个整数给i*/
scanf("%f", &x);/*读入一个float数值给x*/

程序:计算箱子的空间重量(改进版)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
* Computes the dimensioal weight of a box
* from input provided by the user
*/

# include <stdio.h>
int main(){
int height, length, width, volume, weight;

printf("Enter height of box:");
scanf("%d", &height);
printf("Enter length of box:");
scanf("%d", &length);
printf("Enter width of box:");
scanf("%d", &width);

volume = height * length * width;
weight = (volume + 165) / 166;


printf("volume(cubic inches):%d\n", volume);
printf("Dimensional weight (pounds):%d\n", weight);

return 0;
}
1
2
3
4
5
6
$ ./dweight2 
Enter height of box:2
Enter length of box:3
Enter width of box:4
volume(cubic inches):24
Dimensional weight (pounds):1

2.6 定义常量

宏定义(macro definition):对程序进行预处理时,预处理器会把每一个宏用其表示的值替换回来。
语法:# define 宏变量名 字面量或表达式
注意:

  • 常量的名字使用大写字母(沿用了10几年的规范)
  • 当宏包含运算符时,必须使用括号把表达式括起来

程序:华氏温度转换为摄氏温度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/************************************************
* Converts a Fahrenheit temperature to Celsius *
* **********************************************/


# include <stdio.h>

# define FREEZING_PT 32.0
# define SCALE_FACTOR (5.0 / 9.0)/*如果是(5/9)结果为0*/
int main(){
float fahrenheit, celsius;

printf("Enter Fahrenheit temperature:");
scanf("%f", &fahrenheit);

celsius = (fahrenheit - FREEZING_PT) * SCALE_FACTOR;/*温度转换*/

printf("Celsius equivalent:%.1f\n", celsius);/*保留小数点后一位*/
return 0;
}
1
2
3
$ ./celsius 
Enter Fahrenheit temperature:32
Celsius equivalent:0.0

2.7 标识符

定义:变量、函数、宏和其他实体的名字成为标识符(identifier)。
规则:

  1. 可以包含字母、数字和下划线
  2. 必须以字母或者下划线开头
  3. 区分大小写
  4. 对标识符的最大长度没有限制
  5. 不能使用关键字作为标识符
    Alt text

2.8 c语言程序的布局

原则

  • 语句可以划分在任意多行内
  • 记号间的空格应该便于肉眼区别记号。因此通常在每个运算符的前后都放上一个空格。
  • 缩进有助于轻松识别程序嵌套
  • 空行可以把程序划分成逻辑单元,从而使读者更容易辨别程序的结构。