Day3 C语言基础语法学习-2
- 一、输入输出函数
-
- 1.1 getchar()/putcgar()
-
- 1.1.1getchar()
- 1.1.2 putchar
- 1.2 gets()/puts()
-
- 1.2.1 gets()
- 1.2.2 puts()
- 3.3 printf()/scanf()
-
- 3.3.1 printf()
- 3.3.2 scanf()
- 3.3.3 scanf附加字符
- 3.3.4 scanf输入多个内容以及垃圾字符的处理
- 二、控制语句
-
- 2.1 概念
- 2.2 if...else语句
-
- 2.2.1 if语句的形式
- 2.2.2 练习:大小写转换
- 2.3 swich...case语句
-
- 2.3.1格式
- 2.3.2注意事项
- 作业1:两个数运算
- 作业2:编写程序计算身高
- 作业3:输入一个日期,输出当前日期是这一年的第几天
- 三、循环语句
-
- 3.1 while循环
-
- 3.1.1 格式
- 3.1.2 循环的简单使用
- 3.1.3 do..while..使用
- 3.2 for循环
-
- 3.2.1 格式
- 3.2.2 for循环的注意事项
- 3.2.3 for循环的使用
- 3.2.4 打印100-1000以内的所有的水仙花数
- 四、辅助控制关键词
-
- 4.1 goto
- 4.2 break;
- 4.3 continue
- 4.4 return
- 约瑟夫环问题之报到3的退出
- 五、数组
-
- 5.1 数组的概念
- 5.2 一维数组
-
- 5.2.1 一维数组的定义
- 5.2.2 一维数组的性质
一、输入输出函数
1.1 getchar()/putcgar()
1.1.1getchar()
头文件:#include <stdio.h>
原型:int getchar(void);
功能:从终端读取一个字符
参数:无
返回值:从终端读取到的字符
#include <stdio.h>
int main(int argc, const char *argv[])
{/*int ch;ch = getchar();printf("ch = %c %d\n",ch,ch);
*/int a,b,c;a = getchar();b = getchar();c = getchar();printf("a = %c %d\n",a,a);printf("b = %c %d\n",b,b);printf("c = %c %d\n",c,c);return 0;
}
1.1.2 putchar
头文件:#include <stdio.h>
原型:int putchar(int c);
功能:向终端输出一个字符
参数:c:要输出的字符
返回值:输出的字符
#include <stdio.h>int main(int argc, const char *argv[])
{//参数为一个字符putchar('w');putchar('\n');//参数为一个asciiputchar(97);putchar(10);int a = 'h';int b = 10;putchar(a);putchar(b);return 0;
}
1.2 gets()/puts()
1.2.1 gets()
头文件:#include <stdio.h>
原型:char *gets(char *s);
功能:从终端读取一个字符串
参数:s:保存读取的数据的内容,一般是一个数组,char buf[32]
返回值:保存的字符串
#include <stdio.h>int main(int argc, const char *argv[])
{char str[32] = {0};gets(str);printf("str = %s\n",str);return 0;
}
1.2.2 puts()
头文件:#include <stdio.h>
原型:int puts(const char *s);
功能:向终端输出一个字符串
参数:s:要输出的内容
返回值:输出的字符串的字节数
#include <stdio.h>int main(int argc, const char *argv[])
{//puts函数自带换行功能puts("hellworld");char s[32] = "helloworld";puts(s);char buf[32] = {0};gets(buf);puts(buf);return 0;
}
3.3 printf()/scanf()
3.3.1 printf()
printf函数是一个行缓冲函数(1024K),先将内容写到缓冲区,满足一定条件后,才会将内容写入对应的文件或者流中。
printf函数将内容写到缓冲区的条件:
1.缓冲区满
2.写入的字符中有‘\n’,’\r’
3.调用fflush或stdout手动刷新缓冲区
4.调用scanf等要从缓冲区读取数据时,也会将缓冲区内的数据刷新
5.程序结束时
头文件:#include <stdio.h>
原型:int printf(const char *format, …);
功能:向终端按照格式输出字符串
参数:format:带格式要输出的内容
普通字符:原样输出
例如:printf(“hello world!\n”);
格式说明: %[修饰符]格式字符,用于指定格式输出
例如:printf(“a = %d\n”,a);
%d: 32位有符号十进制数
%u: 32位无符号十进制
%o: 八进制
%x: 十六进制
%e: 指数形式
%c: 字符
%s: 字符串
%%:输出%本身
%p: 输出地址
附加格式字符:
#: 用于输出八进制或者十六进制的前导符
l: 用于输出long类型或者double类型的数据
m: 设置输出内容的宽度
【注意:如果数据的宽度大于等于m,则没有影响;
如果数据的宽度小于m,则默认右对齐,左边的位置补空格。】
0:当设置宽度后,默认右对齐,左边空格的位置补0
-:将右对齐改成左对齐
.n:保留小数点后n位
arg:可变参,可以有,也可以没有,也可以有多个
返回值:输出的字节个数
#include <stdio.h>
int main(int argc, const char *argv[])
{int num = 256;printf("%d%d%d\n",num,num,num);//5:将输出的宽度设置为5printf("%5d%5d%5d\n",num,num,num);//0:右对齐左边补0 printf("%05d%05d%05d\n",num,num,num);//-:右对齐改成左对齐 printf("%-5d%-5d%-5d\n",num,num,num);//:0不能用于左对齐 printf("%-05d%-05d%-05d\n",num,num,num);float f = 45.45678912345;printf("f = %f\n",f);//.2:保留小数点后2位,并且会四舍五入printf("f = %6.3f\n",f);printf("f = %p\n",&f);return 0;
}
3.3.2 scanf()
头文件:#include <stdio.h>
原型: int scanf(const char *format, …);
功能:按照格式从终端输入指定的内容
参数:format:含有格式的字符的内容
格式字符:
%d 整形数据
%f 浮点型数据
%c 字符数据
%s 字符串数据
。。。
返回值:成功保存的内容的个数
#include <stdio.h>int main(int argc, const char *argv[])
{/*int num;int ret = scanf("%d",&num);printf("ret = %d,num = %d\n",ret,num);*//*char ch;scanf("%c",&ch);printf("ch = %c %d\n",ch,ch);*//*char buf[32] = {0};//scanf默认只能保存一个不带空格的字符串scanf("%s",buf);//找到换行符才结束输入scanf("%[^\n]",buf);printf("buf = %s\n",buf);*//*int num;scanf("[%d]",&num);printf("num = %d\n",num);*/int a,b,c;scanf("%d,%d,%d",&a,&b,&c);printf("a = %d,b = %d,c = %d\n",a,b,c);return 0;
}
3.3.3 scanf附加字符
m:设置输入的宽度,如果输入的内容超过设置的宽度,只会保存设置宽度的内容
:抑制符,当带有的格式的字符输入的内容不会保存到与之对应的变量中,而是将下一个不带 * 的格式的字符的内容保存在之前的变量中
#include <stdio.h>
int main(int argc, const char *argv[])
{/*int year,month,day;scanf("%2d%2d%2d",&year,&month,&day);printf("%d/%d/%d\n",year,month,day);char buf[32] = {0};scanf("%5s",buf);printf("buf = %s\n",buf);*/int a,b,c;scanf("%d %*d %d %*d %d",&a,&b,&c);printf("a = %d,b = %d,c = %d\n",a,b,c);return 0;
}
3.3.4 scanf输入多个内容以及垃圾字符的处理
#include <stdio.h>
int main(int argc, const char *argv[])
{
#if 0int a,b,c;scanf("%d %d %d",&a,&b,&c);printf("a = %d,b = %d,c = %d\n",a,b,c);
#endif
#if 0char a,b,c;scanf("%c%c%c",&a,&b,&c);printf("a = %c,b = %c,c = %c\n",a,b,c);
#endif/* 一个scanf处理垃圾字符 *///方法1:使用抑制符
/* char a,b,c;scanf("%c%*c%c%*c%c",&a,&b,&c);printf("a = %c,b = %c,c = %c\n",a,b,c);*///方法2:使用空格隔开/*char a,b,c;scanf("%c %c %c",&a,&b,&c);printf("a = %c,b = %c,c = %c\n",a,b,c);*//*多个scanf处理垃圾字符*/int id;char name[32];char sex;int score;char bg;/*printf("请输入学号:");scanf("%d",&id);printf("请输入姓名:");scanf("%s",name);printf("请输入性别:");scanf("%c",&sex);printf("请输入分数:");scanf("%d",&score);printf("请输入年龄:");scanf("%d",&age);*/#if 0//使用抑制符printf("请输入学号:");scanf("%d",&id);printf("请输入姓名:");scanf("%s",name);printf("请输入性别:");scanf("%*c%c",&sex);printf("请输入分数:");scanf("%d",&score);printf("请输入是否有女朋友:");scanf("%*c%c",&bg);
#endif#if 0 //使用getcharprintf("请输入学号:");scanf("%d",&id);printf("请输入姓名:");scanf("%s",name);//使用getchar()获取了在输入完姓名之后的回车//从而防止在回车时程序直接跳过 “请输入性别:” 这个过程getchar(); printf("请输入性别:");scanf("%c",&sex);printf("请输入分数:");scanf("%d",&score);getchar();printf("请输入是否有女朋友:");scanf("%c",&bg);
#endif// 使用空格printf("请输入学号:");scanf("%d",&id);printf("请输入姓名:");scanf("%s",name);printf("请输入性别:");scanf(" %c",&sex); //在%c的前面有一个空格符printf("请输入分数:");scanf("%d",&score);printf("请输入是否有女朋友:");scanf(" %c",&bg);return 0;
}
二、控制语句
2.1 概念
控制语句主要解决一些代码需要执行,一些代码不执行,或者相同的代码要执行很多次。
分类:
1)分支语句:
if…esle
switch…case…
2)循环语句:
goto
while
do…while…
for
3)辅助控制关键字:
goto
break
continue
return
2.2 if…else语句
2.2.1 if语句的形式
形式1:
if(表达式)
{语句块
}
形式2:
if(表达式)
{语句块1
}
else
{语句块2
}
形式3:
if(表达式1)
{语句块1}
else if(表达式2)
{语句块2}
else
{语句块3}
注意事项:
1.if的表达式非0即为真:
if(0) //假
if(1) //真
if(0.00000001) //真
if(a)---->if(a != 0) //a不等于0时,a为真
if(!a) ---->if(a == 0) //a等于0时,不等于a为真
if(a = 0) //假
if(a = 1) //真
2.if或者else语句后面只有一条代码,可以不加{},但是一般为了不产生歧义,最好加上;
3.else 后面不能跟表达式;
if和else只能执行一条;
else不能单独使用,而且else默认和与之最近的一个if关联。
if(表达式1){if(表达式2){ }}
2.2.2 练习:大小写转换
在终端输入一个字符,如果是大写字母,将其转化为小写字母,如果是小写字母,将其转化为大写字母,并输入,如果是字符数字,将其转化为数字输出。
‘h’---->‘H’
‘H’---->‘h’
‘6’----->6
答案:
#include <stdio.h>
int main(int argc, const char *argv[])
{printf("请输入一个字符:\n");char ch;scanf("%c",&ch);//if(ch >= 97 && ch <= 122)if(ch >= 'a' && ch <= 'z'){ch -=32;printf("ch = %c\n",ch);}else if(ch >= 'A' && ch <= 'Z'){ch += 32;printf("ch = %c\n",ch);}else if(ch >= '0' && ch <= '9'){ch -=48;printf("ch = %d\n",ch);}else{printf("输入有误,退出程序!\n");}return 0;
}
2.3 swich…case语句
switch语句和if语句一样,也是分支语句,只不过switch语句用于条件过多的情况下使用
2.3.1格式
switch(变量或者变量表达式)
{case 常量或者常量表达式1:语句块1;break;case 常量或者常量表达式2:语句块2;break;case 常量或者常量表达式3:语句块3;break; case 常量或者常量表达式4:语句块4;break; defalut:语句块n;break;
}
eg:
#include <stdio.h>int main(int argc, const char *argv[])
{int num;printf("***1.注册 2.登录 3.退出***\n");printf(">>>> ");scanf("%d",&num);switch(num){case 1:printf("正在执行注册操作\n");break;case 2:printf("正在执行登录操作\n");break;case 3:printf("正在退出,请稍等..\n");break;default:printf("您输入有误,请重新输入\n");break;}return 0;
}
2.3.2注意事项
switch后面的表达式是一个变量或者变量表达式;
case只能是一个常量或者常量表达式,而且这个表达式不能是范围,每个常量表达式的值必须各不相同,否则将出现矛盾;
case后面如果有多条语句,不用加{};
switch语句中只能判断整形数据和字符型数据,不能是浮点型或者字符串;
default后面可以不加break;
break主要是为了结束switch语句,如果不加,从指定case语句之后一直向下执行所有语句块,直到遇到break为止。
作业1:两个数运算
输入两个数,再输入运算符(加减乘除),实现两个数字之间的运算
作业2:编写程序计算身高
每个做父母的都关心自己孩子成人后的身高,据有关生理卫生知识与数理统计分析表明,
影响小孩成人后身高的因素有遗传、饮食习惯与坚持体育锻炼等。小孩成人后身高与其父
? 母身高和自身性别密切相关。
? 设faHeight为其父身高,moHeight为其母身高,
身高预测公式为:
? 男性成人时身高 = (faHeight + moHeight) * 0.54(cm)
? 女性成人时身高 = (faHeight * 0.923 + moHeight) / 2(cm)
? 此外,如果喜爱体育锻炼,那么可增加身高2%
? 如果有良好的卫生饮食习惯,那么可增加身高1.5%
程序要求:父亲的身高与母亲的身高、小孩的性别、是否喜爱体育锻炼和是否有良好的卫生
? 饮食习惯也从键盘上输入,最终输出预测的身高。 提示:小孩性别的输入方式,可在屏幕
? 给出提示“请输入小孩的性别(男孩输入M,女孩输入F):”,然后通过if语句来判断从键盘
? 输入的字符是M还是F。是否喜爱体育锻炼也可以通过类似的方式实现。
作业3:输入一个日期,输出当前日期是这一年的第几天
2021年1月10日是2021年的第10天
2021年2月10日是2021年的第31+10=41天
2021年3月10日是2021年的第31+28+10=69天
闰年和平年2月份的天数不一样
每一月的天数都有区别
输入的年月日也得满足实际情况
不满足条件,可以使用return -1;结束整个程序
三、循环语句
我们在写代码中,往往会出现有些代码可能会执行很多次的情况,那么为了简便书写,可以通过循环来实现,这样可读性,逻辑性都会更好。
3.1 while循环
3.1.1 格式
while(表达式)
{语句块
}
注意事项:循环条件不能永远为真,必须要有循环结束的条件,如果永远循环,将其称之为死循环。
例如:while(1);
3.1.2 循环的简单使用
#include <stdio.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{/*while(1){printf("helloworld\n");sleep(1);}*/int i = 5;while(i--){printf("helloworld\n");}//程序员40W,房价200W,10%,如果不涨工资的情况下,不贷款,问多少年可以买房?int year = 0,sum = 0,price = 200;while(1){year++;sum += 40;price += price*0.1;if(sum >= price){printf("第%d年买房\n",year);break;}printf("第%d年买不起房\n",year);}return 0;
}
3.1.3 do…while…使用
#include <stdio.h>int main(int argc, char *argv[])
{//do..while循环会先执行一次,然后再判断,所以不管表达式是否为假,都会先执行一次do{printf("hello world!\n");}while(0);return 0;
}
3.2 for循环
3.2.1 格式
for(表达式1;表达式2;表达式3)
{语句块;
}
执行顺序:先执行表达式1,执行完毕后执行表达式2,如果表达式2为真,则执行语句块,执行完语句块后,接着执行表达式3,然后再执行表达式2,如果表达式2为真,则执行语句块,以此类推,直到表达式2为假时,循环结束
【注意:for循环和while循环是通用的】
int i = 0;
while(i < 10)
{i++;
}
for(i = 0; i < 10;i++)
{
...
}
3.2.2 for循环的注意事项
for(表达式1;表达式2;表达式3)
{语句块
}
1.表达式1:主要对要计数的变量赋初值,整个循环只执行一次,也可以省略不写;
2.不管省略哪个表达式,分号不能丢;
3.表达式2主要就是判断条件,条件为真执行语句块,条件为假循环结束,如果省略表达式2不写,会造成死循环;
eg:for(i = 0 ;;i++)
4.表达式3就是为了改变计数变量的值从而影响循环的次数,如果省略表达式3不写,会造成死循环,当然可以把表达式三放在语句块中也是可以的
死循环:for( ; ; );
3.2.3 for循环的使用
#include <stdio.h>
int main(int argc, const char *argv[])
{int i;/*for(i = 0,printf("i = %d\n",i);i < 5,printf("i = %d\n",i);i++,printf("i = %d\n",i)){printf("hello world!\n");}*/int j;for(j = 0 ;j < 3;j++){for(i = 0 ; i < 5;i++){if(1 == i){continue; //结束本次循环,继续下一次循环// break; //结束这一层循环}printf("hello world! %d\n",i);}printf("hello nanjing\n");}return 0;
}
3.2.4 打印100-1000以内的所有的水仙花数
水仙花数:是指一个三位数的每一位的立方和等于这个数,则这个数称之为水仙花数
num = 个位的立方+十位的立方+百位数的立方
示例:
#include <stdio.h>
int main(int argc, const char *argv[])
{int num,ge,shi,bai;int sum;for(num = 100; num < 1000;num++){ge = num %10;shi = num %100 /10;bai = num /100;sum = ge*ge*ge + shi*shi*shi + bai*bai*bai;if(sum == num){printf("%d\n",num);}}return 0;
}
四、辅助控制关键词
4.1 goto
goto主要用于在一个函数内进行跳转,可以跳转到当前函数的任意位置
注意:不建议过多使用,可读性,逻辑性会变差
#include <stdio.h>
int main(int argc, const char *argv[])
{
#if 0int num = 100;printf("111111111111111111111111\n");goto NEXT;printf("hello world!\n");num = 888;printf("hello nanjing");
NEXT:printf("hello beijing\n");printf("num = %d\n",num);printf("222222222222222222222222222");
#endifint i = 0;
TEMP:printf("hello world\n");i++;if(i <= 9){goto TEMP;}return 0;
}
4.2 break;
break在switch语句中主要用于结束指定的语句块
break主要在循环语句中使用,功能是结束本次循环
【注意:break除了在switch语句中以外,其它地方只能在循环中使用。】
4.3 continue
continue只能在循环中使用,表示退出本次循环,下次循环接着运行。
4.4 return
#include <stdio.h>int main(int argc, const char *argv[])
{int i;for(i = 1;i <= 10;i++){if(i == 5){return i;}printf("i = %d\n",i);}printf("hello world!\n");return 0;
}
约瑟夫环问题之报到3的退出
#include <stdio.h>
int main(int argc, const char *argv[])
{int num,k = 0;printf("请输入人数:\n");scanf("%d",&num);int person = num;int i =0;int flag[1000] = {0};while(person != 1){i++;if(flag[i] == 0){k++;}if(k == 3){k = 0;flag[i] = 1;person--;}if(i == num){i = 0;}}for(i = 1; i <= num;i++){if(flag[i] == 0){printf("the last one is %d\n",i);}}return 0;
}
五、数组
5.1 数组的概念
数组:
保存一组相同类型的数据;
不管是几维数组,都是开辟一段连续的内存空间;
数组是一种构造数据类型(数组,结构体,共用体)。
5.2 一维数组
5.2.1 一维数组的定义
<存储类型> <数据类型> <数组名> [数组下标]
存储类型:auto,register,static,extern
数据类型:基本数据类型:int,char,float…等
数组名:是一个标识符,满足标识符的命名规则
数组下标:确定数组张元素的个数
例如:
int a[10];
含义:定义一个名为a的数组,一共10个元素,每个元素都是int类型。
5.2.2 一维数组的性质
#include <stdio.h>int main(int argc, const char *argv[])
{int a[4];a[0] = 222;a[1] = 333;a[2] = 444;a[3] = 555;printf("%d %d %d\n",a[0],a[1],a[2]);//数组在定义和使用的时候,数组下表尽量不要使用变量//防止后期变量改变会影响对数组的操作,一般数组下标//都是常量或者常量表单大师,宏定义本身也是一个常量表达式,//所以可以当做数组下标使用
#if 0int num = 10;int b[num];b[2] = 5;int n =3;b[n] = 888;printf("%d %d\n",b[2],b[n]);#endifprintf("sizeof(a) = %ld %ld\n",sizeof(a),sizeof(int)*4);printf("%p\n",&a[0]);printf("%p\n",&a[0]+1);printf("%p\n",a);printf("%p\n",a+1);printf("%p\n",&a);printf("%p\n",&a+1);a++; //数组名是常指针,不能修改return 0;
}