新手学C语言之入门Word下载.docx
《新手学C语言之入门Word下载.docx》由会员分享,可在线阅读,更多相关《新手学C语言之入门Word下载.docx(29页珍藏版)》请在冰豆网上搜索。
}是C语言里必须有的一个格式,main翻译是”主要“,main函数就是主函数,相当于程序从这里入口并开始运行。
运行的内容就是花括号{}里头的代码。
了解#include<
main(){}的功能之后,就真正的开始代码实现的部分了。
上面有一条简单的代码:
——————————
inta,b,c;
我们每句话结束用句号“。
”来结束,C语言里用的是分号“;
”来结束一个语句,上面每个语句后面都有一个分号。
a=1表示赋值,把等号右边的数值赋予给左边,赋值之后a等于1,b等于2。
同理可知c=a+b就是把a+b的结果数值赋予给c,这样c的值就是3.
print的翻译是打印,printf()函数实现的功能是输出(打印在屏幕上)。
而printf()函数是属于stdio.h的,这就是为什么上面要写#include<
原因。
定义a,b,c三个变量,int是数据类型里的一种,int是整型,就是说a,b,c都是整数而不能是其他类型。
另外float浮点型,如果用floata,b,c,那么a,b,c就能赋予小数值。
还有char字符型,比如chara,b,,那么a,b只能赋予字符的值。
这是因为在定义a,b,c变量的同时,要在计算机内存中分配给它们空间,整数占用2个字节而小数占4个字节,所以inta后a分配到的空间就是能装下2个字节的东西,然后如果用a=1.23,由于1.23是小数占用4个字节装不下,那么这个赋值就出错。
因此,int,float,char等数据类型定义的意义就在于给变量分配一个多大的内存空间,存储对应类型大小的数据(任何没有定义数据类型的变量是不会分配内存空间所以是不能使用的!
)。
来看下运行结果(print出结果c的值):
所以这样就实现了计算a+b赋值给c并输出c的值。
数据类型一览(当想要使用何种类型变量,直接用以下来定义即可):
C语言和数学语言也还是有所区别的,比如数学里判断a等于b用“a=b?
”,但是C语言里“a=b?
”就变成了赋值,它的等号是两个数学等号组成“==”,所以C里正确的表达是“a==b?
”(不要纠结为什么要用两个等号,这是大神们设定的),为了能让计算机理解自己的代码,下面来认识C语言有哪些运算符:
+
加
-
减
*
乘
/
除;
不存在÷
号,表达式里“/”就是除号。
%
取余数;
17%5等于2,余数是2。
>
大于
<
小于
=
大于等于
小于等于
!
不等于
==
等于
赋值,右边值赋予左边变量(a=a+1+2)。
&
与;
(1==1)&
(1!
=2),判断两边都真结果为真。
||
或;
判断有一边为真结果为真。
非;
!
(1==1),判断条件的相反。
?
:
条件运算;
(2>
1)?
3:
4,判断为真,结果取3,否则取4.
++
自增;
a++,相当于a=a+1。
--
自减;
a--,相当于a=a-1。
其他
经历一遍胜过深思千回,在软件上尝试几遍便能熟记于心。
intmain()
{inta,b,c,d;
a=1;
b=a+1;
c=b*2;
c++;
d=c%3;
printf(“%d”,d);
//ps:
输出结果d。
return0;
写一个能计算圆的周长和面积的C代码:
定义三个浮点型float(含有小数)变量s、l、r。
scanf()是输入函数,scan是扫描的意思,从键盘扫描你的输入,这个函数也是stdio.h头文件里的一个函数。
Scanf()括号里的是参数,跟printf()一样,格式有所不同。
printf(“%d”,c)表示输出结果c,c的数据类型是整型(int),用“%d”格式。
如果输出结果是浮点型(float)则用“%f”格式,比如printf(“%f”,1.23)。
如果是字符型(char),用printf(“%c”,’s’)等。
“%_”
类型
Printf(“%_”,s);
对应数据类型格式
d
int,short
以十进制形式输出带符号整数(正数不输出符号)
o
以八进制形式输出无符号整数(不输出前缀0)
x,X
以十六进制形式输出无符号整数(不输出前缀Ox)
u
以十进制形式输出无符号整数
f
float,double
以小数形式输出单、双精度实数
e,E
以指数形式输出单、双精度实数
g,G
以%f或%e中较短的输出宽度输出单、双精度实数
c
char
输出单个字符
s
字符串
输出字符串
Scanf(“%d“,&
r)比printf(“%d“,r)多了个地址运算符&
,因为scanf是输入,把数据存入到r变量的地址空间,所以scanf()函数统一要加个地址运算符。
(在代码中添加备注用//备注,本行此符号之后的都为备注,也可以用/*备注*/,两个符号之内的是备注,可囊括多行。
)
上面代码中:
————————————
————————————是标准主函数格式,intmain()表示返回int型,return表示返回,返回值为0。
不必深究。
————————————————————
floats,l,r;
//备注:
面积s,周长l,半径r。
scanf("
%f"
&
r);
l=2*3.14159*r;
s=3.14159*r*r;
周长为:
%f,面积为:
%f\n"
l,s);
相当于一个能计算圆的周长和面积的计算器,只要scanf()输入r的值,就能printf()输出l(周长)和s(面积)的值,结果图示:
可以通过输入不同的半径来得到其周长和面积。
同理可以利用c语言来求得其他数学公式的结果:
求y=x^2+2x-3当x取某个数时的值。
代码:
——————————————————
intx,y;
scanf("
x);
//这里输入x的值。
y=x*x+2*x-3;
printf("
输出结果y:
y);
——————————————————
对于这样的函数式:
x*x+2*x-3(0<
x<
10)
Y=
x+2(x>
=10)
要用到条件语句。
(1)if语句
if(表达式)
语句1;
else
语句2;
(2)if语句的嵌套
If(表达式1)
语句1;
//语句1也可以嵌套if语句。
if(表达式2)
语句2-1;
语句2-2;
//这样的嵌套可以多重.
if()里的表达式如果正确则为真,执行紧接着的语句1,否则执行else下面的语句2。
因此上面数学函数式的代码:
————————————————————————————————————
intx,y;
//scanf输入x的值。
if(x>
0&
x<
10)//x>
0和x<
10是与的关系,若同时为真则结果为真。
y=x*x+2*x-3;
else
if(x>
y=x+2;
//双引号里的文字原样输出,%d输出为y的值。
——————————————————————————————————
ps:
if()里的表达式常用到逻辑表达式“与或非”。
(3)switch语句
switch(表达式)
case常量1:
语句1
case常量2:
语句2
case常量3:
语句3
case常量...:
语句...
case常量n:
语句n
default:
语句n+1
switch是匹配的意思,就是用表达式的值从常量1开始比较是否相等,如果相等,从相等的那条语句开始执行,到default的语句结束。
如果想执行完这一句就结束,可以在其后加上break;
语句来打断跳出switch。
下面是输入小明同学的分数判断他的成绩级别的代码:
假如小明的成绩是a=76,那么十位数i=7,利用switch函数匹配,case7符合,执行之后的printf(“C\n”)语句,又因为break;
语句打断,所以不再执行之后的case,直接跳出switch(){}。
如果是59到0,都只有一条语句可执行。
(4)while循环语句
写一个代码,让你输入一个数字,如果你输入的数字不大于100则重新输入,否则结束。
这里就用到了循环,循环必须要有判断条件语句,循环不能是没有结束条件的。
格式:
while(表达式)
语句1
如果表达式为真(判断正确),则执行语句1,直到表达式为假。
inta;
scanf(“%d”,&
a);
//输入数字a。
while(a<
=100)//判断是否小于等于100,是则循环,否则结束。
//重新输入a
return0;
红色部分是循环体,花括号{}里可以写多条语句,作为一个整体一并运行。
执行的顺序是,判断while(表达式)真假,为真则执行循环体,执行完毕跳回到while(表达式)开始下一次的判断,直到判断为假结束循环。
所以上面会不断循环要输入a,直到输入的值大于100,表达式为假结束。
另一种是do-while语句,区别只是先执行循环体,再判断,直到判断为假,while(表达式)后跟着一个分号!
代码如下:
do
//输入a
}while(a<
=100);
//判断是否小于等于100,是则循环,否则结束。
(5)for循环语句
for(表达式1;
表达式2;
表达式3);
循环体语句
实例:
以上加入了一个for循环(/*多行备注*/),
表达式1“a=1”是for循环的入口,是进入for循环第一个运行的语句,而且只运行一次。
表达式1之后就到表达式2,表达式2“a>
b”后面虽然没有问号,但是它是一个判断语句,就像if语句或者while语句的判断表达式一样,在这里如果a>
b判断为真,则继续执行循环体语句,否则结束跳出for循环。
如果表达式2为真,接下来执行循环体语句,再接下来是表达式3,然后开始下一次的循环:
表达式2(先判断是否为真)—>
循环体语句—>
表达式3,表达式1会且只会运行一次,之后的循环都不再执行,而且以上的表达式和循环体都可以是多个语句的组合,比如表达式1可以是“a=2,b++,……”。
(3,4,5为一个循环)
——————————————————————
让我们来输出一个星号*构成的正方形:
表达1赋值使得i=1,j=4,判断i<
=j为真,执行循环体{}后输出五个星号和换行,然后i=i+1(即i变成了2,j不变),继续下一次的循环:
判断2<
4为真,继续执行循环体语句,再输出一行星号并换行,如此重复到i=5大于j判断为假,结束for循环,这时共执行了4次循环体,打印出了4行星号,如上图。
事实上for循环里还可以套用for循环,也可以套用while循环,前者最为常见和好用。
假如要输出3次上面的矩形星号,那么把上面的for循环嵌入到另一个for循环中即可:
这样就把里面的for当成了外面for循环的循环体语句,按步骤执行即可!
兴趣是最好的老师,实践是最好的证明,如果有哪些记不住的地方,上机写代码运行处结果,让事实来让自己信服,这样不单更容易记住,而且还能提高动手能力。
如果遇到有疑问的地方,上网寻找答案,或者上机调试(就是对代码的执行结果有疑问,认为可能出现多种结果),看结果是否如自己所想,也是验证和解疑的一种好办法。
问题:
输入两个正整数m和n,求其最大公约数
解题算法:
辗转相除法,又名欧几里德算法(Euclideanalgorithm)乃求两个正整数之最大公约数的算法。
算法思路:
假如求m和n的最大公约数(m>
n),设y为m÷
n的余数,继续用除数n除以余数y,直到余数为0。
比如求99和21的最大公约数,有:
99÷
21余15
21÷
15余6(这里的被除数和除数分别是上面的除数和余数,相当于后移一位)
15÷
6余3
6÷
3余0(整除)
那么最后一个除数3就是一开始两个数99和21的最大公约数,此算法可以应用到任何两个正整数上,这就是辗转相处求公约数的算法。
算法应用:
1、直接用scanf("
%d%d"
&
m,&
n)输入需要求公约数的两个正整数;
2、m%n的余数为c
3、把n的值赋给m,把余数c的值赋给n(除数变成被除数,余数变成除数)
4、判断c是否为0,是则最后一个除数n(已经赋值给m)就是最大公约数,并输出最大公约数m即可(printf("
m和n的最大公约数是:
%d\n"
m);
5、如果c不为0,继续执行步骤2,直到符合步骤4结束。
intmain()/*辗转相除法求最大公约数*/
{
intm,n,c;
输入两个正整数:
\n"
);
n);
c=n;
while(c!
=0)/*余数不为0,继续相除,直到余数为0*/
c=m%n;
m=n;
n=c;
}
printf("
}
自定义函数
下面代码显示1个错误,0个警告,双击错误提示,会在错误的当行出现一个箭头标识:
原来是math.h前把<
写成(,在printf()后漏了分号;
。
在math.h中有一个求平方根的函数sqrt(x)用于求实数x的平方根,比如sqrt(1.21)的值等于1.1。
intmain(){return0;
}是代码中仅有的一个主函数,其实sqrt(),printf()都是函数,只是其他的非主函数一般都是在主函数中“调用”。
也就是说可以在主函数main(){}的外面自己定义一个函数如love(){},在花括号中写这个函数实现的功能,然后在main()函数中调用自己定义的love()函数,它就能实现其功能。
好比sqrt()就是定义在math.h库中的一个函数,然后在主函数main()中直接调用就可以求平方根,这里只需要调用名称,不用管怎么实现的,功能实现只写在定义函数的花括号{}内。
自定义函数主要有三个点,函数的入口,内部代码实现,出口(返回值的输出)。
—————————————
intAnd(inta,intb)
intc;
returnc;
上面是一个计算a+b的自定义函数And(),其中()里的inta,intb是入口,表示到时将会有两个int型的数进来,然后里面的代码是实现a+b,最后的return用来返回这个函数的结果值c,并且在And前面的int是规定这个返回值c的数据类型的。
因此,在主函数main()中可以这样用:
intd;
d=And(3,5);
printf(“%d”,d);
(ps:
运行时不接受任何中文输入法符号)
那么输出的d的值是多少呢?
由于3和5都是int型符合And()函数的“入口”,事实上3和5叫做实参(实际的参数),a和b叫做形参(形式上的参数),在调用这个函数之后,会把实参的值传递给形参,所以a=3,b=5。
计算之后得出c的值为8,这就是And()内部代码的实现,然后通过return提供int型的返回值c,所以最终整个And(3,5)的值就是8。
这样,就可以把实现某个功能的代码自定义为一个独立的函数,然后在主函数中调用,好处是可以多次调用,而且调用只需要写一次调用的函数名和写入实参,简便许多。
另外自定义函数的函数名可以自己随便起,但是不能使用中文等,只能是标识符,大小写有别,不能跟int,for这些关键字相同,标识符由字母,数字,下划线组合而成,不能以数字开头。
一般使用英语单词或简称比较好记。
下面用自定义函数实现a+b:
截图
自定义函数一般写在main函数后面或者放到其他地方,然后把定义函数的名称那一行照搬到main()函数的前面加个分号进行“声明”,声明之后的自定义函数才能在main()函数中合法被调用。
所以,自定义函数就这样,根据需要,自己设定返回值的类型,自己设定函数名,自己设定有多少个形参和各个形参的类型,函数里就像main()里一样实现各种功能,然后return后写上想返回的值,返回值可以是一个数字如10,可以是一个存在的变量如c,也可以是一个表达式如(2*c+a),以此返回值作为整个定义函数的结果。
把上一节求最大公约数的解法写成一个自定义函数,返回值类型是int,取函数名为gcd,入口有两个形参设为(intm,intn),所以
声明部分为:
intgcd(intm,intn);
//这里加分号
(定义过形参m,n后在函数内部就不用重复定义了,直接用,其他没有定义的如果需要必须定义。
定义函数为:
intgcd(intm,intn)//这里不能加分号
intc;
//这一句去掉,通过入口传递进形参m和n的值
c=m%n;
returnm;
主函数为:
intmain()//主函数
{
inta,b,d;
a,&
b);
d=gcd(a,b);
//调用定义的函数gcd()
%d\n"
d);
}
有兴趣可以写几个自定义函数:
分别求最大公约数,a+b,求1+2+3+……+n,然后在同一个主函数中调用它们。
自定义函数与递归:
递归,顾名思义就是传递过去,然后归来。
比如阶乘5!
,传递过去成为
5×
4!
,再传递过去成为5×
4×
3!
直到变成5×
3×
2×
1!
之后,再倒过来归回来,因为1是直接已知的,然后归来乘以2,再归来乘以3……递归的前提条件是下一步的形式跟原来的是一致的,比如n!
变成n×
(n-1)!
,(n-1)!
变成(n-1)×
(n-2)!
另外递归必须有个出口,不能无限的递下去却没有归回来,要有个终止点(具体的),比如阶乘最后的2×
1。
用知乎作者Memoria的话来说就是:
假设你在一个电影院,你想知道自己坐在哪一排,但是前面人很多,你懒得去数了,于是你问前一排的人「你坐在哪一排?
」,这样前面的人(代号A)回答你以后,你就知道自己在哪一排了,因为只要把A的答案加一,就是自己所在的排了。
不料A比你还懒,他也不想数,于是他也问他前面的人B「你坐在哪一排?
」,这样A可以用和你一模一样的步骤知道自己所在的排。
然后B也如法炮制。
直到他们这一串人问到了最前面的一排,第一排的人告诉问问题的人「我在第一排」。
最后大家就都知道自己在哪一排了。
就是这样,以同样的形式向前传递问题,到第一排有具体的答案后向后一层层返回答案。
这里的第一排就是递归的出口。
intDigui(inti)//求i的阶乘,返回值为i!
intm=0;
if(0==i)
return
(1);
m=i*Digui