c语言学习笔记
简单了解
重复是计算机最擅长的
计算机只懂16进的数字之类的语言(机器语言)
“需要告诉计算机一步一步的执行语法”
那怎么让计算机明白你想要的程序执行?
- 解释:用一个程序,那个程序能理解你的程序,然后按照你的要求执行
- 编译:用一个程序,就像一个翻译,把你的程序翻译成计算机能懂的语言(机器语言),然后机器语言写的程序就能直接执行了
为什么学习c语言?
- c语言在工业界占有重要地位,在很多领域无可替代
- 现代的编程语言语法差异不大,许多是C-LIKE的形式
简单了解c语言历史
- “it was the summer of 69”
- c语言是一种工业语言
编译软件使用:Dev C++
第一个c程序
#include <stdio.h>
int main()
{
printf("hello,world!\n");
return 0;
}
程序框架、printf、出错怎么办
程序框架(前面暂时不用深入了解,后面会慢慢理解)
- 框架也是程序集,不过相对普通程序集,框架是在应用上层更高级的封装。
- 封装了某领域内处理流程的控制逻辑
输出
- pritf(“Hello!world”);
- **""**里面的内容叫做“字符串”,printf会把其中的内容原封不动的输出
- \n表示需要在输出的结果后面换一行
程序出错怎么办
程序编写错误会怎么样?
-
编译器会显示错误
但不一定错误就在警告处,需要一点经验判断 -
不要用中文编写程序
如何让程序输出算术结果?
#include <stdio.h>
int main()
{
printf("12+34=%d",12+34);
return 0;
}
数学中的四则运算都可以
小练习
#include <stdio.h>
int main()
{
int price = 0;
printf("请输入金 (元):");
scanf("%d",&price);
int change = 100 - price;
printf("找你%d元\n",change);
return 0;
}
计算
变量
如何能在程序运行时输入数值,然后计算输出结果?
- 基本思路是:1、有地方放输入的数值。2、有办法输入数值。3、输入数值能参加计算
上面的小练习中
int price = 0;
//int类型 变量名是price 初始值是0
printf("请输入金 (元):");
scanf("%d",&price);
int change = 100 - price;
printf("找你%d元\n",change);
所以变量是一个保存数据的地方,当我们需要在程序中保存数据时,就需要一个变量用来保存它。变量保存数据之后,它才能参与到后面的计算中
- 定义变量:<类型名称><变量名称>
- 变量名字:“标识符”,了解“标识符”命名规范
- 赋值:“=”,注意是赋值,不是等于。此时的**=在计算机中是一种动作,但数学中的=**是一种关系
- 初始化:变量需要初始化,如果没有初始化呢?数值会变混乱。
变量初始化:<类型名称> <变量名称> = <初始值>
常量
固定不变的数值是常量
关键词-----const
const int NUM = 100;
这里的NUM是后面不能修改的。
浮点数
-
什么是浮点数?
属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。10.0就是浮点数 -
整数的运数只能是整数(10/8=1),计算机中10与10.0差别很大
那怎么进行浮点数运数?
%d 变为 %f
printf("%f",10.0/3);
return 0;
关键词–double
double foot;
小练习:double
printf("请输入身高的英尺英寸,"
"如输入的是5 7,表示的是5英尺7英寸");
double foot;
double inch;
scanf("%lf %lf",&foot,&inch) ;
printf("身高是%f米",((foot+inch/12)*0.3048));
return 0;
表达式
就如:num1 + num2 = nmu3;之类的
-
运算符:进行运算的动作,“±*/”等等
-
算子:参与运算的值,可能是一个参数有可能是变量。
-
算子和运算符组成表达式
-
取余计算:%
int hour1,minter1;
int hour2,minter2;
scanf("%d %d",&hour1,&minter1);
scanf("%d %d",&hour2,&minter2);
int t1 = hour1 * 60 + minter1 ;
int t2 = hour2 * 60 + minter2 ;
int T = t2 -t1 ;
printf("时间差距是%d小时%d分",T/60,T%60);
- 注意运算符优先级
赋值也是运算符,也有运算结果(就如 a=b=0,理解成a=(b=0))
避免==“嵌入式赋值”==,因为赋值符优先级很低,会发生错误!也不容易理解!
交换变量
- 怎么交换两个变量??
需要一个中间空白变量。
先将其中一个变量的数值放进中间空白变量。
然后另一个变量数值赋值给前一个。
然后中间空白变量赋值给后一个。
完成
a = 5
b = 10
t
t = a
a = b
b = t
int a = 5;
int b = 10;
int t;
t = a;
a = b;
b = t;
printf("a=%d b=%d",a,b);
小问题:a++和++a
a++是后面a,++a是前面a
int a = 10;
printf("a++=%d\n",a++);
printf("a=%d\n",a);//这里表达式的值是a原来的值
printf("++a=%d\n",++a);
printf("a=%d\n",a);//这里表达式的值是a+q以后的值
小练习
int a = 14;
int t1 = a++;
int t2 = ++a;
printf("%d %d",t1,t2);
//t1 t2等于多少
判断
关键词—if
int hour1,minter1;
int hour2,minter2;
scanf("%d %d",&hour1,&minter1);
scanf("%d %d",&hour2,&minter2);
int ih = hour2 - hour1;
int imin = minter2 - minter1;
if(imin < 0){
imin = 60 + imin;
ih --;
}
printf("时间差距是%d小时%d分\n",ih,imin);
if(这里是判断){
判断为turn,就执行{}里面的语法
}判断为false,就跳过if{}里面的语法
运算符 | 意义 |
---|---|
== | 相等 |
!= | 不相等 |
> | 大于 |
< | 小于 |
> = | 大于\相等 |
if属于bool类型,所以只要turn和false
判断运算符的优先级相对低,但比赋值运算符优先级高。
==和!=优先级相对其他判断运算符低。
小例子:找零计算器
int price = 0;
int bill = 0;
printf("需要(元)\n");
scanf("%d",&price);
printf("请给(元)\n");
scanf("%d",&bill);
if( bill>= price){
printf("应该找你:%d(元)\n",bill - price);
}
printf("你的钱不够\n");
如果是不进入if判断:
如果进入if判断:
这样的语言出现错误;那怎么做呢?
else
if-else
if(/*判断语法*/){
//turn时,执行的语法
}else{
//false时,执行的语法
}
找零计算器改进后:
int price = 0;
int bill = 0;
printf("需要(元)\n");
scanf("%d",&price);
printf("请给(元)\n");
scanf("%d",&bill);
if( bill>= price){
printf("应该找你:%d(元)\n",bill - price);
}else{
printf("你的钱不够\n");
}
if和else后面可以没有{}
计算工资
const double RATE = 8.25;
const int STANDRD = 40;
double pay = 0.0;
int hours;
printf("请输入工作小时数:");
scanf("%d",&hours);
printf("\n");
if(hours > STANDRD)
pay = STANDRD * RATE + (hours - STANDRD) * (RATE * 1.5);//需要;结束
else
pay = hours * RATE;//需要;结束
printf("应付工资:%f\n",pay);
不过不建议使用这种方式,因为加上{},能让代码逻辑性strong,而且不加上{}的话,if里面只能执行一个语法!
嵌套if
如果三个数值变量,怎么判断最大值?
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
int max =0;
if( a>b ){
if( a>c ){
max = a;
}else{
max = c;
}
}else{
if( b>c ){
max = b;
}else{
max = c;
}
}
printf("the max is %d\n",max);
嵌套if多次判断灵活性高,判断条件越来越丰富
if-else if级联
if(判断语法){
执行语法
}else if(判断语法){
执行语法
}else{
执行语法
}
类似于
if(判断语法){
执行语法
}else{
if(判断语法){
执行语法
}else{
if(判断语法){
执行语法
}else{
···
}
}
}
int x;
scanf("%d",&x);
int f = 0;
if( x<0 ){
f = -1;
}else if( x==0 ){
f=0;
}else{
f = 3*x;
}
printf("%d\n",f);
switch-case判断分支
问题:if-else if结构使用时,是“一步一步”往下执行判断,如果我的判断是前面的判断可以结束那还好,但如果我的判断是在后面的判断,那if-else if占用的资源会多一点。那有没有一种一步到位的语法结构?
补充点:我的理解是if-else if和switch-case都是一种**“同级判断”**
Switch-case判断分支
const int NUM = 3;
switch(控制表达式){
case 1:
执行语法1;
break;//break跳出switch-case判断
case 2:
执行语法2;
break;
case NUM:
执行语法3;
break;
default://default是没有相应的case时的执行
执行语法;
break;
···
}
小例子
int type;
scanf("%d",&type);
switch(type){
case 1:
printf("早上好");
break;
case 2:
printf("中午好");
break;
case 3:
printf("晚上好");
break;
case 4:
printf("你输入错误");
break;
}
这里输入3,就直接执行case 3的语法,不会执行case 1,2的判断语法,同样不会执行case 4的;
如果没有break,就会按顺序执行,直到遇到break。
case只是个入口
我的理解:case和case之间是在同一个内存里面,当switch创建一个内存时,case 1,case2等等都在这个switch创建的内存里,只不过case1在switch内存里占了一个地方,当这个地方没有break跳出switch时就会按顺序执行下一个case,直到遇到break跳出switch!!
循环
while
如果我想判断一个数值有几位数,怎么做?
用if:
思路,数值/10时,计算值++,最后输出n
int x;
int n = 0;
scanf("%d",&x);
n++;
x/=10;
if(x>0){
n++;
x/=10;
if(x>0){
n++;
x/=10;
if···
}
}
这样会发现很多if,很麻烦;怎么处理?
while语法
while(控制表达式){
循环体;
}
int x;
int n = 0;
scanf("%d",&x);
n++;
x/=10;
while(x>0){
n++;
x/=10;
}
printf("%d",n);
while只要满足控制表达式就会不断执行下去,所以注意不要写死循环
while(turn){
循环体;
}
同时注意循环体要有改变条件的机会,不然没有改变条件的话也是死循环
死循环会不断占用内存资源
不要写死循环
有时候if和while配合使用会让逻辑更加完美
do-while
我想先执行一次循环内的语法,然后再执行while,怎么做?
do-while语法结构
do{
循环体;
}while(控制表达式);
区别在于while是循环进去的时候判断,而do-while是循环出去的时候判断,也就是说无论怎样do-while都会执行一次,然后再来判断条件。
循环是相同,满足循环执行循环,不满足循环结束循环。
小练习:改进计数器
int x;
int n = 0;
scanf("%d",&x);
n++;
x/=10;
do{
x/=10;
n++;
}while(x>0);
printf("%d",n);
小练习
编程本身语言语法的学习不难,难的是编程的一种思维方式,和解决计算问题的编程想法和实现
1、log2的计算
int x;
int ret = 0;//保存最初的数值,因为x会在while中不断被修改
scanf("%d",&x);
int t = x;
while( x>1 ){
x/=2;
ret ++;
}
printf("log2 of %d is %d",t,ret);
问题是:为什么“ret”初始值是0?为什么用while能不能用do-while?这样才能想到利用log数学机制来写出这样逻辑的代码?代码中的各个变量都会有一点点的联系,怎么将这种联系“理想化”?等等编程问题。。。
看问题的方向有很多,自然解决问题的方式也有很多,解决编程问题不是只要一个答案
2、计数循环
int count = 100;
while( count >= 0){
count--;
printf("%d",count);
}
printf("发射");
问题是这个循环需要执行几次?
循环结束后,有没有输出最后的0?
原代码一个一个计算,算100个?显然不合理。那怎么处理?
count的值设计成一个小的数,“以小放大”。
int count = 3;
while(count>=0){
count--;
printf("%d\n",count);
}
printf("发送\n");
3、随机数字游戏
计算机随机一个数,用户去写,写大了就输出大,小也一样,直到输出相同结束
随机数生成:srand、rand
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(time(0));
int a = rand();
printf("%d\n",a%100);
return 0;
}
#include <stdlib.h>
#include <time.h>
int main()
{ srand(time(0));
int number = rand()%100+1;
int count = 0;
int a = 0;
printf("计算机已经随机好一个数。\n");
do{
printf("请写出你的答案:(1~100)\n");
scanf("%d",&a);
count++;
if(a>number){
printf("你写的数大了\n");
}else if(a<number){
printf("你写的数小了\n");
}
}while(a!=number);
printf("nb,你用了%d次就写对了答案。",count);
return 0;
}
4、算平均数游戏
int number;
int sum =0;
int count =0;
scanf("%d",&number);
while(number!=-1){
sum+=number;
count++;
scanf("%d",&number);
}
printf("%f\n",1.0*sum/count);
循环控制
for循环
for(最初的条件;循环判断条件;每次的操作){
}
我想写一个数,然后让计算机结束n!。是n!。
用while做
int n;
scanf("%d",&n);
int fact =1;
int i =1;
while(i<=n){
fact *=i;
i++;
}
printf("%d!=%d\n",n,fact);
用for做
int n;
scanf("%d",&n);
int fact =1;
int i =1;
for(i=1;i<=n;i++){
fact*=i;
}
printf("%d!=%d\n",n,fact);
for循环是在循环开始时进行判断的,和while一样
for==while
小总结
三种循环什么时候用?
1、如果有固定次数,用for。
2、如果必须执行一次,用do-while。
3、其他情况,都用while
break和continue控制循环
例子:素数(只能被1和自己整除的数,不包括1)
int x;
scanf("%d",&x);
int i;
int isPrime =1;
for( i =2;i<x;i++ ){
if( x%i==0 ){
isPrime = 0;
}
}
if(isPrime==1){
printf("是素数\n");
}else{
printf("不是素数\n");
}
问题是
但是for循环要的i<x条件不成立才结束循环,如果我的结果只需要判断一次,怎么处理?
跳出循环!
break和continue
break:跳出循环
continue:跳过这一次循环,剩下的语法进入下一轮。
break:
for( i =2;i<x;i++ ){
if( x%i==0 ){
isPrime = 0;
break;
}
printf("第几次输出");
/*
当第n次输出,进入if并执行break,
那就第N次不会输出并跳出for,就算for还能执行
*/
}
continue:
for( i =2;i<x;i++ ){
if( x%i==0 ){
isPrime = 0;
contiune;
}
printf("第几次输出");
/*
当第n次输出,进入if并执行contiune,
那就第N+1次会输出,这是跳过第n次,不跳出for
*/
}
注意点:
C语言break 只能用于这两种情况,break 语句只用于循环语句和 switch 语句!!
嵌套循环
怎么输出100以内的素数?
外面加上for
int x;
printf("100以内的素数:\n");
for(x=2;x<=100;x++){
int i;
int isPrime =1;
for( i =2;i<x;i++ ){
if( x%i==0 ){
isPrime = 0;
break;
}
}
if(isPrime==1){
printf("%d\n",x);
}
}
输出前50个素数
int x;
int cut = 0;
printf("前50个的素数:\n");
x=1;
while(cut<50){
int i;
int isPrime =1;
for( i =2;i<x;i++ ){
if( x%i==0 ){
isPrime = 0;
break;
}
}
if(isPrime==1){
cut++;
printf("%d\t",x);//\t是对齐
if(cut%5==0){
printf("\n");
}
}
x++;
}
如何用1元、2元、5元去整合10元?
int x;
int one,two,five;
scanf("%d",&x);
for(one=1;one<x*10;one++){
for(two=1;two<x*10/2;two++){
for(five=1;five<x*10/5;five++){
if(one+two*2+five*5==x*10){
printf("可以用%d个1元加%d个2元加%d个5元得到%d0元\n",one,two,five,x);
}
}
}
}
问题补充点:
嵌套想跳出循环需要多个break和continue,因为break和continue只对应相应的一层循环,并不会影响其他循环,那多个break和continue编写麻烦,有其他的语法吗?
goto
goto
for(···){
for(···){
for(···){
···
goto out;
}
}
}
out;//就跳到