第0章 C语言基本语法3.docx
《第0章 C语言基本语法3.docx》由会员分享,可在线阅读,更多相关《第0章 C语言基本语法3.docx(81页珍藏版)》请在冰豆网上搜索。
第0章C语言基本语法3
第0章C语言基本语法
一共80学时,分两部分:
C、数据结构。
其中C大概32学时,数据结构48学时。
0.1C编译环境
C语言一般可使用两种编程环境:
1、TurboC2.0版本,重要的三个热键:
1)编译:
F9
2)运行:
Ctrl+F5
3)观察结果:
Alt+F5
2、VisualC++6.0版本:
只适合在Windows操作系统下,是微软开发出来的,在这个环境下进行C、C++、VisualC++进行编程非常方便。
在VC++6.0看来,每个程序都应该以“Project”(工程、项目)的形式来进行。
而每个Project又应该包含在一个WorkSpace(工作区)之中。
当然,一个Workspace中可以有多个Project。
因此,我们每创建一个程序,都应该首先创建一个工程,这个工程就是一个整体,经过编译连接等操作,这个工程最终就能够变成一个在Windows下可执行的程序。
在VC6.0中的Project有以下几种常用类型:
1)Win32ConsoleApplication:
Win32控制台应用程序,适合所有的C程序,由它创建出来的应用程序一般没有独立的窗口。
这种程序的入口函数为main函数。
2)Win32Application:
Win32应用程序,适合C/C++程序,这个与上面的区别在于,可以创建出有独立窗口的应用程序,特别地,它可以使用WinAPI函数库。
入口函数不是main函数,而是tmain或WinMain等。
3)MFCAppWizard(.exe):
适合使用VisualC++语言进行编程,可以方便地创建出普通的Windows窗口,能够方便地进行窗口编程。
在这种程序中,连main或WinMain函数都找不到。
0.2熟悉VisualC++6.0编程环境
每一个程序都以“工程(Project)”的形式出现,在VC中,又将一个或多个工程包装成一个“工作区(WorkSpace)”,所以,我们在每个程序编程时都需要创建一个工程,再在这个工程中创建文件(.cpp、.h文件等)。
编译微型条
0.3顺序程序设计
0.3.1数据类型
1、基本类型(整型、浮点型、字符型),枚举类型、复合类型(数组、指针、结构体、共用体)。
2、整型:
int、shortint、longint,都是使用补码的形式来表示。
如要将-123表示成16位(2B)的补码
1)先将123化为原码二进制形式:
0000000001111011
2)最高位取1,其它位按位取反:
1111111110000100,得到的是反码。
3)末尾加1:
1111111110000101
显然,16位所能表示的数据,最大的那个是:
0111111111111111=215-1,最小的那个数:
1000000000000000=-215,而1111111111111111=-1
int
shortint
longint
char
TurboC
2B,-215~215-1
2B,-215~215-1
4B,-231~231-1
1B,-128~127
VisualC++
4B,-231~231-1
2B,-215~215-1
4B,-231~231-1
ASCII:
1B
Unicode:
2B
unsigned:
无符号,也就是没有负数,全部是正数。
如unsignedint
所以,如果对于int来说,1111111111111111=-1,而对于unsignedint来说,1111111111111111=216-1
另外还有一个关键字:
signed,代表有符号,如signedint实际上就是int。
longint可以简写为long,而shortint可简写为short
3、浮点数:
float、double,
float称为单精度浮点数,由4B表示,它只有6个有效数字。
能表示的数据范围:
0及1.2X10-38~3.4X1038
double称为双精度浮点数,由8B表示,它有15个有效数字。
能表示:
0及2.3X10-308~3.4X10308
longdouble长双精度浮点数,一般不太使用,它一般可以有有16B。
注意一个细节:
不准确,可能有些数明明是有限小数,但在计算机中无法表示,将表示成无限的近似的数,如0.1,所以,我们有两点要注意的:
1)不要用浮点数来控制循环次数。
floatf;
for(f=0;f<1;f+=0.1)
{……}
2)不要直接比较两个浮点数是否相等。
如:
doublea=0.1,b=0.11
if(a==b)
真正要做的比较应该为:
if(fabs(a-b)<=1e-7)
4、字符:
char,包括:
(可参照ASCII码表进行)
1)字母:
大写、小写
2)数字:
0~9
3)专门符号:
29个,!
@#$
4)空格符:
空格、水平制表符
5)不能显示出来的字符:
null,可以以'\八进制代码'表示出来,如回车换行符'\007',还可以以'\代号'表示,如'\n'
\n:
回车换行
\f:
换页
\b:
退一格
\r:
回车,不换行,就是回到这一行的最前面开始
\0:
空字符,
\\:
反斜杠本身
字符必须包含在一对单引号中,如:
'a','\035','\n'等
5、字符串:
包含在一对双引号中的任意个(1个或多个)字符,但是一个字符串中至少有一个字符\0,如:
"China"、
charstr[]="\123abc\n\\",
可以使用strlen(str)来求字符串str中有多少个字符,此处得到6.
可以使用sizeof(str)来求字符串str占了多少个字节的空间,此处得到7.
注意:
1)双引号本身应该在英文状态下
2)字符串中可以有中文,一个中文点两个字节
0.3.2运算符
+-*/%
除:
规定如果参加运算的两个数都是整数的话,则结果也是整数;而如果只有有任意一个数据为float或double,则结果为double,如:
doublec;
inta=-10,b=4;
//方法一:
强制转换某个数为double或float
c=(double)a/b;//c=2.5
c=a/(double)b;
printf("c=%lf\n",c);
//方法二:
将数字前面乘以1.0,从而该数变为double
c=1.0*a/b;//c=2.5;
printf("c=%lf\n",c);
陷阱:
inta=-10,b=4;
floatc=2.5,d=5.2;
doublee;
e=c*d+a/b;
取余%:
规定参加运算的两个数必须是整型(包括int、short、long、char),不得为浮点数,其结果为被除数除以除数所得到的余数,其符号与被除数相同。
如:
inta=-20,b=3;
intc=a%b;//c=-2
intd=a/b;//d=-6
如果
inta=20,b=-3;
intc=a%b;//c=2
intd=a/b;//d=-6
0.3.3赋值
在C中,赋值运算符包括:
=、+=、-=、*=、/=、%=及后面的位运算的&=、|=、^=等。
注意问题:
1、复合赋值:
+=、-=、*=、/=、%=,如:
intb=5;
b+=7;//相当于b=b+7;
其计算顺序为从右向左计算,如:
inta=10;
a+=a-=a*=a/=2;//结果a=0
可以分解为:
a/=2;a*=a;a-=a;a+=a;
2、括号的问题:
inta=10,b,c;
a+=(b=3*4);//b=12,a=22
3、逗号表达式的问题,规定,取最后一个数的值,如:
inta=10,b;
a+=(b=3*4,c=(5,10,15));//b=12,c=15,a=25
4、混合运算类型的转换问题:
1)有些转换是自动完成的,其一般原则为:
char->int->long->double如:
doublef;
inta,b;
floatt;
charc;
f=(t=a+c);
2)如果不满意,可以强制类型转换
a=(int)(f+t);
由doube或float强制向int转换方式,是直接将小数点后面的所有的数据摸掉,不会自动进行四舍五入。
如:
doubled=12.89;
inta;
a=(int)d;//a=12
如果我们想要四舍五入,得用技巧,加0.5后再取整。
如:
doublee=12.89,f=34.46;
inta=(int)(e+0.5);//a=13
intb=(int)(f+0.5);//b=34;
这个小技巧可以扩展:
精确到小数点后几位,如:
doubled=12.345678;
现在,要想精确到小数点后3位,应该得到:
12.346,方法为先乘以1000,再加0.5,再取整,再除以1000.0:
d=(int)(d*1000+0.5)/1000.0;
0.3.4自增和自减
++、――,形式有两种:
a++,++a,
a++规定,先取a的值在本表达式中进行计算应用,再将a加一,只影响后面的语句,如:
inta=4;
intb=a++;//b=4,a=5
intc=++a;//a=5,c=5
a=4;
intd=(a++)+(a++)+(a++);
在VC中,相当于四条语句:
d=a+a+a;a++;a++;a++;
其结果,a=7,d=12;
++a规定:
先将a的值加一,再应用a的值,并影响这条语句。
如:
inta=4;
intb=++a;//a=b=5;
intc=(++a)+(++a)+(++a);
在TurboC中,相当于四条语句:
++a;++a;++a;c=a+a+a;
0.3.5数据的输入与输出
1、输出:
printf、putchar、puts等
注意:
1)特殊字符的输出:
\n、\b
2)输出各种字符的方式:
整型%d,字符%c,字符串%s,小数形式的浮点数%f,指数形式的浮点数:
%e,长整型%ld,double型%lf,后面的指针类型(地址)%lp
3)对于整型宽度问题:
%5d,这个数字点5个位置,多出的位置用前置空格被齐,被在数字的前面。
如果%-5d,空格被在数字的后面。
如果这个数字的长度大于5,则将该数字完整的打印出来。
4)对于浮点数,用%f打印小数,用%e打印指数。
5)可以指定小数点后几位,如%.3f,或%10.3f,意思是说,小数点后占3位,一共占10位(包括小数点位,因此,只有9位数字)
6)对于整数,输出八进制数:
%o,输出十六进制数:
%x或%X
7)输出无符号整数:
%u,如果该数实际上已经是有符号的数,按%u输出后,负数会变成正数。
8)输出长整型数:
%l(注:
字母l),在VC中完全不需要。
9)如果想输出特殊的字符如\、%本身,可\\,%%输出
10)输出地址:
%lp,
11)输出单个字符可用putchar()进行。
2、输入:
scanf、getchar、gets等
可接收的输入数据包括:
整数、浮点数、字符、字符串,且均以回车键结束输入。
格式与输出相同。
1)可以指定宽度:
如:
scanf("%3d%4d%d",&a,&b,&c);//如果输入123456789,则a=123,b=4567,c=89,但是,如果用户输入的是:
123456789,则a=12,b=3456,c=78,9多余舍弃掉。
2)常见错误:
(1)后面的变量必须用地址,如果不用地址,会出错。
scanf("%3d%4d%d",a,b,c);//错误,a、b、c必须用地址表示
(2)如果变量本身就是地址(指针),那么不能再用地址,如:
inta;
int*p=&a;
scanf("%d",p);//正确,因为p就是a的地址,就是输入到a中去了。
scanf("%d",&p);//错误,变成将整数输入到p中去,可是,p又是指针。
(3)在scanf中,除了格式符外,不要出现多余的文字,如:
scnaf("a=%d,b=%d",&a,&b);//用户在输入数据时,必须a=5,b=10才能正确输入。
3)输入字符:
可用%c,如果混合输入,非常麻烦:
4)还可以使用getchar()输入字符,方式为:
c=getchar();
5)还可以使用getch()输入字符,方式为:
c=getch();
该函数应该包括头文件,且用户不需要按回车键就输入,在制作游戏中比较有用。
6)还可以使用getc(stdin)输入字符,其中参数stdin就是标准输入设备,由VC定义好的。
c=getc(stdin);
这种方法在文件操作中比较有用,其中的参数stdin可以换成是我们已经通过fopen打开的文件指针,就能够从该文件中输入一个字符。
0.4C语言中的选择结构程序设计
0.4.1关系运算符和关系表达式
关系运算符有6种:
<、<=、>、>=、==、!
=
其中:
<、<=、>、>=的优先级相同,==、!
=优先级相同,且前者的优先级高于后者。
而且,优先级:
算术运算符高于关系运算符高于赋值。
关系表达式:
就是用关系运算符将若干个数值、数值表达式连接起来的式。
如:
a>b,(a=3)>b+(c==4)
在C中,并不存在"真"和"假",只有非0和0,规定:
凡是结果为0的,认为“假”(不成立),凡是结果为非0的,都认为是“真”(成立),哪怕结果为0.000001、'A',也是真。
且在C语言中,没有所谓的BOOL型。
因此,有时我们会看到类似这样的式子:
if(a=b+c)//判断a是0还是非0,如果为非0,则说明“真”
{
}
注意与:
if(a==b+c)
{
}
的区别。
在编程的时候,有时可以用C的检查机制来检查我们的错误。
可以写为:
if(b+c==a)
{
}
因为如果你写错成:
if(b+c=a)
{
}
C语言能够查找出这个错误:
赋值运算符规定左边必须是一个变量。
同样地,如果要写判断一个变量是否与某个常数相等:
if(a==12)
可写成:
if(12==a),因为如果写错成:
if(12=a),则C语言能发现这个错误。
再次强调:
通过关系运算的结果只有两种:
1表示真,0表示假。
所以:
inta=3,b=4,c=5,d=0;
表达式c>b>a在数学上的结果为“真”,但是在C语言中,这个表达式的结构为0(假),其计算过程为先计算:
c>b,为真得到1,再计算1>a为假,得到0.也正因为如此,如果我们就是要表达数学上的c>b>a的真实含义,则需要使用逻辑运算符来连接起来:
c>b&&b>a
0.4.2逻辑运算符和逻辑表达式
逻辑运算符:
&&与、||或、!
非
逻辑表达式:
用逻辑运算符将若干个表达式连接起来的式子。
如:
a+b>c&&c逻辑表达式的结果也用0或1来表示假或真。
逻辑运算符的真值表:
a
b
!
a
!
b
a&&b
a||b
非0
非0
0
1
1
非0
0
0
0
1
0
非0
1
0
1
0
0
1
0
0
优先级:
!
最高→&&→||
与关系运算符的比较:
!
高于算术运算符,&&和||低于关系运算符,算术运算符高于关系运算符。
!
→算术运算符(+-*/%)→关系运算符(<、<=、>、>=、==、!
=)→&&和||→赋值运算符=
所以:
如果有式子:
(a>b)&&(x>y)可以写成a>b&&x>y
a+!
b>c&&!
c使用逻辑运算和关系运算可以进行复杂的计算、判断。
如判断闰年,满足以下条件的年份都是闰年:
1)如果年份能够被400整除,则一定是闰年,如2000;
2)如果年份能被4整除,但又不能被100整除的,也是闰年,如1996、2004是,而2100年不是闰年。
3)其它的不是闰年
假设年份为y,请写出判断闰年的表达式:
y%400==0||(y%4==0&&y%100!
=0)
或写成:
!
(y%400)||!
(y%4)&&y%100
判断一个变量是否为0,至少有两个方法:
if(a==0)
或:
if(!
a)
而判断一个变量是否为非0,也有两种方法:
if(a!
=0)
或:
if(a)
在C++或VisualC++中,有一种称为BOOL类型的数据,实质就是int型。
实际上BOOL就是通过typedef这个关键字来定义出来的新的类型:
typedefBOOLint;
这样,用BOOL来定义变量,实质就是用int来定义的。
而TRUE和FALSE实际上是用#define定义出来的两个宏:
#defineTRUE1
#defineFALSE0
BOOLb;//intb;
b=TRUE;//b=1,TRUE是一个宏定义为1:
#defineTRUE1
b=FALSE;//b=0,#defineFALSE0
在Java中,有真实的BOOL型数据,用true和false表示真、假。
因此,在Java中,如果inta=5;if(a)是错误的。
0.4.3条件运算符和条件表达式
表达式1?
表达式2:
表达式3
它的计算过程是,如果表达式1的值为非0,则取表达式2的值,如果表达式1的值是0,则取表达式3的值。
如:
inta=5,b=-2,c,d=7,e=-6,f=11,g=-9,h=-1;
c=(a>b)?
10:
-7;//c=10
c=(a>b)?
((a>d)?
d:
((df:
g)):
h;//c=-9
有一个经典的考题:
如何用条件表达式来求出a、b、c三个变量中最大值。
intgetMax(inta,intb,intc)
{
return_______________________________________;
}
0.4.4if-else语句
基本语法:
if(表达式)
{
路径1
}
else
{
路径2
}
其程序流程图:
0.4.5嵌套的if-else语句
1、第一种嵌套的形式有:
if(表达式1)
{
路径1;
}elseif(表达式2)
{
路径2;
}else
{
路径3;
}
例如:
判断成绩s:
0~59
60~69
70~79
80~89
90~100
差
及格
中
良
优
可以编程:
假设s一定在0~100之间,则:
if(s>=0&&s<=59)
{
差;
}elseif(s>=60&&s<=69)
{
及格;
elseif(s>=70&&s<=79)
{
中;
elseif(s>=80&&s<=09)
{
良;
}elseif(s>=90&&s<=100)
{
优;
}
假设s一定在0~100之间,则:
if(s<=59)
{
差;
}elseif(s<=69)
{
及格;
elseif(s<=79)
{
中;
elseif(s<=89)
{
良;
}else
{
优;
}
其它语句;
2、第2种嵌套的形式:
if(表达式1)
{
if(表达式2)
{
if(表达式3)
{
}else
{
}
}else
{
}
}else
{
if(表达式4)
{
}else
{
}
}
如:
if(s<=79)
{
if(s<=69)
{
if(s<=59)
{
差;
}else
{
及格;
}
}else
{
中
}
}else
{
if(s<=89)
{
良;
}else
{
优;
}
}
0~59
60~69
70~79
80~89
90~100
差
及格
中
良
优
7
10
64
13
6
或者写成:
if(s<=89)
{
if(s<=69)
{
if(s<=59)
差
else
及格
}else
{
if(s<=79)
中
else
良
}
}else
{
优
}
3、几种特殊的if-else语句及其嵌套形式:
有些程序判断中,if比else要多,在这种情况下,必须准确地判断else与哪个if配对。
如:
inta=5,b=3,c=-10,d=-7,e=100;
if(a>b)
{
if(c>d)
e++;
}else
e――;
需要强调的是,用分号;来表示一个语句的结束,如:
if(a>b);
if(c>d)
e++;
else
e――;
0.4.6switch-case语句
switch语句又称为多分支选择语句,它可以提供多条路进行选择,它完全可用if语句来取代。
其一般格式:
switch(表达式)//表达式是可以计算出的结果,建议应该是int型或char型,不要是float或者double
{
case值1:
……
break;
case值2:
……
break;
……
default:
……
}
如判断成绩:
switch(s/10)
{
case0:
case1:
case2:
case3:
case4:
case5:
printf("差\n");
break;
case6:
printf("及格\n");
break;
……
}
关于switch-case的注意事项:
1)应该具有必要的break语句来跳出switch,否则结果可能会出错,如:
inta=3,b=10;
switch(a)
{
case1:
b++;
break;
case2:
b++;
case3:
b--;
break;
case4:
b--;
case5:
b++;
default:
b--;
break;
}
课后思考题:
请问2012年11月23日是这一年的第几天?
已知1月1日是第1天。
如果2012年1月1日是星期天,问2012年11月23日是星期几?
0.4.7选择语句编程时的错误小结
1、在判断两个值是否相等时,==误写成=,变成了赋值,如:
inta=5,b=-2;
if(a==b)
{
}
误写成:
if(a=b)
{
}
2、经常if复合语句忘记写大括