一、C语言程序的 基本结构
⑴一个C程序由一个或多个函数组成,但有且仅有一个主函数(main 函数)main函数是程序执行的入口,可置于程序的任何位置。
⑵程序中可以有预处理命令(如:include 命令)。预处理命令通常放 在程序的最前面。
⑶每个语句以分号结尾;预处理命令、函数头和花括号“}”之后不能 加分号。
⑷ 函数包括函数的说明部分和函数体;函数体包括变量说明部分和 执行部分;函数体由一对花括号“{ }”括起来。
⑸括在/*„*/内的文本为注释。
⑹一行可以写几个语句,一个语句也可以写在多行上。
⑺程序区分大小写字母。一般变量、语句等用小写字母书写;符号常 量、宏名等用大写字母书写。
⑻标识符(用户编程时使用的名字)和保留字(在高级语言中已经定义过的字)之间须加空格以示分隔。
C语言保留字
auto :声明 自动变量
double :声明双精度 变量或函数
int: 声明 整型变量或函数
struct:声明 结构体 变量或函数
break:跳出当前循环
else :条件语句否定分支(与 if 连用)
long :声明长 整型变量或函数
switch :用于开关语句
case:开关语句分支
enum :声明枚举类型
register:声明 寄存器变量
typedef:用以给 数据类型取别名
char :声明 字符型 变量或函数
extern:声明 变量是在其他文件正声明
return :子程序返回语句(可以带参数,也可不带参数)
union:声明共用 数据类型
const :声明只读 变量
float:声明 浮点型 变量或函数
short :声明短 整型变量或函数
unsigned:声明无符号类型 变量或函数
continue:结束当前循环,开始下一轮循环
for:一种 循环语句
signed:声明有符号类型 变量或函数
void :声明函数无返回值或无参数,声明无类型 指针
default:开关语句中的“其他”分支
goto:无条件跳转语句
sizeof:计算 数据类型长度
volatile:说明 变量在程序执行中可被隐含地改变
do : 循环语句的循环体
while : 循环语句的循环条件
static :声明 静态变量
if:条件语句
常见注释规范:
1、在C语言中有两种注释方式: 一种是以/*开始、以*/结束的块注释(block comment); 另一种是以//开始、以换行符结束的单行注释
(line comment)
2、一般情况下,源程序有效注释量必须在20%以上,边写代码边注释。
3、文件头部应进行注释,注释必须列出:版权说明、版本号、生成日期、 作者、内容、功能、修改日志等。
/*****************************************************************************
Copyright: 1988-1999, xxxxxx xxx. xx., xxx. File name: 文件名 Description: 用于详细说明此程
序文件完成的主要功能,与其他模块或函数的接口, 输出值、取值范围、含义及参数间的控制、顺序、独立或依
赖等关系 Author: 作者 Version: 版本 Date: 完成日期 History: 修改历史记录列表, 每条修改记录应包
括修改日期、修改者及修改内容简 述。
*****************************************************************************/
4、函数头部应进行注释,列出:函数的目的/功能、输入参数、输出参数、 返回值、调用关系(函数、表)等。
/*************************************************
* 函数介绍:
* 输入参数:
* 输出参数:
* 返回值:
*/
*************************************************/
二元一次方程的两个解
二、C语言基本数据类型
数据(Data)
程序需要使用数据。
数据是信息的载体。
数据有多种形式:数、字符、图片等
常量(Constants)
在程序运行之前可以预先设定,并在整个运行过程中 没有变化的数据。 (例如圆周率3.14)
变量(Variables)
在程序运行过程中可能变化或被赋值的数据。 (例如的半径和面积)
数据类型的作用
定数据的存储方式和占用的存储空间的大小。
决定可以进行的操作
C语言的数据类型
基本类型
整型(integer) 符型(character) 点型(floatingpoint)枚举类型(enumeration)
构造类型
结构体(structure)共用体(union)数组(array)
指针类型(pointer)
空类型(void)
下面给出一些类型的数据(仅供参考,实际值与所 使用的操作系统、编译 系统、机器有关)
C标准只规定:short ≤ int ≤ long
最大最小值参考<limits.h>:
limits.h头中确定各种变量类型的各种属性。在这个头中定义的宏限制的char,int和long类型,如各种变量的值。
这些限制指定一个变量,无法存储任何值超越这些限制,例如一个无符号的字符最多可以存储的最大值为255。
库文件:https://www.yiibai.com/c_standard_library/limits_h.html#
这个网址里特别全~
整型常量有三种形式:
十进制(decimal)整数
12 65 65535
八进制(octal)整数:带前缀 0(zero) 014 0101 0177777
十六进制(hexadecimal)整数:带前缀 0x 或 0X 0xc 0x41 0xffff
默认类型是int,即有符号的基本整型。
可以加上后缀 u 或 U 表示无符号整数,或者 l 或 L 表 示长整数。 0xb5Lu
声明变量(Declaration)
变量在使用之前必须被声明。
声明语句的格式: <类型说明符> <变量名>[,<变量名>[,...]];
举例
<类型说明符> <变量名>[,<变量名>[,...]];
int counter;
int width, height;
short x, y;
long number;
初始化(Initialize)变量
为变量赋一个初始值。
可以在声明语句中初始化变量。
举例
int counter = 0;
int width = 352, height = 288;
C语言的字符类型:char
占一个字节;
可视为一个有符号的整数。
举例(cw02-03.c)
字符常量
用单引号括起来的一个字符。 'x' '9' '+
C语言将字符常量视为int类型。
举例(cw02-04.c)
char c1, c2;
c1=‘a’;
c2=‘bc’;
如果int类型为16位,char类型为8位,那么对于’bc‟,将把’b‟和’c‟的ASCII码值存储在两个字节 中,并把’c‟赋值给变量c2。
注意:不同系统处理方式不同,结果不同
转义字符(escape character)
指代一些特殊的字符。(打印不出来的字符)
浮点数也有多种类型
类型名称及典型大小
浮点型常量有两种形式:
十进制形式
12.3 .65 0.
指数形式:< 小数 > < e | E > < 整数 >
默认类型是double。
可以加上后缀 f 或 F 表示float类型,或者 l 或 L 表示 long double类型,否则该常量是double类型。
2.3f 1.2L .1E5f
浮点型变量的声明和初始化
float radius;
double x = 0.0, y = 0.0;
不能写成: double x = y =0.0;
在算术表达式中允许不同类型的数据参与运算
例如,10+‘a’+1.5-65.4*‘b’
在进行运算时,不同类型的数据要先转换成同一类型, 然后进行运算
转换方式有两种:
自动转换:数据类型自动由低级向高级转换。
这种类型转换由编译系统自动完成。
转换规则
强制转换:将表达式的值强制转换成指定的数据类型
类型转换运算符: ( )
(<类型说明符>)[(]<表达式>[)]
将一个表达式的值转换成指定的类型。
属单目运算符。
优先级:2
结合性:从右往左。
举例
(double)a
(int)(x+y) ≠(int)x+y //因为是从右向左结合的
(float)(5/3) =1.0
三、输入输出和库函数
字符串常量
用双引号括起来的字符序列。 "this is a string" "x" "12345"
字符串常量的存储方式
字符串中的字符存放在相邻的存储单元中,每个字符 占用一个单元,在最后加上一个空字符(\0)作为结束 标识符
字符串常量和字符常量的区别
字符‘x’是基本型数据。
字符串“x”是构造型数据。
占用的存储空间大小不同
符号常量
符号常量是用一个标识符表示的常量。
定义规则 #define < 符号常量名 > < 字符串 >
#define MAXSIZE 20
#define WELCOME "Welcome to you!"
#define PI 3.14
为什么需要符号常量
名字比数字包含的信息多。
便于维护
如果需要在多个地方用到同一个常量,而且必须改变它的值, 则只需要修改其符号常量的定义。
另一种定义符号常量的方法
使用const把一个变量声明转换成常量声明。
举例
const int MAX_NUMBER = 30; (MAX_NUMBER是只读的)
C语言中数据的输入、输出是由函数来实现的
字符输入函数:getchar()
字符输出函数:putchar()
格式输入函数:scanf()
格式输出函数:printf()
注:getchar();其返回值类型为int类型。eg. int getchar(void);
它们都属于标准输入输出库函数,其原型(prototype) 都在stdio.h头文件(header file)中。
printf()函数
使用形式 printf(<格式控制字符串>, <输出列表>);
按格式控制字符串规定的格式,向指定的输出设备输 出输出列表中的输出项
格式控制字符串
由双引号括起来的字符串,用于指定输出格式
举例
printf(“n=%5d,f=%5.2f\n”, 3, 6.235)
n=%5d 普通字符 原样输出
%5.2f 格式说明符(转换规则) % [修饰符] 格式字符 指定数据的输出格式
输出列表
需要输出的数据列表,彼此间用逗号分隔
输出项可以是任意合法的表达式
格式说明符小结
scanf()函数
使用形式 scanf(<格式控制字符串>, <地址列表>);
按格式控制字符串规定的格式,从指定的输入设备读入数据,并存放到地址列表中的各地址项指定的变量 中
使用说明 格式控制字符串,由双引号括起来的字符串,用于指定输入格式地址列表 由若干个变量的地址组成
地址列表
scanf(“%d,%d”, &a, &b);
取地址运算符:&
&<变量>
得到变量在内存中的地址。
格式字符
格式修饰符
格式说明符小结
用c格式字符输入字符时,若格式控制字符串中加入空格作为分隔符,那么输入时各数据之间可以 加任意多个空格、制表符或回车符)。
例:scanf(‚%c %c %c‛,&a,&b,&c);
输入:a b c↙
则 a=a,b=b,c=c
在下列情况下可认为数据输入结束: 回车、遇非法输入
如果%c中间不加空格会读入空格
使用说明
程序中可以不明确指定包含 stdio.h 头文件
#include <stdio.h>(可省略)
使用标准库中的数学函数
包含数学函数库的头文件 #include <math.h>
常用的数学函数的原型
取绝对值函数
int abs(int n) double fabs(double x)
取平方函数
double pow(double x, double y)
取根号函数
double sqrt(double x)
使用举例 int n = abs(-21); n=21;
double v = pow(r, 3.0); v=9.0
四、运算符和表达式
取模运算(%),结果是两个整数相除的余数。 这句话要好好理解
例如,7%5 = 2,-2%3 = -2(符号与被除数有关)
算术表达式
算术表达式,是由算术运算符和括号将运算对象(也 称为6操作数)连接起来的式子。
运算对象包括常量、变量、函数等
ps:表达式有自己的值(计算 结果),其值的类型就是表达式的类型(也就是结果所代表的类型)。
赋值运算符
简单赋值运算符:=
复合赋值运算符:+=,-=,*=,/=,%=
优先级:14
结合性:从右往左
赋值表达式
<变量> <赋值运算符> <表达式>
d = 23
作用:将表达式的值赋给变量。
赋值表达式的值就是被赋值的变量的值
自增和自减运算符
自增运算符:++ 将操作数的值增一。
自减运算符:-- 将操作数的值减一。
操作数必须是整型和字符型变量。
单目运算符。
优先级:2
结合性:从右往左。
关系运算(比较运算)
比较两个值,结果为真或假。
举例:a>3
如果a=8,则结果为‚真 如果a=1,则结果为‚假
用关系运算进行条件判断
关系表达式表示一个条件,根据其结果判断条件是否 满足。
举例:a>3
如果a=8,结果为真,即条件满足
如果a=1,结果为‚假‛,即条件不满足
关系运算符
关系表达式
<表达式1> <关系运算符> <表达式2>
表达式1和表达式2可以是任何表达式。
a>b
m+n<=20
c!='y'
(x>z)==(y>z)
关系表达式的值是一个逻辑值: 真 或 假
C语言没有逻辑类型,因此用整数 1 表示真,用整数 0 表示假
即关系表达式的值是整数 1 或 0 。
举例
若a=1,b=2,c=3
条件运算符:? :
三目运算符
右结合
条件表达式 <表达式1>?<表达式2>:<表达式3>
先求解表达式1,
若其值为真(非0)则将表达式2的值作为整个表达式的取值,
否则(表达式1的值为0)将表达式3的值作为整个表达式的取值。
逻辑运算符
!(逻辑非)
&&(逻辑与)
|| (逻辑或)
逻辑表达式
[<表达式1>] <逻辑运算符> <表达式2>
表达式1和表达式2可以是任何表达式
(x>5)||(x<-5)
!(a<b)&&(m!=n) 特意去跑了一遍!(a<b)是一个整体 (m!=n) 是一个整体 a1 b0 m1 n0表达式的值为1
(a+b>c)&&(a+c>b)&&(b+c>a)
布尔变量与零值比较
规则:不可将布尔值直接与0,1或者true,false比较
bool flag;
if (flag) //表示flag为真
if (!flag) //表示flag为假
//以下是不良风格,编程时不要使用
if (flag == 0)
if (flag == 1)
if (flag == false)
if (flag == true)
整型变量与零值比较
规则:应当将整形变量用‚==”或‚!=”直接与0比较
int num;
if (num == 0)
if (num != 0)
//以下不可模仿bool值的比较方式以免被当成是bool变量
if (num) if (!num)
浮点变量与零值比较
规则:不可将浮点型变量用“==”或者“!=”与任何数字比较
不论是float变量还是double变量,都有精度限制。
所以一定要避免将浮点型变量 用“==”或“!=”与数字比较,应该设法换成“>=”或者“<=”
形式
float epsinon = 0.000001; //设定允许的误差
float x;
if (x == 0.0) //隐含错误的比较方法,交题会报错
if ((x >= -epsinon) && (x <= epsinon)) //正确的比较方法
指针变量与零值比较
规则:应当将指针变量用“==”或者“!=”与NULL比较
指针变量的零值是‚空(记为NULL),尽管NULL与0值相同,但是两者意义不同。
char ptr;
//显示比较,强调ptr是指针变量
if (ptr == NULL) (有时候我们可能会看到 if (NULL == p) 这样古怪的格式。)
if (ptr != NULL)
//不要写成
if (ptr == 0)
if (ptr != 0)
if (ptr)
if (!ptr)
五、结构语句
C语言程序常用的语句
流程控制语句
条件判断语句(构造选择结构)
if if-else switch
循环执行语句 (构造循环结构)
while do-while for
跳转语句
goto
用法
#include<stdio.h>
int n;
int main(void)
{
printf("input a string: ");
loop:
if (getchar()!='\n')
{
n++;
goto loop;
}
printf("output: %d\n",n);
}
例如输入:abcdefghijklmnopqrstuvwxyz
然后回车Enter
输出:26
本例用if语句和goto语句构成循环结构。当输入字符不为'\n'时即执行n++进行计数。
然后转移至if语句循环执行,直至输入字符为'\n'才停止循环。
if 选择结构
只有在条件满足时,才会执行一个操作;否则就会跳过这个操作
if-else 选择结构
条件满足时所执行的操作与不满足时所执行的操作不同。但整个操作只进行一次
switch
在一个表达式可能的一组固定数量的值中进行选择, 并采取不同的动作
switch(<条件表达式>)
{
case <常量表达式_1>: <动作_1>; [break;]
case <常量表达式_2>: <动作_2>; [break;]
……
case <常量表达式_n>: <动作_n>; [break;]
[default: <缺省的动作>; [break;]]
}
条件表达式:整型/字符型表达式(或枚举表达式)
常量表达式:整型/字符型常量表达式
while语句
while (<条件表达式>) <循环体>;
while 循环结构 是单入/单出结构
标记控制的循环
使用标记(flag)指定‚数据输入的结束
即当用户输入标记值时,循环结束
其他名称:信号值(signal value),哨兵(sentinel)
标记值不应与正常的用户输入混淆
但同时标记值也是合法的输入
不确定的循环,即循环次数未知。
do-while 语句
do <循环体>;
while (<条件表达式>);
for语句
for (<表达式1>; <表达式2>; <表达式3>)
<循环体>;
说明: 三个表达式都是可选的(都可以为空),但分号不能少,表达式1和表达式3可以是任何合法的表达式 (常用逗号表达式)
例如:for (s=0,i=1;i<=100;s+=i,i++);
如果表达式2为空,那么就假定该循环条件为真
则创建一个无限循环
< Ctrl + C > 强行终止无限循环,结束程序的执行
break语句
break;
当在while、do-while、for或switch结构中执行break语句时,break语句会造成程序从该结构中退出,程序接着执行该结构之后的第一条语句。
注意:执行break语句后,for语句的表达式3不被执行
常规应用:提前从循环结构中退出
跳过switch结构的剩余部分
continue 语句
当在while、do-while或for结构中执行continue语句时,continue语句能够跳过该结构中剩余语句,执行下一个 循环过程。
注意:在while和do-while结构中 continue语句被执行之后,立即进行循环条件的测试 ,在for结构中 表达式3被执行之后,然后进行循环条件的测试
六、函数
C语言的函数有两大类
标准库函数
提供了丰富的函数。 例如 数学计算:sqrt(),abs() 输入/输出:scanf(),printf()
自定义函数
程序员可以编写函数来完成特定的任务。
应该熟悉C系统中的标准函数库。
应该避免从零开始构建一切。
定义函数的格式
<函数类型> <函数名>(<参数表>)
{ <函数体语句> } //包括声明语句和可执行语句,函数的定义不允许嵌套。
函数名:一个有效的标识符。
函数类型:返回值的类型说明符。
如果不指定,即缺省,就是 int。 void :表示函数不返回任何值。
参数表:声明参数,多个参数用逗号分隔。
接收传递进来的数据。 必须为每个参数指定数据类型。 但 int 可以省略。
控制返回:结束执行,把程序的控制交还主调函数, 也可以用return返回一个数值
如果传递给函数的参数不正确,编译程序不会检查到这些错误
函数原型强迫参数采用正确的数据类型
printf(“%.3f”, sqrt(4) );//double sqrt(double);
函数原型使编译程序把整数值4转换为double型的值4.0
没有与函数原型中的参数类型完全对应的参数值会在调用函数之前被转换成合适的数据类型。
遵守C语言的提升规则。
头文件
每个标准库函数都有对应的头文件。
包含了标准库中所有函数的函数原型,以及那些函数所需的数据类型和常量的定义。 使用#include命令把头文件包含到程序文件中: #include <文件名> 例如,#include <math.h>
程序员可以创建自己的头文件
程序员可以创建自己的头文件
使用.h扩展名。
使用下面的命令格式包含头文件:
#include “文件名”
例如,#include “abc.h”
函数间的数据传递方式:
参数 返回值
实参和形参
int max(int a, int b)
{ int c=a>=b?a:b;
return c;
}
main()
{ int a, b, c;
scanf(“%d%d”, &a, &b);
c=max(a, b);
}
形式参数
简称“形参”。在函数定义时 表示可以接受传递过来的值。//a,b
实际参数
简称“实参”。在函数调用时给出。//c
参数赋值
在函数体的入口处和出口处从严把关, 从而提高函数的质量。
在函数的入口处,使用‚断言(assert)检查 参数的有效性(合法性)。
参数传递的顺序
按从右往左的顺 序求值
参数传递的影响
实参与形参不共用存储单元。
参数传递时,把实参的值复制一份 给形参。
形参值的变化不影响实参的值。
形参和实参可以同名。
函数间参数的传递有两种类型
值传递
主调函数把实参的值的副本传递给被调函数的形参。
在被调函数内改变形参的值不会改变主调函数中实参的值。
如果函数不需要修改参数的值,就采用这种调用方式。
引用传递 (在C++中,函数参数的传递方式有引用传递。所谓引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。)
主调把实参“自参”传递给被调函数的形参。
在被调函数内改变形参的值将改变主调函数中实参的值。
用于可信的函数。
形式参数前加&符号,这个形参相当于实参的一个别名,对这个形参的操作 等同于对实参的操作,有点类似快捷方式。
a等同于x,比如fun(int &a)函数内对a的操作和值传递的函数fun(int a)中对 形参的操作一样,但是修改形参同时也是修改实参。
在C语言中,所有参数传递都采用值传递。