目录
一、C语言
- 上机运行一个C程序必须经过编辑、编译、链接和执行4个步骤。
- C语言源程序文件的后缀是 .c ;
经过编译(作用:①对于按程序进行检查,判定是否有语法错误。②直到没语法错误为止,编译程序把源程序转换成二进制形式的目标程序)后,生成文件的后缀是 .obj ;
经过连接(编译后得到的二进制目标文件还不能供计算机执行,只能得到与源程序文件相对应的文件,也就是目标模块,他只是整个程序的一部分。
要将所有编译后得到的目标模块连接装配起来,目标模块输入计算机与系统提供的库函数等进行连接)后,生成文件的后缀是 .exe,成为可执行程序。(经编译链接后生成的文件后缀是.exe)。 - c语言程序的基本结构是顺序结构,选择结构,循环结构。
它们的特点是:①只有一个入口;②只有一个出口;③结构内的每一部分都有机会被执行到(不代表每个部分都会被执行到);④结构内不存在死循环。 在顺序结构中,各语句是按排列的先后次序顺序执行的,但也是有条件的,需要事先做出判断。(×) - C语言被称为“高级语言”是因为它们比较接近人们习惯使用的自然语言和数学语言。(√)
汇编语言被称为“低级语言”是因为程序不直观、繁琐、工作量大,且无通用性。(√)
高级语言跟低级语言的区分:
低级语言是相对于高级语言而言,所谓低级,也是指接近电脑底层的编程语言。高级语言相对低级语言有较高的可读性,更易理解(但计算机不能直接识别和执行)。
常见的低级语言包括:机器语言,嵌入式,汇编语言等;而高级语言则包括:c,java.net,Android,objectC,swift等。其中,低级语言的特点是执行效率高,速度快;因为它们都是接近底层编程,没有编译解析等过程,程序直接操控硬件,效率相对较高,但是其学习和编程调试难度较高,编程比较慢,且比较费时,项目周期长。而高级语言是依赖编译解析的,更接近于人类语言逻辑的编程语言,其可读性更高,开发效率更高,学习起来相对较容易;但是其执行效率较低级语言而言要低一些,而且高级语言的执行,需要依赖运行环境,在Java等编程语言中,如果环境配置不完善,或者环境版本不一致则可能导致程序无法执行。
简单来说,高级语言:实现效率高,执行效率低,对硬件的可控性弱,目标代码大,可维护性好,可移植性好。低级语言:实现效率低,执行效率高,对硬件的可控性强,目标代码小,可维护性差,可移植性差。 - C语言程序的结构:
①一个程序有一个或多个源程序文件组成。
②函数是C程序的主要组成部分。
③一个函数包括两部分:函数首部和函数体。
④程序总是从main函数开始执行的。
⑤C语言本身不提供输入输出语句。两操作是由库函数scanf和printf等函数来完成的,也就是说由系统提供的输入输出函数。
每个C程序文件中都必须有一个main()函数(×)原因:每一个C程序中都必须有且只有一个main()函数,但一个C程序可以由多个程序文件组成,所以并非每个C程序文件中都必须要有一个main()函数。
-
构成C程序的基本单位是函数(√)
- 一个源程序文件中可以包含三部分:①预处理指令。如#include <stdio.h>等。②全局声明。③函数定义。
-
在文件包含命令#include中,文件名只能用尖括号括起来(×)
include文件两种表达形式:
①<> ② "" (这个在后续会重点讲)
-
-
C语言关键字 main不是关键字
二、顺序程序设计
-
常量和变量
1.常量:在程序运行过程中,其值不能被改变的量称为常量。
(1)整数常量。如123,0,-86等。
(2)实型常量。又称实数或浮点数。在C语言中可以用单精度型和双精度型两种形式表示实型常量,分别用类型名float和double进行定义 。实型变量只能存放实型变量,a=10转换成实型变量后存储。
①在C语言中,则以“e”或“E”后跟一个整数来表示以“10”为底数的幂数。且C语言语法规定,字母e或E之前必须要有数字,且e或E后面的指数必须为整数。总言而之,带'e'或'E'表示幂数时,前后都必须有数。如e3、7e5.4、.e、e等都是非法的指数形式。注意:在字母e或E的前后以及数字之间不得插入空格。
②小数形式是由数字和小数点组成的一种实数表示形式。注意:小数形式表示的实型常量必须要有小数点。
0.1、.123、123.、0.0、-3.54e-5都是合法的。
(3)字符常量是一个用单引号括起来的单个字符(转义字符自带\开头,带两个或多个字符,但它只代表一个字符,\后跟八进制数据,比如'\101'表示字符A,一般\后最多三位),在C语言中一个字符常量代表ASCII字符集中的一个字符,字符常量在内存中占4个字节,存放的是字符的ASCII码(整型数据) 。C语言规定所有字符常量都作为整型量来处理。此外,字符型数据与整型数据任意通用。 char c='\72';包含1个字符,占一个字节。
①普通字符,用单撇号括起来的一个字符。
②转义字符。'\12'代表八进制数12. '\x41'代表16进制数41的ASCII字符,'\033'或'\x1B'代表ASCII代码为27的字符。'\0'或'\000'表示ASCII码为0的控制字符,即“空操作”字符。转义字符后的八进制或十六进制不应大于char类型所允许的范围。所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示。
d代表一个八进制数,h代表一个十六进制数。
(4)标识符
在计算机高级语言中,用来对变量、符号常量名、函数、数组、类型等命名的有效字符序列的统称。C语言规定标识符只能由字母、数字、下划线三种字符组成,且第1个字符必须为字母或下划线。
正确描述的C语言常量
(1).25(√)
(2)5.(√)
(3)090(×)
原因:以0开头的表示他是一个八进制数,而它的各个位置最大小于8。
(4)'\xAA'=='\xaa' (√)转制字符不受大小写影响,A、B、C、D、E、F(a、b、c、d、e、f)表示,其中:A~F表示10~15,
(5)'\02071' (×)
原因:编译后出现waring:multi-character character constant [-Wmultichar]。转义字符都有意义,而不是随意表示。所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示。
(6)在字符串中的//跟/*都不作为注释的开始,而是作为字符串的一部分。
'\\'(√)表示字符斜杠常量\
(4)字符串常量
"a"表示一个字符串(√)
与'a'区别?
C语言中"a"表示一个字符串,在内存中存储为 'a' '\0' 两个字符,大小为2字节。
C语言中'a'表示一个字符,在内存中存储为 'a' 一个字符,大小为1字节。
注意:"123"中的123不是十进制的123,而是字符。
(5)符号常量,用#define指令,制定一个字符名称代表一个常量。符号常量不是变量,不占内存,它只是一个临时符号,代表一个值,预编译后这个符号就不存在了,故不能对符号常量赋上新值。通常用大写表示。如:
#define PI 3.1416 //注意行末没有分号
2.变量 必须先定义,后使用。
3.常变量 前加上一个关键词const,而且变量存在期间其值不能改变。
常变量和符号常量区别:性质不同。后者一个预编译指令不占内存,后者要占内存,且有变量值,只是该值不改变而已。
4.标识符。只能有字母、数字和下划线三种字符组成,且第一个字符必须为字母或下划线。
合法整数 0Xbbc(√) afbc(×) 110110B(×)
若a是实型变量,C程序中允许赋值a=10,因此实型变量中允许存放整型数(×)
若a是实型变量,C程序中不允许赋值a=10,因此实型变量中只允许存放实型数(×)
原因:实型变量中只能存放实型变量a=10是将10做了隐式转换成实型变量后再存在a中的,只能说是整型和实型可以转换。
字符串"\012945"是一个合法的字符串。(√)
原因:字符串中如果有\,则不再理解为转义符。
-
数据类型
注意内存长度,即有效数字。如int a=12356789的有效数字为123567,即从最高位到最低位计内存长度。
- 只有整型(包括字符型)数据可以加unsigned或signed修饰符,实型数据不能加。
- "%u"是无符号整型数据的格式输出。
- 补码(先挖个坑)
-
一个实型变量的小数部分并不一定都是精确、有意义的(√)
-
字符串不是C语言基本数据类型。(√)
C语言六种基本数据类型short、int、long、char、float、double
所以当判断浮点数是否等于0时,不能直接用==0,而是得采取近似无限接近于0的方法(一个浮点变量的绝对值小于一个极小值,这个极小值就可以是1e-6至1e-7左右)。
(1)字符型数据和字符变量
i.字符是以整数形式(字符的ASCII代码)存放在内存单元中的。'1'和1是不同概念。字符'1'只是代表一个形状为'1'的字符,在需要时按原样输出。也即'1'+'1'的结果并不等于整数2或字符'2'。
ii.“%d”格式输出的是整数,“%c”格式输出字符。此外大小写问题可以运用差32通过ASCII码转换。
例 数字字符0的ASCII值为48,若有以下程序: main() char a='1',b='2'; printf("%c,",b++); printf("%d\n",b- a);
输出结果是2 2
原因:char型变量,表示的是字符,其内部存储的就是ASCII码值,以整型方式输出时,打印的就是对应的ascii码值的10进制值。也就是%d输出ASCII码的值,而%c输出ASCII上对应的结果。
运算符和表达式
- 自增自减在循环中的差异
- %要求运算对象为整数。如5.0%3是错误表达式。除%外的运算符的操作数都可以是任何算数类型。
- 整型变量"/"的运算结果会被截断。如若有定义:int a=8,b=5,c执行语句c=a/b+0.4后,c的值为1,小数赋给c后的部分被截断。
- 条件运算符是唯一三目运算符,右结合。
- c>a+b 等效于 c>(a+b) a>b==c 等效于 (a>b)==c
a==b<c等效于 a==(b<c) a=b> 等效于a=(b>c) - 字符型数据与整型数据进行运算,就是把字符的ASCII代码与整型数据进行运算。如:12+'A'相当于12+65等于77。与实型数据运算同理(将ASCII代码转换成double 型数据)。
- 强制转换类型
格式应为(类型名)(表达式)。在强制类型转换时,得到一个所需类型的中间数值,而原来便来那个的类型未发生改变。
设x,y分别为单精度和双精度类型变量.则 int(x+y)可将表达式x+y的运算结果强制转换为整型数据(×) -
逗号运算符是C语言运算符中优先级最低的运算符,比赋值运算符还低。其语法格式为:表达式1, 表达式2,表达式3。结合方式:自左至右,把最右侧表达式的值作为整个表达式的值。
例① a=5,b=3,a*b a=5,3的运算后的结果分别是15 3
例②p=q=2,q*6其中p=2,q=2,逗号表达式值为12。
p=(q=2,q*6)其中p=12,q=2,逗号表达式值为12。
若d为double型变量,则表达式d=1,d+5,d++的值是 1.0
解析:按照运算符优先级,从右往左,最后值为1。因为是double 所以要加小数部分
-
单目运算符--或++的运算对象可以使整型变量、实型变量、字符型变量,但不能是常量或表达式。例++(i+1)是非法赋值语句。(√)
原因:++a,这个a必须是变量而不能是表达式或者常量(这里的常量包括数值常量、符号常量、常变量)。由于(i+1)是表达式,虽然i是变量,仍然不符合C语言的语法规则,所以是错的。
- C源程序中不能表示的数制是二进制。原因:虽然计算机只能识别二进制,但源程序不能用二进制表示。
- putchar(c)中c可以是字符常量、整型常量、字符变量或整型变量(其值在字符ASCII代码范围内)。如 putchar('\101') 输出字符A int a=66 putchar(a)其中66是字符B的ASCII代码,输出字符B。
运算符和表达式
-
逻辑表达式3<2||-1&&4>3-!0的值为:___1___。
-1,值非零,逻辑结果为1(真);
逻辑过程如下:
3<2||(-1&&4>3-!0)
其中3<2=0(假)
右边是逻辑与运算:
逻辑与的左半侧:-1,值非零,逻辑结果为1(真);
逻辑与的右半侧:4>3-!0,!0是非运算,结果为1,所以4>3-1 => 4>2,逻辑结果为1(真);
所以逻辑与运算的结果=1(真)
所以整个逻辑表达式=0||1=1(真) -
sizeof()是整型表达式.
-
putchar(c)中的c可以是字符常量、整型常量、字符变量或整型变量(其值在ASCII代码范围内)
-
scanf里用逗号时,输入也需加上逗号,不然会出现错误。
-
指定数据宽度和小数位数,用%m.nf(点也算在宽度内)。
输出数据左对齐用%-m.nf,左对齐用%m.nf。
scanf输入时不能指定精度,若输入多于要求是,余下的可作为下一个scanf使用。
-
若有定义:int i=3,j;执行j=++i后,i,j的值都为4.但如果这里的j=i++则j为3.
例题 以下程序输出结果是__6___
main( ) {
int m=5;
if(m++>5)printf("%d\n",m); else printf("%d\n",m--); }
-
位运算符
右移 >> 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0
左移<< 用来将一个数的各二进制位全部左移N位,右补0
无符号右移>>>3<<2=12 3>>1=1
-
以下程序的输出结果是a=%d,b=%d
# include <stdio.h>
main()
{ int a=2,c=5;
printf("a=%%d,b=%%d\n",a,c);
}
原因:在%%d中,"%%"代表输出一个"%",d代表一个字符,所以输出结果是%d。
类似的
#include <stdio.h>
int main ()
{
int a =4;
printf("%%d\n",a);
printf("%%%d\n",a);
printf("%%%%d\n",a);
printf("%%%%%d\n",a);
printf("%%%%%%d\n",a);
printf("%%%%%%%d\n",a);
return 0;
}输出结果分别为 %d %4 %%d %%4 %%%d %%%4
每两个"%%"都会被认为是输出一个"%",也就是当%是偶数时输出的应该是带着%d(这里百分号不定,按具体情况确定)的结果,而带奇数时,剩下的一个%(前面每两个%%都被认为是输出一个%)跟d也就是平常输出十进制结果的格式%d。
-
if(x!=y) a=0 else a=1(语句错误,无;)
-
int n=2; n+=n-=n-n执行完后n为4 计算实际是n=n+n-(n-n)=2+2=4
-
短路运算 ①当 && 碰到值为0时发⽣短路 ②当 || 碰到值为1时发⽣短路。
简单来说就是,&&碰到0就不执行后面的语句,||碰到1就不执行后面的语句。
设int a = 1, b=6 ;,执行表达式--a‖(b=8)后,a和b的值分别是0 6.理由同上设整型变量m,n,a,b,c,d均为1,执行 ( m=a>b)&&(n=c>b) 后m,n的值是 0,1
原因:跟&&运算顺序有关。当&&判断前面的部分不为真时,直接认定该表达式为假,而不执行后面的语句。这也能解释为什么n还是等于1,因为执行完前面已经判断为假,而不执行后面的语句。 -
各种进制的表示方法 表示前缀
二进制:0b 八进制:0 十六进制:0x或0X
三、选择结构程序设计
- else总是与它上面的最近的未配对的if配对(不带括号时)。
- switch语句一般形式
switch(表达式)
{case 常量1:语句1 case 常量2:语句2……}
switch一般形式中括号内的“表达式”,其值的类型应为整数类型(包括字符型)。case后只能为常量或常量表达式,不能为有确定值的变量及表达式,即不能有变量。case并不必须从小到大或从大到小。
case常量表达式起语句标号作用。 -
语句括号中的使用条件
if可使用任意表达式
switch其值类型应为整数类型(包括字符型)
putchar可以使字符常量、整型常量、字符变量或整型变量(不能是字符串,只能输入一个字符)
-
switch语句要记得用break终止,在上句无break的情况下,default(无任何条件匹配下的输出)后面的语句也输出。
阅读下面的程序
运行下面的程序时,从键盘输入字母H,则输出结果是 Hello! Good morning!Bye_Bye!
#include <stdio.h> main() char ch; ch=getchar(); switch(ch) case 'H':printf("Hello!\n"); case 'G':printf("Good moming!\n"); default:printf("Bye_Bye!\n");switch语句的执行过程为:进入switch结构后,对条件表达式进行运算,然后从上至下寻找与条件表达式值相匹配的case,以此作为入口,执行switch结构中后面的各语句,直到遇到break语句,则跳出switch语句,如果各case都不匹配时,则执行default后面的语句。本题中ch为字符'H',所以case'H'条件中的语句将被执行,由于没有break语句,所以case'G'后的语句也被执行,由于同样没有break语句,所以default后的语句也被执行了。
- 在case子句中虽然包含了一个以上执行语句,但可以不必用花括号括起来,会自动顺序执行本case标号后面所有语句。当然加上花括号也可以。
-
易错
设有程序:
int n;
scanf("%d",&n);
if(n==1)
printf("1,");
if(n==2)
printf("2,");
else
printf("3,");
n分别等于1,2,3,输出结果是 B
A.1,2,3, B.1,3,2,3, C.1,2,3,3, D.1,2,1,3, - break语句不能终止正在进行的用for语句实现的多层循环。(√)
四、循环结构程序设计
- do...while语句(无论条件是否符合,先执行一次)一般形式:
do {statement(s);} while( condition ); 或者 do 语句 while(表达式);
在do-while循环中,任何情况下都不能省略while。(√)
do-while循环的while后的分号不可以省略。(√)
-
while,do-while和for语句中条件判断只能是关系表达式或逻辑表达式.(×)
也可以为常量。在for语句中,表达式甚至可以不填,但必须有分号,表达式3也可以是与循环控制无关的任意表达式。
for(i=1,s=0;i<=5;i++,j++)此处表达式1表示对i跟s都赋了值,表达式3同时执行两个赋值表达式。 -
若有定义int c;则while(c=getchar());是正确的C语句.(√)
-
break语句只能用于循环语句和switch语句之中,而不能单独使用。
-
break作用是使流程跳到循环体外,接着执行循环体下面的语句,如果为嵌套循环,则终止break所含的循环,跳到上一层循环中。continue作用是提前结束本次循环,跳过循环体终面尚未执行的语句,而接着执行下次循环,并不终止整个循环。
-
***①t为int类型,进入下面的循环之前,t的值为0
while(t=1)
{……}
,则以下叙述中,正确的是 循环控制表达式的值为1
原因:循环控制表达式为赋值表达式“t=1”,永远为1(为真)。
②已知int k=0;则语句while(k=1)k++;将一次也不执行.(×)
while中的表达式应为k==1,而本题却为k=1,是赋值表达式而不是逻辑表达式。因此,编译器将其值一直认为是1,因此表达式一直为真,陷入无限次的循环。
以下不构成无限循环的语句或语句组是_A_。A.n=0;do ++n;while(n<=0);B.n=0;while(1)n++;C.n=10;while(n);n--;
注意:C选项有;
-
(易错)下列程序的输出为_y=-1_。
main()
{int y=10;
while(y--);
printf("y=%d\n",y);
}
while循环先判断,再进行++或者--
-
(重要)下面程序的运行结果是x=1,y=20
#include<stdio.h>
int main()
{ int i,x,y;
i=x=y=0;
do
{ ++i;
if(i%2!=0)
{ x=x+i;i++;}
y=y+i++;
}while(i<=7);
printf("x=%d,y=%d\n",x,y);}
-
下列程序的功能是输入一个整数,判断其是否是素数,若为素数输出1,否则输出0.请填空。
int main()
{ int i, x, y=1;
scanf("%d", &x);
for(i=2; i<=x/2; i++)
if(x%i==0){ y=0; break;}
printf("%d\n", y);
}
-
以下程序的执行结果是___1___。
void main()
{int x=0,s=0;
while(!x !=0)s+=++x;
printf("%d",s);}
-
下面程序的运行结果是_2870_。
#include<stdio.h>
void main()
{ int x,i;
for(i=1;i<=100;i++)
{ x=i;
if(++x%2==0)
if(++x%3==0)
if(++x%7==0)
printf("%d",x);
}}
-
以下程序的运行结果是__21__ 。
#include <stdio.h>
main()
{
int a=3, b=7, t;
t=a > b ? a:b;
while(t % a || t % b)
t++;
printf("%d\n", t)
}
-
编写函数double fun(int n),为以下级数的前n项和,sum。
sum = 1 + 1/3 + 1/5 + 1/7 + 1/9 +...double fun(int n)
{
double sum=1;
int i;
if(n<=0)
return -1;
for(i=2; i<=n; i++)
{
sum += 1.0/(2*i-1);
}
return sum;}
- 有以下程序
void main()
{ int i=0,s=0;
do {
if (i%2) { i++; continue; }
i++;
s+=i;
} while(i<7);
printf("%d\n", s);
}
执行后输出结果是16。