c语言基础知识有哪些
C语言是世界上最流行、使用最广泛的高级程序设计语言之一。在操作系统和系统使用程序以及需要对硬件进行操作的场合,用C语言明显优于其它高级语言,许多大型应用软件都是用C语言编写的。下面一起来看看小编为大家整理的c语言基础知识有哪些,欢迎阅读,仅供参考。
C语言基础知识
C语言程序的结构认识
用一个简单的c程序例子,介绍c语言的基本构成、格式、以及良好的书写风格,使小伙伴对c语言有个初步认识。
例1:计算两个整数之和的c程序:
#include main() { int a,b,sum; /*定义变量a,b,sum为整型变量*/ a=20; /*把整数20赋值给整型变量a*/ b=15; /*把整数15赋值给整型变量b*/ sum=a+b; /*把两个数之和赋值给整型变量sum*/ printf(“a=%d,b=%d,sum=%d\n”,a,b,sum); /*把计算结果输出到显示屏上*/ }
重点说明:
1、任何一个c语言程序都必须包括以下格式:
main() { }
这是c语言的基本结构,任何一个程序都必须包含这个结构。括号内可以不写任何内容,那么该程序将不执行任何结果。
2、main()----在c语言中称之为“主函数”,一个c程序有且仅有一个main函数,任何一个c程序总是从main函数开始执行,main函数后面的一对圆括号不能省略。
3、被大括号{ }括起来的内容称为main函数的函数体,这部分内容就是计算机要执行的内容。
4、在{ }里面每一句话后面都有一个分号(;),在c语言中,我们把以一个分号结尾的一句话叫做一个c语言的语句,分号是语句结束的标志。
5、printf(“a=%d,b=%d,sum=%d\n”,a,b,sum); ----通过执行这条c语言系统提供给我们直接使用的屏幕输出函数,用户即可看到运行结果,本程序运行后,将在显示器上显示如下结果:
a=20,b=15,sum=35
6、#include
注意:(1)以#号开头 (2)不以分号结尾 这一行没有分号,所以不是语句,在c语言中称之为命令行,或者叫做“预编译处理命令”。
7、程序中以 /*开头并且以*/结尾的部分表示程序的注释部分,注释可以添加在程序的任何位置,为了提高程序的可读性而添加,但计算机在执行主函数内容时完全忽略注释部分,换而言之就是计算机当做注释部分不存在于主函数中。
C程序的生成过程
C程序是先由源文件经编译生成目标文件,然后经过连接生成可执行文件。
源程序的扩展名为 .c ,目标程序的扩展名为 .obj , 可执行程序的扩展名为 .exe 。
标识符
在编写程序时,必须为函数、变量等命名,这个名字称为标识符。C语言中标识符的命名规则如下:
标识符只能由字母、数字、下划线组成;
标识符的第一个字母必须是字母和下划线;
标识符区分大小写字母,如If和if是两个完全不同的标识符。
合法标识符如下: A6, b_3 , _mn 非法的标识符如下: ab#12 , 8m , tr3:4 , yes no
标识符不能与程序中具有特殊意义的关键字相同,不能与用户编制的函数名、C语言库函数相同,在程序中各种标识符尽量不要重复,以便区分。选择变量名和其他标识符时,应注意做到 “见名知义”。
标识符分为如下三类:
1、关键字
关键字是具有特定含义的,专门用来说明c语言特定成分的一类标识符,不能用作用户的标识符。
auto break case char union do double else enum extern goto if int long short signed static sizof struct switch unsigned void for while typedef continue float return typedef default
2、预定义标识符
预定义标识符在c语言中也有特定的含义,但可以用作用户标识符,预定义标识符分为两类:
(1)、库函数名字,比如(printf,scanf,sin,isdigit等) (2)、编译处理命令名,比如(define,include)
3、用户标识符
用户根据需要自己定义的标识符称为用户标识符。无论如何自定义标识符,都必须符合标识符的三条命名规则。
常量
在程序运行中,其值不能被改变的量称为常量。常量有5种类型:整型常量、实型常量、字符常量、字符串常量和符号常量。
(一)数值转换
数字的四种表现形式:
①:二进制:所有数字由0,1构成,逢二进一,二进制数中不会出现2.。 例: ②:八进制:以数字0(注意不是以字母O,o)开头,所有数字由0~7构成,逢八进一,八进制数中不会出现8。 例:0112,0123,077等 ③:十进制:所有数字由0~9构成,逢十进一,十进制数中不会出现10。 例:0,12,-15等 ④:十六进制:以0x或者0X(数字0加字母x)开头,所有数字由0~9,A~F(或者a~f)构成,逢十六进一(其中A、B、C、D、E、F分别代表10、11、12、13、14、15) 例:0x4A、0X14c7等
在计算机内部,数字均以二进制形式表示和存放,用户输入的普通十进制数字都要被计算机转换成二进制才能在计算机内部存储,同样计算机的运算结果也为二进制,一般要将其转换成十进制数再输出给用户阅读,这种转换通常由计算机自动实现。
(1)将十进制转换二进制、八进制和十六进制
除法:将十进制数除以2,记录余数,得到的商继续除以2,直到商为0,然后将各次相处所得的余数从后往前逆序排列,所得余数数字序列就是该十进制数对应的二进制数。八进制和十六进制转换方法同上。
例:十进制数13转换成二进制数的值为1101,转换八进制为015,转换成十六进制为D.
(2)将二进制、八进制和十六进制转换成十进制
乘积求和:将二进制的每一位从低位到高位(右边为低位,左边为高位)分别乘以20,21,22。。。。,然后将这些积求和。
例如:=(13)10 (317)8= (23E)16=
(3)二进制与八进制、十六进制数之间的相互转换
①:二进制转八进制:从右往左每三位一组转换成十进制数,将所得数据组合就是对应的八进制数(注意:高位不足三位补零)。 例:(010 110 111)2=(267)8 ②:二进制转十六进制:从右往左每四位一组转换成十进制数,将所得数据组合就是对应的十六进制数(注意:高位不足四位补零)。 例:(0101 1011)2=(5B)16 ③:八进制转化二进制:每一位数字转换为三位二进制数字 例:(13)8=(001 011)2= (注意:去掉前面的两个00,因为0在高位没有意义) ④:十六进制转化二进制:每一位数字转换为四位二进制数字 例:(E3)16=(1110 0011)2
(二)整型常量
整型常量有3种形式:十进制整型常量、八进制整型常量和十六进制整型常量。
(注意:c语言中没有直接表示二进制的整型常量,在c语言源程序中不会出现二进制。)
书写方式如下:
十进制整型常量:123 , 0 ,-24 , 85L(长整型常量) 等 八进制整型常量:051 ,-026 ,0773 等 十六进制整型常量:0x55 , 0x1101 , 0x , 0x5AC0 , -0xFF。 其中L为长整型。
(三)实型常量
实型常量有两种表示形式:小数形式和指数形式。
小数形式:5.4 0.074 -23.0 指数形式:5.4e0 4.3e-3 -3.3e4
(1)小数部分为0的实型常量,可以写为453.0 或453。 (2)用小数表示时,小数点的两边必须有数,不能写成“ .453“和“453.“,而应该写成“0.453“和“453.0“。 (3)用指数写法时,e前必须有数字,e后面的指数必须为整数(注意:整数阶码可以是正数,负数,也可以是八进制数、十六进制数,但必须为整数)。
(四)字符常量
字符常量的标志是一对单引号‘ ’,c语言中的字符常量有两类:
(1)由一对单引号括起来的一个字符,如‘a ’, ‘r’ ,‘#’。注意: ′a′ 和 ′A′ 是两个不同的字符常量。
(2)由一对单引号括起来,以反斜杠\开头,后跟若干数字或者字母,比如‘\n’,其中“\“是转义的意思,后面跟不同的字符表示不同的意思,这类字符常量叫转义字符。具体如图所示 。
转义字符 转义字符的意义 ASCII码
\n 回车换行 10 \t 横向跳到下一制表位置 9 \b 退格 8 \r 回车 13 \f 走纸换页 12 \\ 反斜线符"\" 92 \' 单引号符 39 \” 双引号符 34 \a 鸣铃 7 \ddd 1~3位八进制数所代表的字符 \xhh 1~2位十六进制数所代表的字符
(五)字符串常量
C语言中,以双引号括起来的,由若干个字符组成的序列即为字符串常量。
例:“ni hao” “happy”等等。
(六)符号常量
符号常量是由宏定义“#define“定义的常量,在C程序中可用标识符代表一个常量。
例:计算圆的面积的c程序。
#include #define PI 3. main() { float r,s; r=12.5; S=PI *r*r; printf(“s= %f ”,s); }
说明:
#define 是宏定义,此程序中所有出现PI的地方都代表3.,同时PI称为符号常量。习惯上我们用大写字母来表示符号常量,小写字母表示变量,这样比较容易区别。
变量
变量就是其值可以改变的量。变量要有变量名,在内存中占据一定的存储单元,存储单元里存放的是该变量的值。不同类型的变量其存储单元的大小不同,变量在使用前必须定义。
(一)整型变量
整型变量分为4种:基本型(int)、短整型(short int 或short)、长整型(long int 或 long)和无符号型(unsigned int ,unsigned short,unsigned long)。
不同的编译系统对上述四种整型数据所占用的位数和数值范围有不同的规定。
类型说明符
字节 数值范围 字符型
基本整型 char 1 C字符集
int 2 -32768 ~ 32767
短整型 short int 2 -32768 ~ 32767
长整型 long int 4 -214783648 ~ 214783647
无符号型 unsigned 2 0~65535
无符号长整型 unsigned long 4 0~4294967295
单精度实型 float 4 3/4E-38 ~3/4E+38
双精度实型 double 8 1/7E-308~1/7E+308
单词signed来说明“有符号”(即有正负数之分),不写signed也隐含说明为有符号,unsigned用来说明“无符号”(只表示正数)。
(二)实型变量
C语言中,实型变量分为单精度类型( float )和双精度类型( double )两种。如:
float a , b ; double m ;
在vc中,float 型数据在内存中占4个字节(32位),double型数据占8个字节。单精度实数提供7位有效数字,双精度实数提供15~16位有效数字。实型常量不分float型和double型,一个实型常量可以赋给一个float 型或double型变量,但变量根据其类型截取实型常量中相应的有效数字。
注意:实型变量只能存放实型值,不能用整型变量存放实型值,也不能用实型变量存放整型值。
(三)字符变量
字符变量用来存放字符常量,定义形式:
char 变量名;
其中关键字char定义字符型数据类型,占用一个字节的存储单元。
例:char cr1,cr2; cr1= ‘A’ , cr2=‘B’ ;
将一个字符赋给一个字符变量时,并不是将该字符本身存储到内存中,而是将该字符对应的ASCII码存储到内存单元中。例如,字符 ′A′ 的ASCII码为65,在内存中的存放形式如下:0
由于在内存中字符以ASCII码存放,它的存储形式和整数的存储形式类似,所以C语言中字符型数据与整型数据之间可以通用,一个字符能用字符的形式输出,也能用整数的形式输出,字符数据也能进行算术运算,此时相当于对它们的ASCII码进行运算。
类型的自动转换和强制转换
当同一表达式中各数据的类型不同时,编译程序会自动把它们转变成同一类型后再进行计算。转换优先级为:
char < int < float < double
即左边级别“低“的类型向右边转换。具体地说,若在表达式中优先级最高的数据是double型,则此表达式中的其他数据均被转换成double型,且计算结果也是double型;若在表达式中优先级最高的数据是float型,则此表达式中的其他数据均被转换成float型,且计算结果也是float型。
在做赋值运算时,若赋值号左右两边的类型不同,则赋值号右边的类型向左边的类型转换;当右边的类型高于左边的类型时,则在转换时对右边的数据进行截取。
除自动转换外,还有强制转换,表示形式是:
( 类型 )(表达式); 例:(int)(a+b)
讨论:当a值赋值为3.4,b值赋值为2.7,(int)(a+b)和(int)a+b的值分别为多少?
C运算符认识
C语言的运算符范围很广,可分为以下几类:
、算术运算符:用于各类数值运算。包括加(+)、减(-)、乘(*)、除(/)、求余(%)、自增(++)、自减(--)共七种。
、赋值运算符:用于赋值运算,分为简单赋值(=)、复合算术赋值(+=,-=,*=,/=,%=)和复合位运算赋值(&=,|=,^=,>>=,<<=)三类共十一种。 <="" span="">
、逗号运算符:用于把若干表达式组合成一个表达式(,)。
、关系运算符:用于比较运算。包括大于(>)、小于(<)、等于(==)、 大于等于(="">=)、小于等于(<=)和不等于(!=)六种。 <="" span="">
、逻辑运算符:用于逻辑运算。包括与(&&)、或(||)、非(!)三种。
、条件运算符:这是一个三目运算符,用于条件求值(?:)。
、位操作运算符:参与运算的量,按二进制位进行运算。包括位与(&)、位或(|)、位非(~)、位异或(^)、左移(<<)、右移(>>)六种。
8、指针运算符:用于取内容(*)和取地址(&)二种运算。
9、求字节数运算符:用于计算数据类型所占的字节数(sizeof)。
10、特殊运算符:有括号(),下标[],成员(→,.)等几种。
另外,按参与运算的对象个数,C语言运算符可分为:单目运算符 (如 !)、双目运算符 (如+,- )和三目运算符 (如 ? : )。
算术运算符和算术表达式
一、 基本的算术运算符
(1)+(加法运算符或正值运算符,如2+5)。
(2)-(减法运算符或负值运算符,如4-2)。
(3)*(乘法运算符,如3*8)。
(4)/(除法运算符,如11/5)。
/的运算分为两种情况:
a、“除”的左右两边都为整数时,所得结果必然是整数(注意:仅取整数部分,不是四舍五入)
比如:5/2的值为2,不是2.5,1/2的值为0。
b、“除”的左右两边至少有一个是实型数据(即小数)时,所得结果为实型数据。
比如:5/2.0的值为2.5,7.0/2.0的值为3.5.
(5)%(模运算符或称求余运算符,%两侧均应为整型数据,如9%7的值为2)。
需要说明的是:当运算对象为负数时,所得结果随编译器不同而不同,在vc中,结果的符号与被除数相同,比如:13%-2值为1,而-15%2值为-1。
二、 算术表达式和运算符的优先级与结合性
算术表达式是用算术运算符和括号将运算量(也称操作数)连接起来的、符合C语言语法规则的表达式。运算对象包括函数、常量和变量等。
在计算机语言中,算术表达式的求值规律与数学中的四则运算的规律类似,其运算规则和要求如下。
(1)在算术表达式中,可使用多层圆括号,但括号必须配对。运算时从内层圆括号开始,由内向外依次计算各表达式的值。
(2)在算术表达式中,对于不同优先级的运算符,可按运算符的优先级由高到低进行运算,若表达式中运算符的优先级相同,则按运算符的结合方向进行运算。
(3)如果一个运算符两侧的操作数类型不同,则先利用自动转换或强制类型转换,使两者具有相同类型,然后进行运算。
三、 自增自减运算符
作用:使变量的值增1或减1。
如:++i,--i (在使用i之前,先使i的值加1、减1)。 i++,i-- (在使用i之后,使i的值加1、减1)。
(1)只有变量才能用自增运算符 (++)和自减运算符(--),而常量或表达式不能用,如10++或(x+y)++都是不合法的。
(2)++和--的结合方向是“自右向左“,如 -i++ ,i的左边是负号运算符,右边是自增运算符,负号运算和自增运算都是 “自右向左“结合的,相当于 -(i++)。
在循环语句中常用到自增(减)运算符,在指针中也常用到该运算符,考生要弄清楚“i++”和“++i”及“i--”和“--i”的区别,特别弄清楚表达式的值和变量的值。
赋值运算符与赋值表达式
一、赋值运算符与赋值表达式
赋值符号 “=“就是赋值运算符,作用是将一个数据赋给一个变量或将一个变量的值赋给另一个变量,由赋值运算符组成的表达式称为赋值表达式。一般形式为:
变量名 = 表达式
在程序中可以多次给一个变量赋值,每赋一次值,与它相应的存储单元中的数据就被更新一次,内存中当前的数据就是最后一次所赋值的那个数据。
例:a=12; 此表达式读作“将10的值赋值给变量a”。
a、如果赋值号两边的运算对象类型不一致,系统会自动进行类型转换,转换的规则:将赋值号右边表达式的值的类型转换成赋值号左边变量的类型,
例:int y=3.5; 在变量y中最终存储的是整数3。
b、 可以将复制表达式的值再赋值给变量,形成连续赋值。
例如:x=y=25 是一个连续赋值表达式,x=y=25 等价于x=(y=25),所以表达式x=y=25 最终的值为25 。
二、复合的赋值运算符
在赋值运算符之前加上其他运算符可以构成复合赋值运算符。其中与算术运算有关的复合运算符是:+=,-=,*=,/=,%= 。
两个符号之间不可以有空格,复合赋值运算符的优先级与赋值运算符的相同。表达式n+=1等价于n=n+1,作用是取变量n中的值增1再赋给变量n,其他复合的赋值运算符的运算规则依次类推。
如求表达a+=a-=a*a 的值,其中a的初值为12 。
步骤:
(1)先进行“a-=a*a“运算,相当于a=a-a*a=12-144=-132 。 (2)再进行“a+=-132“运算,相当于 a=a+(-132)==-264 。
逗号运算符和逗号表达式
在c语言中,逗号除了作为分隔符,还可以用作一种运算符----逗号运算符,用逗号运算符将几个表达式连接起来,例如a=b+c,a=b*c等称为逗号表达式。
一般形式为:
表达式1 ,表达式2 ,表达式3 , …,表达式n
例:x=2,y=3,z=4
逗号表达式具有从左至右的结合性,即先求解表达式1,然后依次求解表达式2,直到表达式n的值。表达式n的值就是整个逗号表达式的值。上述的逗号表达式的值就是表达式z=4的值4.需要注意的是,逗号运算符是所有运算符中级别最低的。
例:有如下程序段:
main() { int a=2,b=4,c=6,x,y; y=(x=a+b),(b+c); printf("y=%d,x=%d",y,x); }
程序显示结果为:y=6,x=6
讨论:将y=(x=a+b),(b+c);改为y=((x=a+b),b+c) 的程序结果?
关系运算符和关系表达式
一、 C语言中的逻辑值
C语言中的逻辑值只有两个:真(true)和假(flase)。用非零代表真,用零代表假。因此,对于任意一个表达式,如果它的值为零,就代表一个假值,如果它的值为非零,就代表一个真值。只要值不是零,不管是正数,负数,整数,实数,都代表一个真值。例如-5的逻辑值为真。
二、 逻辑表达式
“&&”和“||”的运算对象有两个,故它们都是双目运算符,而!的运算对象只有一个,因此它是单目运算符。逻辑运算举例如下:
(1)a&&b: 当&&两边都为“真”时,表达式a&&b的值才是真。
值得注意的是:在数学中,关系式0
(2)a||b: 当||两边有一个为“真”时,表达式a||b的值就是真。
(3)!a: 表示取反,如果a为真,则!A为假,反之亦然。例如!-5的值就为0.
在C语言中,由&&或||组成的逻辑表达式,在某些特定情况下会产生“短路“现象。
(1)x && y && z ,只有当x为真(非0)时,才需要判别y的值;只有x和y都为真时,才需要去判别z的值;只要x为假就不必判别y和z,整个表达式的值为0。口诀:“一假必假”。
例:(!5==1)&&(++i==0) (!5==1)表达式的值为0,所以计算机运行中就跳过(++i==0)此表达式,(!5==1)&&(++i==0)表达式的值为0.
(2)x||y||z ,只要x的值为真(非零),就不必判别y和z的值 ,整个表达式的值为1,只有x的值为假,才需要判别y的值,只有x和y的值同时为假才需要判别z的值,口诀:“一真必真”。
位运算
一、 位运算符
在计算机中,数据都是以二进制数形式存放的,位运算就是指对存储单元中二进制位的运算。C语言提供6种位运算符。
二、位运算
位运算符 & |~<< >> ∧ 按优先级从高到低排列的顺序是:
位运算符中求反运算“~“优先级最高,而左移和右移相同,居于第二,接下来的顺序是按位与 “&“、按位异或 “∧“和按位或 “|“。顺序为~ << >> & ∧ | 。
例1:左移运算符“<<”是双目运算符。其功能把“<< ”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0。="" <="" span="">
例如: a<<4 指把a的各二进位向左移动4位。如a=00000011(十进制3),左移4位后为00(十进制48)。
例2:右移运算符“>>”是双目运算符。其功能是把“>> ”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。
例如: 设 a=15, a>>2 表示把右移为十进制3)。
应该说明的是,对于有符号数,在右移时,符号位将随同移动。当为正数时,最高位补0,而为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定。
例3:设二进制数a是00 ,若通过异或运算a∧b 使a的高4位取反,低4位不变,则二进制数b是。
解析:异或运算常用来使特定位翻转,只要使需翻转的位与1进行异或操作就可以了,因为原数中值为1的位与1进行异或运算得0 ,原数中值为0的位与1进行异或运算结果得1。而与0进行异或的位将保持原值。异或运算还可用来交换两个值,不用临时变量。
如 int a=3 , b=4;,想将a与b的值互换,可用如下语句实现: a=a∧b;
b=b∧a;
a=a∧b;
所以本题的答案为: 。
C语言作为一门非常适合编程入门的语言,打好基础的重要性不言而喻。
C语言基础知识总结
主要内容:1.C数据类型
2.简单的算术运算和表达式
3.键盘输入和屏幕输出
4.选择控制结构
总结风格:分条罗列,主要是知识点,有例题不多
5.循环控制结构
一、C数据类型
1.C语言处理两种数据:常量和变量
2.常量:整形常量、实型常量、字符常量、字符串常量、枚举常量
3.整形常量:正整数、负整数、零 eg: 10,-30,0
4.实型常量:实数、小数、浮点数 eg: 3.14,-0.56,18.0
5.字符常量:字符型常量、用单引号括起来的任意字符 eg: 'x' 'X' '?' ',' '9'
6.字符串常量:用双引号括起来的一个或多个字符 eg: "x" "Hello" "Y78"
7.在C程序中,整型常量可以用十进制、八进制、十六进制形式表示,但编译器都会自动将
其转换成二进制存储
8.整型常量的类型:长整型、短整型、有符号、无符号。
9.不同进制的整型常量的表示形式:
1)十进制:0~9数字组合,可带正负号 eg: 256,-128,0,+7
2)八进制:0开头,后面跟0~7数字组合 eg: 021,-017
3)十六进制:0x(0X)开头,后跟0~9,a~f(A~F)数字组合 eg:0x12,-0x1F
10.不同类型的整形常量的表示形式:
1) 有符号整型常量:默认int型定义为有符号整数,无需signed eg:10,-30,0
2) 无符号整形常量:常量值后跟u或U,只能表示>=0的数 eg:30u,256U
3) 长整型常量:常量值后跟l或L eg:-256l,1024L
4) 无符号长整型常量:常量值后跟LU、Lu 、lU 、lu eg:30lu
11.C程序中,实型常量两种表示形式:小数、指数
12.不同形式的实型常量的表示形式:
1) 十进制表示形式:数字和小数点组成,必须要有小数点,整数部分可省略 eg:0.123, -12.35, .98
2) 指数形式:e或E代表以10为底的指数, e左边是数值部分(有效数字,可以是整
数、小数,不能省略),e右边是指数部分(必须是整数形式) eg:3.45e-6
13.实型常量有单精度和双精度之分,无有符号和无符号之分
14.不同类型的实型常量表示形式:
1)单精度实型常量:常量值后跟F或f eg:1.25F,1.25e-2f
2)双精度实型常量(double):实型常量默认按双精度处理 eg:0.123,-12.35, .98
3)长双精度实型常量(long double):常量值后跟L或l eg:1.25L
15.变量:在程序执行过程中可以改变的量
16.变量在必须先定义后使用,定义时需要声明变量的类型和变量名,一般形式:类型关键
字 变量名;
17.关键字是C语言预先规定具有特殊意义的单词,类型关键字用于声明变量的类型
18.标准C语言编写的程序都是以main()作为开头,指定了C程序执行的起点,在C程序中
只能出现一次,称为主函数
19.C程序总是从main函数开始执行,与他在程序中的位置无关,main函数主体部分称为语
句,用{}括起来,一般C语句以;结束
20.变量的类型决定了编译器为其分配内存单元的字节数、数据在内存单元中的存放形式、
该类型变量合法的取值范围以及该类型变量可参与的运算种类
21.变量名是用户定义的标识符,用于标识内存中具体的存储单元,存放的数据称为变量的
值
22.新数据存放于存储单元时,旧数据将会被修改,反应变量的值是可以改变的
23.变量名的命名规则:
1)标识符只能由英文字母、数字、下划线组成
2)标识符必须以字母或下划线开头
3)不允许使用C关键字为标识符命名
4)标识符可以包含任意多个字符,但一般会有最大长度限制,预编译器有关,一般不会超过,最好不超过8个字符
注意:标识符区分大小写
eg:x y3 _imax ELSE X A_to_B (合法)
eg:7x int #No bad one re-input(不合法)
24.标准C规定所有变量必须在第一条可执行语句之前定义
25.在同一条语句中可以同时定义多个相同类型变量,多个变量之间用逗号分隔,没有顺序要求
26.在使用标准输入/输出函数时,必须在程序开头加上编译预处理命令
27.中stdio为头文件,std是standard,i为input,o为output,h为head
28.编译预处理命令#include的作用:将在输入/输出函数的头文件stdio.h包含到用户源文件中
29.%d按十进制整数个格式输出,%f按十进制小数格式输出,一般输出6位小数,%c输出一个字符,\n换行,双引号内字符原样输出
30.不同类型的数据在内存中占用不同大小的存储单元,他们所能表示的数据的取值范围各不相同,不同类型的数据表示形式及其可以参与的运算种类也不同
31.定义整型变量时,只要不指定为无符号型,其隐含类型为有符号型,signed通常省略不写
32.C程序中每个变量的值都是按字节编址,都被存储在内存中特定的存储单元中,这个存储空间实际是一个线性地址表,即每个字节的存储空间对应一个唯一的地址
33.1个字节等于8个二进制位,即8个位为一个字节,一个字节可以表示的整数最小为0,最大255,即8个位可以表示0-255之间的数,一个二进制位的值只能是0或1
34.同种类型在不同的平台所占字节数不同,要计算数据类型所占内存空间的字节数需要用sizeof()运算符
35.sizeof是C语言关键字,不是函数名,sizeof(变量名)计算一个变量所占内存的字节数
36.计算不同类型运算符的表达式时,要考虑运算符的优先级和结合性
37.正数的反码、补码与原码都相同,负数的补码等于反码加1
38.在计算机内存中负数都是用补码来表示
39.对于实数,无论小数海曙指数形式,在计算机内存中都采用浮点形式来存储
40.浮点数分为阶码、尾数两部分,实数N=S*pow(r,j),S为尾数(无论正负,规定用存小数),j为阶码(无论正负,必须是整数),r是基数 eg:10.0111=0.100111*pow(2,10)
41.阶码所占位数决定实数的取值范围,尾数所占位数决定实数的精度,尾数的符号决定实数的正负,阶码和尾数的字节大小与编译器有关
42.float型变量能接收实型常量的7位有效数字,double型变量能接收16位
43.运算符的优先级:单目运算<算术运算<关系运算<逻辑运算<条件运算<赋值运算<逗号运算
44.素数:又称质数,指在大于1的自然数中,除1和本身不能被其他自然数整除的数
45.合数:指在自然数中除1和本身外还能被其他自然数整除的数
46.因子:所有能整除这个数的数,不包括自身,但包括1
47.闰年:能被4整除但不能被100整除,或能被400整除
二、 简单的算术运算和表达式
1.条件运算符是C语言提供的唯一一个三元运算符,C语言中没有幂运算符
2.只有计算相反数是一元运算符,其余运算符都是二元运算符
3.一元运算符也叫单目运算符,二元运算符也叫双目运算符,三元运算符也叫三目运算符
4.整数除法的结果是整数,浮点数除法的结果是浮点数
5.求余运算限定参与运算的两个操作数必须为整型,余数的符号与被除数的符号相同,不能对两个实型数进行求余运算
6.所有的算术运算符中只有一元的去相反数运算符为右结合,其余的结合性都为左结合
7.同一优先级的运算符进行混合运算时,从左向右依次进行
8.运算符的优先级:单目运算>算术运算>关系运算>逻辑运算>条件运算>赋值运算>逗号运算
9.计算并输出一个三位整数的个位、十位、百位数字之和
#include
void main()
{
int x=321;
int a,b,c,sum;
a=x%10;//a=1
b=(x/10)%10;//b=2
c=x/100;//c=3
sum=a+b+c;
printf("a=%d,b=%d,c=%d\nsum=%d\n",a,b,c,sum);
}
10.涉及算术运算的复合赋值运算符有5个:+=,-=,*=,/=,%=
11.增1运算符也称自增运算符,减1运算符也称自减运算符,都是一元运算符,只有一个操作数必须是变量不能是常量或表达式
12.自增自减运算符作为前缀时,先执行加1或减1然后使用;自增自减运算符作为后缀时,先使用再执行加1或减1;
13.考虑优先级与结合性的实例
m=-n++《=》m=-(n++)《=》m=-n,n=n+1;
//正面:-和++都是一元运算符,优先级相同,此时要考虑结合性,结合性都是右结合的,所以先算++后算-
//反面:如果等价m=(-n)++就不合法了,因为表达式不能进行自增操作
14.scanf函数和printf函数都是C的标准输入/输出函数,&为取地址运算符
15.宏常量与宏替换:
1) 在程序中直接使用的常数称为幻数,将幻数定义为宏常量或const常量是为了提高程序的可读性和可维护性
2) 宏常量也称符号常量,没有数据类型,编译器不对其进行类型检查,只进行字符串替换
3) 宏定义一般形式:#define 标识符 字符串。标识符被称为宏名,宏名与字符串之间可有多个空白符,不加等号,结尾不加分号
4) 宏常量是由宏定义编译预处理命令来定义,宏名替换成字符串的过程称为宏替换,宏替换不做任何语法检查
5) 当宏定义是一个表达式时,调用时,是一个数就可以直接带入,而是表达式也要看成是一个数代进宏定义表达式中,
而看成一个数这就要求把调用的数加上圆括号,为了减少不必要的错误,最好都加上圆括号
6) 宏替换的过程是将宏名原样替换成字符串,而不是直接计算出值,所以要用调用后的结果参与其他运算就需要把调用的结果加上圆括号
7) 例题:
#include
#define N 2 //N=2
#define M N+1 //M=2+1
#define NUM 2*M+1 //NUM=2*2+1+1=6
void main()
{
int i;
for(i=1;i<=NUM;i++);
printf("%d\n",i); //执行完空循环,i=7
i--; // i=6
printf("%d\n",i);
}
8) 例题:
#include
#define f(x) x*x
void main()
{
int b;
b=f(4+4); //b=4+4*4+4=24,解释见5)
printf("b=%d\n",b);
}
9) 例题:
#include
#define f(x) x*x
void main()
{
int b;
b=f(4+4)/(2+2); //b=4+4*4+4/(2+2)=21解释见6)
printf("b=%d\n",b);
}
10) 例题:
#include
#define f(x) x*x
void main()
{
int b;
b=f((4+4)); //b=(4+4)*(4+4)=64
printf("b=%d\n",b);
}
11) 例题:
#include
#define f(x) (x*x)
void main()
{
int b;
b=f((4+4))/(2+2); //b=((4+4)*(4+4))/(2+2)=16
printf("b=%d\n",b);
}
16.const常量
1) const常量只能在定义时赋初值,因为编译器将其放在只读存储区,不允许在程序中修改
2) const常量的定义一般形式:const 类型名 标识符=字符串;//将标识符声明为具有该数据类型的const常量
3) const是一种类型修饰符,const常量具有数据类型,编译器要对其进行类型检查
17.表达式中的自动类型转换:
1) 表达式中,操作数类型相同,运算的结果类型与操作数类型相同
2) 表达式中,操作数类型不相同,C编译器自动将所有操作数进行类型提升,转换成同一类型,所占字节最大,再计算
18.赋值中的自动类型转换:
1) 赋值运算符左侧变量与右侧表达式类型不同时,发生自动类型转换:右侧表达式的值转换成左侧变量的类型
19.强制类型转换:
1) 强制类型转换运算符是一元运算符
2) 强制类型转换也称强转,是将表达式的值转换为任意类型,并不改变变量本身的数据类型
3) 强转一般形式:(类型)表达式
4) 演示强制类型转换运算符的使用
#include
void main()
{
int m=5;
printf("m/2=%d\n",m/2);//m=2
printf("(float)(m/2)=%f\n",(float)(m/2));//m=2.000000
printf("(float)m/2=%f\n",(float)m/2);//m=2.500000
printf("m=%d\n",m);//m=5,只是将m强转为实型数据,并不改变m的数据类型 }
20.常用的标准数学函数:
1) 使用C标准数学函数,要在程序开头加上编译预处理命令:#include
2) 例:已知三角形三边长为a,b,c,计算三角形的面积
#include
#include
void main()
{
float a,b,c,s,area;
printf("Input a,b,c:");
scanf("%f,%f,%f",&a,&b,&c);
s=(a+b+c)/2;
area=(float)sqrt(s*(s-a)*(s-b)*(s-c));
printf("area=%f\n",area);
}
21.赋值运算符的左侧不能出现表达式,变量与变量之间可以赋值
例1:若有定义:int a,b,c;下列表达式中哪一个是合法的C语言赋值表达式(C、D)
A)a=7+b=c=7 B)a=b++=c=7 C)a=(b=7,c=12) D)a=3,b=a+5,c=b+2
//A.7+b表达式不能做左值 B.b++表达式不能做左值 C.逗号表达式a=12 D.依次赋值
例2:下面不正确的赋值语句是(B)
A)a=++a B)a=b++=10 C)a+=b D)a=1>'a'
//D.算术运算符优先级高于赋值运算符,先算1>'a'再将其结果赋给a
例3:若有下列定义:int a=3,b=2,c=1;以下选项错误的赋值表达式是(A)
A)a=(b=4)=3 B)a=b=c+1 C)a=(b=4)+c D)a=1+(b=c=4)
//A.先计算圆括号里的值等于4,然后按照赋值表达式的顺序从右向左计算,将3赋值给4这是不对的,
即赋值号左侧只能是变量,不能出现表达式b=4
三、 键盘输入和屏幕输出
1.字符常量:
把字符放在一对单引号内,适用于多数可打印字符
2.转义字符:
以反斜线(\)开头,也是放在一对单引号内,适用于控制字符(如回车符,换行符)
3.常用的转义字符:
1) '\n' — 换行 8) '\a' — 响铃报警提示音
2) '\r' — 回车(不换行) 9) '\"' — 一个双引号
3) '\0' — 空字符 10) '\'' — 一个单引号
4) '\t' — 水平制表 11) '\\' — 一个反斜线
5) '\v' — 垂直制表 12) '\?' — 问号
6) '\b' — 退格 13) '\ddd' —1到3位八进制ASCII码值所代表的字符
7) '\f' — 走纸换页 14) '\xhh' —1到2位十六进制ASCII码值所代表的字符
4.\n,是将光标移到下一行起始位置,\r是将光标移到当前行的起始位置
5.\t,是水平制表符,相当于按下Tab键,每次按下Tab键并不是从当前光标位置向后移动一个Tab宽度,而是移到下一个制表位
实际移动的宽度视当前光标位置距相邻的下一个制表位的距离而定
6.制表位,屏幕上的一行被分为若干个域,相邻域之间的交接点称为制表位,每个域的宽度就是一个Tab宽度,多数习惯上为4
7.当转义序列出现在字符串中时,是按单个字符计数的
8.一个整形数在内存中是以二进制形式存储的,而一个字符在内存中也是以其对应的ASCII码的二进制形式存储的,
但char型数据在内存中只占一个字节,而int型数据在16位系统中占2个字节,32位系统占4个字节
9.在ASCII码取值范围内,char型数据可以和int型数据进行混合运算,char型数据也能以int型输出,直接输出其对应的ASCII码的十进制值
10.字符的输入/输出:
1) getchar()和putchar()是C标准函数库中专门用于字符输入/输出的函数,功能是只能输入/输出一个字符
2) 例:从键盘输入一个大写英文字母,将其转换为小写字母显示在屏幕上
#include
void main()
{
char ch;
ch=getchar();//键盘输入一个字符,再按回车表示输入结束,字符存入变量ch,注意:getchar()没有参数,直接返回读入的字符
ch=ch+32;
putchar(ch);//第二次按回车,将显示转换后的结果
putchar('\n');//注意:putchar()内一定要有参数,参数就是待输出的字符,可以是可打印字符,也可是转义字符
}
11.数据的格式化屏幕输出:
1) 函数printf()的一般格式:printf(格式控制字符串);或者printf(格式控制字符串,输出值
参数表);
2) 格式控制字符串包括:格式转换说明符,需要原样输出的普通字符
3) 函数printf()的格式转换说明符:
%d — 输出带符号十进制整数,整数符号省略
%u — 输出无符号十进制整数
%o — 输出无符号八进制整数,不输出前导符0
%x — 输出无符号十六进制整数(小写),不输出前导符0x
%X — 输出无符号十六进制整数(大写),不输出前导符0x
%c — 输出一个字符
%s — 输出字符串
%f — 以十进制小数形式输出实数,包含单,双精度,隐含6位小数,但并非全是有效数字,单精度有效7位,双精度16位
%e — 以指数形式输出实数(小写e表示指数部分),小数点前有且仅有一位非0数字
%E — 以指数形式输出实数(大写E表示指数部分)
%g — 自动选取f或e格式中宽度较小的一种使用,不输出无意义的0
%% — 输出%
4) 输出值参数表:需要输出的数据项的列表,可以是变量或表达式,逗号隔开,类型与格式转换说明符相匹配
5) 每个格式转换说明符与输出值参数表中的输出值参数一一对应,没有输出值参数,格式控制字符串就不需要格式转换说明符
6) 例:从键盘输入一个大写英文字母,将其转换为小写字母和其十进制ASCII码值显示在屏幕上
#include
void main()
{
char ch;
printf("Please enter a key:");
ch=getchar();
ch=ch+32;
printf("%c,%d\n",ch,ch);//printf("%c",ch)<<=>>putchar(ch),printf("\n")<<=>>putchar('\n') }
7) 函数printf()中的格式修饰符:在%和格式符中间插入格式修饰符,用于输出格式的微调,如:指定输出域宽、精度、左对齐等
英文字母l — 修饰格式符d,o,x,u时,用于输出long型数据
英文字母L — 修饰格式符f,e,g时,用于输出long double型数据
英文字母h — 修饰格式符d,o,x时,用于输出short型数据
输出域宽m — m为整数,输出时占m列,若m>0,当数据宽度小于m时,域内右靠齐,左补空格,当数据宽度大于m时,修饰符失效,按实际宽度输出,若m有前导符0,左边多余位补0;若m<0,输出数据在域内左靠齐
显示精度 .n — n为大于等于0的整数,精度修饰符位于最小域宽修饰符之后,由圆点和整数构成,对于浮点数,用于指定输出的浮点数小数位数;对于字符串,用于指定从字符串左侧开始截取的子串字符个数
8) 使用const常量定义pi,编程从键盘输入圆的周长和面积,使其输出数据保留两位小数
#include
void main()
{
const double pi=3.14159;
double r,circum,area;
printf("Please enter r:");
scanf("%lf",&r);
circum=2*pi*r;
area=pi*r*r;
printf("输出没有宽度和精度的值:");
printf("circum=%f,area=%f\n",circum,area);
printf("输出没有宽度和精度的值:");
printf("circum=%7.2f,area=%7.2f\n",circum,area);//域宽为7,占7个字符宽度,小数点也算一个字符,精度为2,小数点后保留2位
}
12.数据的格式化键盘输入:
1) 函数scanf()的一般格式:scanf(格式控制字符串,参数地址表);
2) 格式控制字符串:包括格式转换说明符,分隔符
3) 格式转换说明符以%开始,以格式字符结束,用于指定各参数的输入格式
4) 函数scanf()的格式转换说明符:
%d — 输入十进制整数
%o — 输入八进制整数
%x — 输入十六进制整数
%c — 输入一个字符,空白字符(包括空格、回车、制表符)也作为有效字符输入 %s — 输入字符串,遇到第一个空白字符(包括空格、回车、制表符)时结束 %f或%e — 输入实数,以小数或指数形式输入均可
%% — 输入一个%
5) 参数地址表:由若干变量的地址组成的列表,用逗号分隔
6) 函数scanf()中的格式修饰符:在%和格式符中间插入格式修饰符
英文字母l — 加在格式符d,o,x,u之前,用于输入long型数据;加在f,e之前,用于输入double型数据
英文字母L — 加在格式符f,e之前,用于输入long double型数据
英文字母h — 加在格式符d,o,x时,用于输入short型数据
输出域宽m — m为正整数,指定输入数据的宽度,系统自动按此宽度截取所需数据
显示精度 .n — n为0或正整数,scanf()没有精度格式修饰符,输入时不能规定精度 忽略输入修饰符* — 表示对应的输入项在读入后不赋给相应的变量
7) 函数scanf()输入数值型数据时,被认为输入结束的几种情况:遇空格符、回车符、制表符;达到输出域宽;遇非法字符输入
8) 如果函数scanf()的格式控制字符串中存在除格式转换说明符以外的其他字符,必须将这些字符原样输入
#include
void main()
{
int a,b;
scanf("%d %d",&a,&b); //以空格作为分隔符,等价于scanf("%d%d",&a,&b),等价于scanf("%d %d",&a,&b),
printf("a=%d,b=%d\n",a,b);//实际输入时,空格、回车符、制表符都可作为分隔符,即输入:12空格34 12回车34 12制表符34均可,
}
#include
void main()
{
int a,b;
scanf("%d,%d",&a,&b);//输入时必须以逗号作为分隔符,即只能输入:12,34
printf("a=%d,b=%d\n",a,b);
}
#include
void main()
{
int a,b;
scanf("a=%d,b=%d",&a,&b);//输入时必须将"a="和"b="原样输入,即只能输入:a=12,b=34 printf("a=%d,b=%d\n",a,b);
}
#include
void main()
{
int a,b;
scanf("%2d%2d",&a,&b);//输入时将前两位数读入存到a中,接着两位存到b中,然后结束读取,即输入:1234,或123456结果一样
printf("a=%d,b=%d\n",a,b);
}
#include
void main()
{
int a,b;
scanf("%d %d",&a,&b);
printf("a=\"%d\",b=\"%d\"\n",a,b);//输出a="12",b="34"
}
#include
void main()
{
int a,b;
scanf("%d%*c%d",&a,&b);//任意字符都可作为分隔符,即输入:12,34或12?34或12+34结果都一样
printf("a=%d,b=%d\n",a,b);
}
#include
void main()
{
int a,b;
scanf("%2d%*2d%d",&a,&b);//忽略两位,输入123456
printf("a=%d,b=%d\n",a,b);//输出a=12,b=56
}
对于程序
#include
void main()
{
int a,b;
scanf("%d %d",&a,&b);
printf("a=%d,b=%d\n",a,b);
}
如果输入12 34a回车,则结果a=12,b=3,程序在遇到非法字符a时,会导致程序输入终止,此时a会读入12,b会读入3
如果输入123a回车,则结果a=123,b=-858993460,程序在遇到非法字符a时,会导致程序输入终止,此时a会读入123,而b未能读入指定数据项数
如果在scanf()函数中忘记在变量前加取地址运算符&,会导致非法内存访问
13.%c格式符使用几种情况:
1) 用%c格式读入字符时,空格字符和转义字符(包括回车)都会被当做有效字符读入 例:键盘输入一个整数加法算式:操作数1+操作数2,输出:操作数1+操作数2=计算结果
#include
void main()
{
int data1,data2;
char op; //输入:12空格+空格3 回车//输出:12 -858993460=-858993448
printf("Enter data1+data2\n");//输入:12空格3 回车//输出:12 3=15
scanf("%d%c%d",&data1,&op,&data2);//输入:12+3 回车//输出:12+3=15 printf("%d%c%d=%d\n",data1,op,data2,data1+data2);
}
2) 先输入一个数据后再输入字符型变量时,输入一个数据后,输入的回车符将被当做有效字符读给字符型变量
例:编程从键盘先后输入int型、char型和float型数据,要求每输入一个数据就显示这个数据的类型和数据值
void main()
{
int a;
char b;
float c;
printf("Please input an integer:");
scanf("%d",&a);
printf("integer:%d\n",a);
//在输入一个整型数据后,输入的回车符被当做有效字符读给了字符型变量b了
printf("Please input a character:");
scanf("%c",&b);
printf("chracter:%c\n",b);
printf("Please input a float number:");
scanf("%f",&c);
printf("float:%f\n",c);
}
14.%c格式符存在问题的解决方法
1) 用函数getchar()将数据输入时存入缓冲区中的回车符读入,以避免被后面的字符型变量作为有效字符读入
#include
void main()
{
int a;
char b;
float c;
printf("Please input an integer:");
scanf("%d",&a);
printf("integer:%d\n",a);
getchar();//将存于缓冲区中的回车符读入,避免在后面作为有效字符读入
//函数getchar()的返回值是一个回车符,已经避免了错误,不需要再将其赋给字符型变量使用
printf("Please input a character:");
scanf("%c",&b);
printf("chracter:%c\n",b);
printf("Please input a float number:");
scanf("%f",&c);
printf("float:%f\n",c);
}
2) 在%c前面加一个空格,将前面数据输入时存于缓冲区的回车符读入,避免被后面的字符型变量作为有效字符读入
void main()
{
int a;
char b;
float c;
printf("Please input an integer:");
scanf("%d",&a);
printf("integer:%d\n",a);
printf("Please input a character:");
scanf(" %c",&b);//在%c前面加空格,将存于缓冲区中的回车符读入
printf("chracter:%c\n",b);
printf("Please input a float number:");
scanf("%f",&c);
printf("float:%f\n",c);
}
//解释:在%c前加空格为什么能将存于缓冲区中的回车符读入
因为如果函数scanf()的格式控制字符串中存在除格式转换说明符以外的其他字符,必须将这些
字符原样输入,所以在%c前加空格,就必须在输入字符型数据前先原样输入空格,而空格,回车符,制表符在
函数scanf()输入数值型数据时都代表输入结束,由实践可知,空格符、回车符、制表符在输入时等效
所以,缓冲区中的回车将代替需要原样输入的空格,因此,实际上,在%c前增加空格或者Tab键都可以完成,
并且与增加的`数量无关,且可以混合增加
3)*经典例题:编程实现键盘任意输入字符,统计字母、数字、空格、其他字符数量 首选字符串的方法:
#include
#define N 100
int main()
{
char a[N];
int i,m=0,n=0,b=0,c=0;
printf("请输入字符:\n");
gets(a);
for(i=0;a[i]!='\0';i++)
{
if((a[i]>='a'&&a[i]<='z')||(a[i]>='A'&&a[i]<='Z')) m++;
else if(a[i]>=0&&a[i]<=9) n++;
else if(a[i]==' ') b++;
else c++;
}
printf("字母个数:%d\n",m);
printf("数字个数:%d\n",n);
printf("空格个数:%d\n",b);
printf("其他字符个数:%d\n",c);
return 0;
}
单个字符输入的方法,但是要解决缓冲区的问题
#include
int main()
{
char ch;
int a,b,c,d;
a=b=c=d=0;
printf("请输入字符:\n");
do{
ch=getchar();
getchar();//清除缓冲区的回车键,不然会当做第二个字符读入
if(ch!=' ')//用Tab键控制输入结束,他在程序中只会出现一次并且统计一次, { //然后结束,所以要去掉它,可以使用if语句,也可在前面初始化为d=-1 if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) a++;
else if(ch>='0'&&ch<='9') b++;
else if(ch==' ') c++;
else d++;
}
}while(ch!=' ');
printf("字母个数:%d\n",a);
printf("数字个数:%d\n",b);
printf("空格个数:%d\n",c);
printf("其他字符个数:%d\n",d);
return 0;
}
//解释:你可以把Tab控制结束改成其他任意字符,包括字母、数字、/;都可以,
就是不能直接使用回车控制结束,因为你在实际键盘输入时,需要打回车才能把前面的 字符读入,当你输完回车后,就已经换行了,再回车就达不到你要的效果了,不可能把 他读入,但是他会留在缓冲区下一次使用,所以说,理论上任意字符都可以控制结束, 但是不能直接使用回车再回车的方法,而getchar()函数一次只能读一个字符,当你回车 读入字符后,回车符就会留在缓冲区下一次使用,你可以试试,你把getchar()这行语句 注释,然后一次输入两个字符再回车的话,那么这时他也只能读入第一个字符,第二个 字符和回车就会计入第二次、第三次的结果。
总结:这种方式与用字符串的区别在于,字符串可以统计任何字符,但是这种方式不能统计 你用来控制结束的字符,比如说,你用/控制结束,那么就不能统计/的数量了,而且你要把 他去掉,因为在整个程序中/只会出现一次,然后就结束了
**当程序中出现两次或以上的键盘输入时,就有可能出现缓冲区的问题,只有一次输入,回车直接结束没有这种问题
15.考点题型:字符串常量的长度问题:
1)字符串常量"ab\\c\td\376"的长度是(A)
A) 7 B) 12 C) 8 D) 14
// a b \\ c \t d \376
2)语句printf("%d",strlen("abs\no12\1\\"));的输出结果是(C)
A) 11 B) 10 C) 9 D) 8
// a b s \n o 1 2 \1 \\
16.考点题型:赋值运算、关系运算的混合运算问题:
1)设m,n,a,b,c,d的值均为0,执行(m=a==b)||(n=c==d),m,n的值是(C)
A) 0,0 B) 0,1 C) 1,0 D) 1,1
// "=="是算术运算符,"="是赋值运算符,优先级:算术运算符>赋值运算符,先判断a==b?是否正确
正确则为真,把1赋给m,"||"是或运算,前面已经为真,所以||后面的就不会再运算了,结果就为真
所以m=1,n=0不变
2)int a,b,m,n;初值依次为4,3,2,1,经计算m=(a<=b)&&(n=m
A) 1,1 B) 1,0 C) 0,1 D) 0,0
// a<=b为假,&&是并,前面已经为假,后面就不会再运算了,结果就为假,把0赋给m,即m=0,n=1不变
四、 选择控制结构
1.沃思提出“数据结构+算法=程序”只在面向过程的语言(如C语言)成立
2.算法的正确性衡量方法:
1)有穷性 2)确定性 3)有效性 4)允许没有输入或者有多个输入 5)必须有一个或者多个输出
3.算法的描述方法:
1)自然语言描述 2)流程图描述 3)NS结构化流程图描述 4)伪码描述
4.关系表达式:用作判断条件,结果只有真和假,(n%2!=0)等价于(n%2),0表示假,非0表示真
5.分支结构:当条件P成立时,执行A操作,否则执行B操作;如果B操作为空,即为单分支结构;
如果B操作不为空,即为双分支结构;如果B操作中又包含另一选择结构,则构成多分支选择结构;
6.单分支例题:计算输出两整数最大值
单分支(一般形式):if(表达式P) 语句A
#include
void main()
{
int a,b,max;
printf("Enter a,b:");
scanf("%d%d",&a,&b);
if(a>b) //单分支:if(表达式P) 语句A
max=a;
if(a<=b) //单分支:if(表达式P) 语句A
max=b;
printf("max=%d\n",max);
}
7.双分支例题:计算输出两整数最大值
双分支(一般形式):if(表达式P) 语句1
else 语句2
#include
void main()
{
int a,b,max;
printf("Enter a,b:");
scanf("%d%d",&a,&b);
if(a>b)
max=a;
else
max=b;
printf("max=%d\n",max);
}
8.条件运算符是C语言中唯一的三元运算符,需要三个操作数
9.条件运算符例题:计算输出两整数最大值
条件运算符(一般形式):表达式1?表达式2:表达式3
含义:若表达式1为非0,则结果为表达式2的值,否则是表达式3的值
#include
void main()
{
int a,b,max;
printf("Enter a,b:");
scanf("%d%d",&a,&b);
max=a>b?a:b;
printf("max=%d\n",max);
}
10.多分支控制条件语句(一般形式):
if(表达式1) 语句1
else if(表达式2) 语句2
...
else if(表达式m) 语句m
else 语句m+1
11.条件语句在语法上只允许每个条件分支中带一条语句,而要在分支里处理多条语句 就要使用花括号,构成复合语句
12.随机数的使用方法:
1) 符号常量RAND_MAX在头文件#include中定义,标准C规定RAND_MAX不大于双字节整数的最大值32767
2)随机函数rand()产生的是一个在0~RAND_MAX之间的整数,即[0,32767]之间的整数
3) 利用求余运算rand()%b可将函数rand()生成的随机数变化到[0,b-1]
4) 利用rand()%b+a可将随机数的取值范围平移到[a,a+b-1]
例:产生1~100的随机数: rand()%100+1
13.例题:猜数游戏:计算机想一个数,人猜对了提示Right!,否则提示Wrong!,并告诉大小 #include
#include
void main()
{
int magic,guess;
magic=rand(); //随机数
printf("Please guess a number:");
scanf("%d",&guess);
if(guess>magic) //多分支
{
printf("Wrong!Too big!\n"); //复合语句
}
else if(guess
{
printf("Wrong!Too small!\n");
}
else{
printf("Right!\n");
printf("The number is:%d\n",magic);
}
}
14.switch语句:用于多路选择,一般情况大于三种,用开关语句代替条件语句
1) switch语句(一般形式):
switch(表达式)
{
case 常量1:
可执行语句序列1 //注意:语句序列不使用花括号
case 常量2:
可执行语句序列2
........
case 常量n:
可执行语句序列n
default:
可执行语句序列n+1
}
2) switch语句相当于一系列的if-else语句
3)switch后圆括号内的表达式只能是char型或int型
4)关键字case后接常量,类型与表达式类型一致,常量的值必须互不相同
5)常量与case中间至少有一个空格,常量后面是冒号
6)case本身并没有条件判断的功能,若case后面的语句省略不写,则表示它与后续case执行相同的语句
7)switch语句的执行过程:
第一步,计算switch后表达式的值
第二步,将表达式的值依次与case后的常量比较
第三步,如果相等,执行case后的代码段,执行完毕,可使用break语句跳出switch语句
如果没有break语句,不会再比较,程序将依次执行下面的case后的语句,直到遇到break或者switch的}为止
15.例题:编程实现简单计算器功能
#include
void main()
{
int data1,data2;
char op;
printf("Enter your expression:");
scanf("%d%c%d",&data1,&op,&data2);
switch(op)
{
case '+':
printf("%d+%d=%d\n",data1,data2,data1+data2);
break;
case '-':
printf("%d-%d=%d\n",data1,data2,data1-data2);
break;
case '*':
case 'x':
case 'X':
printf("%d*%d=%d\n",data1,data2,data1*data2);
break;
case '/':
if(0==data2)//也可写成data2==0,写0==data2的好处:
{ //因为赋值表达式左值必须是变量,如果把==误写成=,会提示错误
printf("Division by zero!\n");
}
else{
printf("%d/%d=%d\n",data1,data2,data1/data2);
}
break;
default:
printf("Invalid operator!\n");
//break;这句一般不需要,因为没有break就会依次执行下面的步骤直到break或者switch的}
} //这里已经是switch的}了
}
16.例题:编程实现简单计算器功能,能进行浮点数运算,操作数与运算符之间可加入任意多个空格
#include
#include
void main()
{
float data1,data2;
char op;
printf("Enter your expression:");
scanf("%f %c%f",&data1,&op,&data2);
switch(op)
{
case '+':
printf("%f+%f=%f\n",data1,data2,data1+data2);
break;
case '-':
printf("%f-%f=%f\n",data1,data2,data1-data2);
break;
case '*':
case 'x':
case 'X':
printf("%f*%f=%f\n",data1,data2,data1*data2);
break;
case '/':
if(fabs(data2)<=1e-7)
{
printf("Division by zero!\n");
}
else{
printf("%f/%f=%f\n",data1,data2,data1/data2);
}
break;
default:
printf("Invalid operator!\n");
}
}
//内存中的浮点数所表示的精度是有限的,所以比较实型变量data2与0是否相等时, 不能像整型变量与0比较那样直接用相等关系运算符与0比较,而应使用如下方式判断 实型变量data2的值是否位于0附近的一个很小的区间内,即:if(fabs(data2)<=1e-7)
17.逻辑运算符和逻辑表达式
逻辑非:!,单目运算符,右结合, 优先级最高
逻辑与:&&,双目运算符,左结合,优先级较高
逻辑或:||,双目运算符,左结合,优先级较低
例:判断某一年year是否是闰年的条件:
1) 能被4整除,但不能被100整除;
1)能被400整除
逻辑表达式:((year%4==0)&&(year%100!=0))||(year%400==0)
或:(year%4==0)&&(year%100!=0)||(year%400==0)
18.特别注意:在计算含有逻辑运算符(&&和||)的表达式时,通常尽量使用最少的操作数来 确定表达式的值,这就意味着表达式中的某些操作数可能不会被计算。
例:if(a>1&&b++>2&&c--!=0)中,仅在条件表达式a>1为真时,才会计算后面的值
19.程序测试:
1)程序测试只能证明程序有错,不能证明程序无错
2)例:编程输入三角形三边长a,b,c,判断他们能否构成三角形,能构成什么三角形 #include
#include
#define EPS 1e-1
void main()
{
float a,b,c;
int flag=1;
printf("Enter a,b,c:");
scanf("%f,%f,%f",&a,&b,&c);
if(a+b>c&&b+c>a&&a+c>b)
{
if(fabs(a-b)<=EPS&&fabs(b-c)<=EPS&&fabs(c-a)<=EPS)
{
printf("等边");
flag=0;
}
else if(fabs(a-b)<=EPS||fabs(b-c)<=EPS||fabs(c-a)<=EPS)
{
printf("等腰");
flag=0;
}
if(fabs(a*a+b*b-c*c)<=EPS||fabs(b*b+c*c-a*a)<=EPS||fabs(a*a+c*c-b*b)<=EPS) {
printf("直角");
flag=0;
}
if(flag)
{
printf("一般");
}
printf("三角形\n");
}
else{
printf("不是三角形\n");
}
}
3)例:编程将输入的百分制成绩转换为五分制成绩输出
#include
void main()
{
int score,mark;
printf("Enter score:");
scanf("%d",&score);
if(score<0||score>100)
{
mark=-1;//这个if语句很重要,如果去掉,边界测试101~109,-1~-9会出错 }
else{
mark=score/10;
}
switch(mark)
{
case 10:
case 9:
printf("%d-优!\n",score);
break;
case 8:
printf("%d-良!\n",score);
break;
case 7:
printf("%d-中!\n",score);
break;
case 6:
printf("%d-及格!\n",score);
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
printf("%d-不及格!\n",score);
break;
default:
printf("Input error!\n");
}
}
20.对输入非法字符的检查与处理
1)例:输入两个整型数,计算并输出两个整数的最大值
#include
void main()
{
int a,b,max;
printf("Enter a,b:");
scanf("%d,%d",&a,&b);
max=a>b?a:b;
printf("max=%d\n",max);
}
//隐含问题:在Visual C++下
1.如果输入3.2,1则输出3
2.如果输入1,3.2则输出3
3.如果输入q则输出-858993460
//解决办法:
#include
void main()
{
int a,b,max,ret;
do{
printf("Enter a,b:");
ret=scanf("%d,%d",&a,&b);
if(ret!=2)//返回在遇到非法字符前已成功读入的数据项数
{
//但是scanf()函数不做类型检查,所以输入1,3.2会输出3
printf("Input error!\n");
while(getchar()!='\n');
}
else{
max=a>b?a:b;
printf("max=%d\n",max);
}
}while(ret!=2);
}
21.位运算符的使用
1)位运算是对字节或字内的二进制数位进行测试、抽取、设置或移位等操作
2) 位运算的操作对象只能是char和int类型
3) C语言中共有6种位运算符,只有按位取反是单目运算符,其他都是双目运算符
4)关系运算和逻辑运算的结果要么是0,要么是1,而位运算结果可为任意值,但每一位都只能是0或1
5)6种位运算符:
按位取反 ~ 用于加密处理,一次求反加密,二次求反解密
左移位 <<
右移位 >>
按位与 & 用于对字节中某位清零
按位异或 ^
按位或 | 用于对字节中某位置1
6)按位取反 ~1=0,~0=1
例:~5=-6
~ 00000101
———————
11111010 是-6的补码
7)按位与 0&0=0,0&1=0,1&1=1
例:将15的最低位不变,其余位清零 15&1=1
00001111
& 00000001
——————
00000001
8)按位或 0|0=0,0|1=1,1|1=1
例:将15的最高位不变,其余位均置1 15|127=127
00001111
| 01111111
——————
01111111 是127的补码
9)按位异或 0^0=0,0^1=1,1^1=0
例:3^5=6
00000011
^ 00000101
——————
00000110 是6的补码
10)左移位
x<
例:将15左移1、2、3位的二进制补码如下
初始字节内容 00001111 对应十进制15
左移1位字节内容 00011110 对应十进制30
左移2位字节内容 00111100 对应十进制60
左移3位字节内容 01111000 对应十进制120
11)右移位
x>>n 表示把x的每一位向右移n位,当x为有符号数时,左边空位补符号位值—算术移位
当x为无符号位时,左边空位补0—逻辑移位
例1:将15右移1、2、3位的二进制补码如下
初始字节内容 00001111 对应十进制15
右移1位字节内容 00000111 对应十进制7
右左移2位字节内容 00000011 对应十进制3
右移3位字节内容 00000001 对应十进制1
例2:将-15右移1、2、3位的二进制补码如下
初始字节内容 11110001 对应十进制-15
右移1位字节内容 11111000 对应十进制-8
右左移2位字节内容 11111100 对应十进制-4
右移3位字节内容 11111110 对应十进制-2
12) 无论左移位还是右移位,从一端移走的位不移入另一端,移走的位的信息就丢失了
13)左移位和右移位可以分表代替整数的乘法和除法,左移n位相当于乘以2^n,右移n为相当于除以2^n
14) 例:写出运行结果
#include x 0000 0000 0000 1100
void main() ~x 1111 1111 1111 0011
{ ~x反码1000 0000 0000 1100
int x=12,y=8; ~x反码加一1000 0000 0000 1101 -13 printf("%5d%5d%5d\n",!x,x||y,x&&y);
printf("%5u%5d%5d\n",~x,x|y,x&y);
printf("%5d%5d%5d\n",~x,x|y,x&y);
}
输出: 0 1 1
4294967283 12 8
-13 12 8
五、循环控制结构
1.循环:包括计数控制的循环和条件控制的循环
2.结构化程序设计的三种基本结构:顺序结构、选择结构、循环结构
3.循环结构的类型:
1)当型循环结构:for语句(适合循环次数已知,计数控制的循环)
2)直到型循环结构:while语句、do-while语句(适合循环次数未知,条件控制的循环)
4.while语句
1)一般形式为:
while(循环控制表达式)
{ |
语句系列 |循环体
} |
2)循环控制表达式在执行循环体之前测试
3)执行过程:
计算循环控制表达式的值
如果循环控制表达式的值为真,那么执行循环体中的语句,并返回步骤1
如果循环控制表达式的值为假,就退出循环,执行循环体后面的语句
5.do-while语句
1)一般形式为:
do
{ |
语句系列 |循环体
}while(循环控制表达式);
2)循环控制表达式在执行循环体之后测试
3)执行过程:
执行循环体中的语句
计算循环控制表达式的值
如果循环控制表达式的值为真,那么返回步骤1
如果循环控制表达式的值为假,就退出循环,执行循环体后面的语句
6.for语句
1)一般形式为:
for(初始化表达式;循环控制表达式;增值表达式)
{ |
语句系列 |循环体
} |
2) 在每次循环体被执行之前,都要对循环控制条件测试一次,每次循环体执行完以后都要执行一次增值表达式
3)初始化表达式作用:循环变量初始化,即赋初值
4)循环控制表达式:是控制继续执行的条件,当表达式的值为非0时重复执行循环
5)增值表达式作用:每执行一次循环,循环控制变量增值
6)for语句三个表达式之间用分号分隔,有且只能有两个分号
7)循环控制表达式若省略,表示循环条件为永真
8)初始化表达式和增值表达式都可省略,但是必须有其他语句反应其作用
7.例:从键盘输入n,然后计算输出1+2+3+??n的值
1)while语句编程实现
#include
void main()
{
int i=1,n,sum=0;//sum一定要初始化,不然会是随机值
printf("Enter n:");
scanf("%d",&n);
while(i<=n)
{
sum+=i;
i++;
}
printf("1+2+3+??+%d=%d\n",n,sum);
}
2)do-while语句编程实现
#include
void main()
{
int i=0,n,sum=0;
printf("Enter n:");
scanf("%d",&n);
do
{
sum+=i;
i++;
}while(i<=n);
printf("1+2+3+??+%d=%d\n",n,sum);
}
3)for语句编程实现
#include
void main()
{
int i=1,n,sum=0;
printf("Enter n:");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
sum+=i;
}
printf("1+2+3+??+%d=%d\n",n,sum);
}
8.逗号运算符
1)所有运算符中优先级最低,左结合
2)作用:可实现对各个表达式的顺序求值
3)结果:将最后一个表达式的值作为整个逗号表达式的值
4)例:从键盘输入n,然后计算输出1+2+3+??n的值
#include
void main()
{
int i,j,n,sum=0;
printf("Enter n:");
scanf("%d",&n);
for(i=1,j=n;i<=j;i++,j--)
{
sum+=i+j;
}
printf("1+2+3+??+%d=%d\n",n,sum);
}
9.空语句
1)仅由一个分号构成的语句
2)作用:什么也不做,只起延时作用
3)例:for(i=1;i<50000000;i++)
{
;
}
或for(i=1;i<50000000;i++)
{
}
或for(i=1;i<50000000;i++);
for(i=1;i<=n;i++);
{
sum+=i;
}
等价于
for(i=1;i<=n;i++)
{
;
}
sum+=i;
4) 例:从键盘输入n,然后计算输出1+2+3+??n的值
#include
void main()
{
int i,j,n,sum=0;
printf("Enter n:");
scanf("%d",&n);
for(i=1,j=n;i<=j;i++,j--);
{
sum+=i+j;
}
printf("1+2+3+??+%d=%d\n",n,sum);
}//输出结果:101
10.死循环
1)while语句行末加分号将导致死循环
2)例:i=1;
while(i<=n);//行末加分号导致死循环
{
sum+=i;
i++;
}
相当于
i=1;
while(i<=n)//当输入大于1的n值,循环体中没有语句可以改变控制变量i { //使得循环条件为永真,导致死循环
;
}
sum+=i;
i++;
11.while语句和do-while语句的区别
1)while先判断后执行,有可能一次都不执行,do-while先执行后判断,至少执行一次
2)例:n=101; n=101;
while(n<100) do
{ {
printf("n=%d\n",n); printf("n=%d\n",n);
n++; n++;
} }while(n<100);
//循环一次也不执行 //结果:输出n=101,循环执行一次
3)例:分别用while和do-while语句编程,输入一组数据,然后显示每次输入数据进行累加运算的结果,输入0结束
do-while语句实现:
#include
void main()
{
int num,sum=0;
do{
printf("Enter num:");
scanf("%d",&num);
sum+=num;
printf("sum=%d\n",sum);
}while(num!=0);
}
while语句实现
#include
void main()
{
int num=1,sum=0;//给num赋任意非0值都可以
while(num!=0)
{
printf("Enter num:");
scanf("%d",&num);
sum+=num;
printf("sum=%d\n",sum);
}
}
12.计数控制的循环:循环次数事先已知的循环
1)例1:编写一个程序,从键盘输入n,计算输出n! #include
void main()
{
int i,n,sum=1;
printf("Enter n:");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
sum*=i;
}
printf("%d!=%ld\n",n,sum);
}
2)例2:编写一个程序,从键盘输入n,计算输出1!,2!??n! #include
void main()
{
int i,n,sum=1;
printf("Enter n:");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
sum*=i;
printf("%2d!=%ld\n",i,sum);
}
}
3)例:键盘输入n,编程计算1!+2!+3!+??+n!
#include
void main()
{
int term=1,sum=0,i,n;
printf("Enter n:");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
term*=i;
sum+=term;
}
printf("1!+2!+3!+??+%d!=%ld\n",n,sum);
}
13.条件控制的循环:循环次数事先未知,由条件控制
1)例1:输入两个整型数,计算并输出两个整型数的最大值,如若输入非法字符,提示错误并重新输入
//解释:非法字符,需要输入数字时,字符相对它来说就是非法字符,而需要输入字符型,数字对它不是非法字符,所有都是合法
#include
void main()
{
int a,b,max,ret;
printf("Enter a,b:");
ret=scanf("%d %d",&a,&b);
while(ret!=2)//判断数据个数或格式是否错误
{
while(getchar()!='\n');//清除缓冲区中的错误数据
printf("Enter a,b:");
ret=scanf("%d %d",&a,&b);
}
max=a>b?a:b;
printf("max=%d\n",max);
}
//注意:scanf()函数不做参数类型匹配检查,当输入1 3.2时,scanf返回2,不会导致重新输入
但是,此后的小数点仍留在缓冲区,如果此后还需输入内容,就要先清除缓冲区内容
2)例2:先由计算机想一个1-100之间的数请人猜,若猜对,则计算机提示Right!结束 游戏,否则提示Wrong!,并告诉人是大是小,直到猜对为止,记录人猜的次数,反应猜数的水平
#include
#include
void main()
{
int magic;
int guess;
int counter=0;
magic=rand()%100+1;
do{
printf("Please guess a magic number:");
scanf("%d",&guess);
counter++;
if(guess>magic)
{
printf("Wrong!Too big!\n");
}
else if(guess
{
printf("Wrong!Too small!\n");
}
else{
printf("Right!\n");
}
}while(guess!=magic);
printf("counter=%d\n",counter);
}
14.随机数的使用
a.随机数的产生: rand()
1) 符号常量RAND_MAX在头文件#include中定义,标准C规定RAND_MAX不大于双字节整数的最大值32767
2)随机函数rand()产生的是一个在0~RAND_MAX之间的整数,即[0,32767]之间的整数
3) 利用求余运算rand()%b可将函数rand()生成的随机数变化到[0,b-1]
4) 利用rand()%b+a可将随机数的取值范围平移到[a,a+b-1]
b.随机数的产生: srand(time(NULL))
1)用rand()直接产生的随机数只是一个伪随机数,反复调用产生的随机数序列是一样的,而且每次都只用第一个
2)随机化:使程序每次运行时产生不同的随机数序列的过程
3)随机化的实现:通过调用标准库函数srand()为函数rand()设置随机数种子来实现
4)随机数种子的设置:
法1:每次通过用户输入来完成随机化,srand(1),srand(2),srand(seed),输入seed
法2:的通过函数time()读取计算机的时钟值,并把该值设置为随机数种子srand(time(NULL))
5)函数time()返回以秒计算的当前时间值,即一个代表时间的字符串,使用NULL作为time()的参数时,
time(NULL)的返回值被转换成一个无符号整数,可作为随机数发生器的种子
6)使用time()函数时,必须在程序开头将头文件包含到程序中
15.例:先由计算机想一个1-100之间的数请人猜,若猜对,则计算机提示Right!结束
游戏,否则提示Wrong!,并告诉人是大是小,直到猜对为止,记录人猜的次数,反应猜数的水平
#include
#include
#include
void main()
{
int magic;
int guess;
int counter=0;
srand(time(NULL));
magic=rand()%100+1;
do{
printf("Please guess a magic number:");
scanf("%d",&guess);
counter++;
if(guess>magic)
{
printf("Wrong!Too big!\n");
}
else if(guess
{
printf("Wrong!Too small!\n");
}
else{
printf("Right!\n");
}
}while(guess!=magic);
printf("counter=%d\n",counter);
}
16.例:先由计算机想一个1-100之间的数请人猜,若猜对,则计算机提示Right!屏幕输出多少次成功,
结束游戏,否则提示Wrong!,并告诉人是大是小,最多猜10次,超过就结束,要避免非法字符的输入
#include
#include
#include
void main()
{
int magic;
int guess;
int counter=0;
int ret;//保存scanf()函数的返回值
srand(time(NULL));
magic=rand()%100+1;
do{
printf("Please guess a magic number:");
ret=scanf("%d",&guess);
while(ret!=1)//若存在输入错误,则重新输入
{
while(getchar()!='\n');//清楚缓冲区中的内容
printf("Please guess a magic number:");
ret=scanf("%d",&guess);
} //若存在非法字符,则重新输入
counter++;
if(guess>magic)
{
printf("Wrong!Too big!\n");
}
else if(guess
{
printf("Wrong!Too small!\n");
}
else{
printf("Right!\n");
}
}while(guess!=magic&&counter<10);
printf("counter=%d\n",counter);
}
延伸拓展:先由计算机想一个1-100之间的数请人猜,若猜对,则计算机提示Right!屏幕输出多少次成功,
结束游戏,否则提示Wrong!,并告诉人是大是小,最多猜10次,超过就继续猜下一个数,每次运行程序,可
反复猜多个数,直到操作者想停时结束,要注意避免非法字符输入的问题
#include
#include
#include
void main()
{
int magic;
int guess;
int counter;
char reply;//保存用户输入的答案
int ret;//保存scanf()函数的返回值
srand(time(NULL));
do{
magic=rand()%100+1;
counter=0;
do{
printf("Please guess a magic number:");
ret=scanf("%d",&guess);
while(ret!=1)//若存在输入错误,则重新输入
{
while(getchar()!='\n');//清楚缓冲区中的内容
printf("Please guess a magic number:");
ret=scanf("%d",&guess);
} //若存在非法字符,则重新输入
counter++;
if(guess>magic)
{
printf("Wrong!Too big!\n");
}
else if(guess
{
printf("Wrong!Too small!\n");
}
else{
printf("Right!\n");
}
}while(guess!=magic&&counter<10);
printf("counter=%d\n",counter);
printf("Do you want to continue(Y/N or y/n)?");
scanf(" %c",&reply);//%c前有一个空格,读取缓冲区中的回车符
}while(reply=='Y'||reply=='y');
}
17.设计一个简单计算器,允许连续做多次算术运算
#include
#include
void main()
{
float data1,data2;
char op;
char reply;
do{
printf("Please enter your expression:\n");
scanf("%f %c%f",&data1,&op,&data2);//加空格可在操作数和运算符之间加任意多个空白符
switch(op)
case '+':
printf("%f+%f=%f\n",data1,data2,data1+data2);
break;
case '-':
printf("%f-%f=%f\n",data1,data2,data1-data2);
break;
case '*':
case 'X':
case 'x':
printf("%f*%f=%f\n",data1,data2,data1*data2);
break;
case '/':
if(fabs(data2)<=1e-7)
{
printf("Division by zero!\n");
}
else{
printf("%f/%f=%f\n",data1,data2,data1/data2);
}
break;
default:
printf("Invalid operator!\n");
}
printf("Do you want to continue(Y/y or N/n)?");
scanf(" %c",&reply);//加空格清除缓冲区中的回车符
}
while(reply=='Y'||reply=='y');
}
18.嵌套循环
一个循环语句放在另一个循环语句中构成的循环称为嵌套循环
1) 嵌套循环的总循环次数等于外层循环次数和内层循环次数的乘积
2)为避免造成混乱,嵌套循环的内层和外层的循环控制变量不要同名
3)例:键盘输入n,编程计算1!+2!+3!+??+n!
#include
void main()
{
int term,sum=0,i,j,n;
printf("Enter n:");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
term=1;
for(j=1;j<=i;j++)
term*=j;
}
sum+=term;
}
printf("1!+2!+3!+??+%d!=%ld\n",n,sum);
}
19累加求和构成规律:
1)当累加项较为复杂或者前后项之间无关时,需要单独计算每个累加项
2)当累加项前项与后项之间有关时,根据前项计算后项
#include
void main()
{
int i,n;
long term=1,sum=0;
printf("Enter n:");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
term=term*i;
sum=sum+term;
}
printf("1!+2!+3!+??%d=%ld\n",n,sum);
}
20.goto语句
1)功能:使程序无条件跳转到语句标号所标识的语句去执行,所跳过的语句不再执行
2)一般形式:
①向前跳转 ②向后跳转
goto 语句标号; 语句标号:??(后)
?? ??
语句标号:?? (前) goto 语句标号;
3)应用:通常情况,goto语句与if语句联合使用
if(表达式) goto语句标号; 语句标号:??
?? ??
语句标号:?? if(表达式) goto语句标号;
21.break语句
1)功能:①用于退出switch结构
②用于退出由while,do-while和for语句构成的循环体
2)原理:当执行循环体遇到break语句时,循环体将立即终止,从循环语句后的第一条语句开始继续执行
3)应用:break语句通常与if联合使用,表明在任何条件下跳转到紧接循环语句后的第一条语句
22.continue语句
1)功能:跳过continue后面尚未执行的语句,开始下一次循环,只结束本次循环,不终止整
个循环
2)例题:
#include
void main()
{
int i,n;
for(i=1;i<=5;i++)
{
printf("Please enter n:");
scanf("%d",&n);
if(n<0) continue;
printf("n=%d\n",n);
}
printf("Program is over!\n");
}
23.函数exit()
1) 标准库函数exit()用于控制程序的流程,调用时,需要加头文件
2)一般形式:exit(code);
3)功能:终止整个程序的执行,强制返回操作系统,并将int型参数code的值传给调用进程 (一般为操作系统),当code的值为0或宏常量EXIT_FAILURE,表示程序出现某种错误后退出
24.goto,break,continue,exit()的比较
1)goto,break,continue,exit()都用于控制程序的流程,前三个是流程控制语言,exit()是C标准函数
1)功能:goto语句可以向任意方向跳转,break语句只限定流程跳转到循环语句之后 的第一条语句,continue语句结束本次循环,exit()直接终止所有程序
2)break,goto语句和exit()函数都可用于终止整个循环的执行,continue不能终止整个循环
3)在嵌套循环下,break语句和continue语句只对包含他们的最内层循环语句起作用, 不能用break语句跳出多重循环,只能一层一层的跳出
4)使用goto语句的两种特定情形:
①快速跳出多重循环
②跳向共同的出口位置,进行退出前的错误处理工作
25.例题:韩信点兵:x%5==1&&x%6==5&&x%7==4&&x%11==10
①穷举法(循环条件自定义,不具实际意义)
②break退出循环(循环条件省略,满足条件结束循环)
③exit(0)结束程序(循环条件省略,满足条件结束整个程序)
④使用标志变量(循环条件为标识变量为0,最佳方法)
#include
void main()
{
int x;
int find=0;
for(x=1;!find;x++)
{
if(x%5==1&&x%6==5&&x%7==4&&x%11==10)
{
printf("x=%d\n",x);
find=1;
}
}
}
26.类型溢出
1)原因:当运算的结果超出了类型所能表示的数的上界,导致进位到达了最前面的符号 位或者更多进位的丢失,就会发生类型溢出
2)解决办法:采用取值范围更大的数据类型来定义变量
27.结构化程序设计的基本思想
1)采用顺序、选择和循环三种基本结构作为程序设计的基本单元,语法结构具有4个特性 ①只有一个入口
②只有一个出口
③无不可达语句,即不存在永远执行不到的语句
④无死循环,即不存在永远都执行不完的循环
2)尽量避免使用goto语句,因为它破坏了结构化设计风格,并且容易带来错误的隐患
3)采用自顶向下、逐步求精的模块化程序设计方法进行结构化程序设计
c语言入门基础知识
数据类型----C的数据类型包括:整型、字符型、实型或浮点型、枚举类型、数组类型、结构体类型、共用体类型、指针类型和空类型。
常量与变量----常量其值不可改变,符号常量名通常用大写。变量是以某标识符为名字,其值可以改变的量。变量在编译时为其分配相应存储单元。
数组----C++语言代码如果一个变量名后面跟着一个有数字的中括号,这个声明就是数组声明。字符串也是一种数组。
指针----如果一个变量声明时在前面使用 * 号,表明这是个指针型变量。换句话说,该变量存储一个地址,指针不仅可以是变量的.地址,还可以是数组、数组元素、函数的地址。
字符串----C语言的字符串其实就是char型数组,使用字符型并不需要引用库,但是使用字符串就就需要C标准库里面的一些用于对字符串进行操作的函数。它们不同于字符数组。
文件输入/输出----在C语言中,输入和输出是经由标准库中的一组函数来实现的。标准输入/输出有三个标准输入/输出是标准I/O库预先定义的:stdin标准输入、stdout标准输出、stderr输入输出错误。
运算----C语言的运算非常灵活,功能十分丰富,运算种类远多于其它程序设计语言。
关键字----又称为保留字,就是已被C语言本身使用,不能作其它用途使用的字。例如关键字不能用作变量名、函数名等标识符。由ANSI标准定义的C语言关键字共32个:
auto double int struct break else long switch
case enum register typedef char extern return union
const float short unsigned continue for signed void
default goto sizeof volatile do if while static inline
restrict _Bool _Complex _Imaginary _Generic
c语言基础知识有哪些相关文章: