一、基础练习
练习1:输入两个数,实现两个数的交换
法1:三杯水交换(常规的方式)
#include int main(int argc, const char *argv[]){int a = 0;int b = 0;int temp = 0; //定义一个临时变量printf("输入两个数字:");scanf("%d%d",&a,&b); //1020temp = a;a = b;b = temp;printf("a = %d, b = %d\n", a, b);//2010return 0;}
法2:如何不使用额外的内存空间,实现两个交换(没有空杯子了)
三次异或实现交换 (异或:不同为1,相同为0 )
#include int main(int argc, const char *argv[]){int a = 0;int b = 0;printf("请输入两个数字:");scanf("%d%d",&a,&b); //10 20--> 二进制分别为 a: 0000 1010 b: 0001 0100 a = a ^ b; a: 0000 1010b: 0001 0100 a= 0001 1110<--现在的a被赋值成这个值b = a ^ b; a: 0001 1110 b: 0001 0100 b= 0000 1010<--现在的b被赋值成这个值 a = a ^ b; a: 0001 1110b: 0000 1010a= 0001 0100 <--现在的a被赋值成这个值printf("a = %d b = %d\n", a, b); //20 10 return 0;}
练习2:改变灯的状态
灯的编号顺序 8 7 6 5 4 3 2 1,进行如下操作。
1. 有8个led灯,分别在8个不同的教室
2. 8个灯初始状态未知
3. 点亮第 1 3 5 7 号灯
4. 把5号灯熄灭
5. 把4号灯点亮
6. 把除了4号灯的其他灯全熄灭
#include int main(int argc, const char *argv[]){ unsigned char led = 0; //使用无符号char(1个字节= 8bit)类型来表示八个灯的状态//点亮第1 3 5 7号灯led = led | 0x55;//这样不会影响2 4 6 8 原有的状态 //若直接赋值,把1 3 5 7 点亮的同时,把其他灯熄灭了//把5号灯熄灭led = led & ~(1<<4);printf("led = %#x\n", led);//0x55//把4号灯点亮led = led | (1<<3);printf("led = %#x\n", led);//0x4d//把除了4号灯的其他灯全熄灭led = led & (1<<3);printf("led = %#x\n", led);//0x08 return 0;}
二、分支控制语句练习题:if..else 语句
练习3:从终端输入一个字符:
如果是大写的 转换成小写,如果是小写的 转换成大写,如果是 0-9 按照 %d 输出对应整型的 0-9,其他字符 转换成 #,并输出
#include int main(int argc, const char *argv[]){printf("请输入一个字符:"); //法1:输入字符方式char ch = getchar(); //getchar 表示在终端获取一个字符getchar(); //清理垃圾字符 回车//法2:输入字符方式char ch = 0;scanf("%c",&ch);if(ch >='A' && ch ='a' && ch = '0' &&ch <= '9'){ch = ch - '0';printf("%d\n",ch); }else{ch = '#';printf("%c\n",ch); } return 0;}
练习4:输入一个年份 判断是平年还是闰年。
(闰年: 能被4整除且不能被100整除 或者能被400整除)提示:整除: 没有余数 year%4==0
2000 闰年、2004 闰年、2022 平年、1900 平年
#include int main(int argc, const char *argv[]){int year = 0;printf("输入一个年份:");scanf("%d",&year);if(year%4 == 0 && year%100 != 0 || year%400 == 0){printf("闰年\n");}else{printf("平年\n");}return 0;}
练习5:输入三角形的三边长,判断能否构成三角形
如果能,输出是什么三角形(等边、等腰、直角、普通)。如果不能,输出不能
#include int main(int argc, const char *argv[]){int a = 0, b = 0, c = 0;printf("请输入三角形的三边长:");scanf("%d%d%d",&a,&b,&c);if( a+b>c && b+c>a && a+c>b){ //构成三角形:任意两边大于第三边printf("能构成三角形\n");if(a == b && b == c && a==c){printf("等边三角形\n");}else if(a==b || b==c || a==c){printf("等腰三角形\n");}else if(a*a + b*b == c*c ||a*a + c*c == b*b || a*a + c*c == b*b ){//上面判断不能用a^2 + b^2 = c^2 ,在c语言中"^" 是异或 printf("直角三角形\n");}else{printf("普通三角形\n");}}else{printf("不能构成三角形\n");} return 0;}
练习6:求孩子身高
每个做父母的都关心自己孩子成人后的身高,据有关生理卫生知识与数理统计分析表明,影响小孩成人后身高的因素有遗传、饮食习惯与坚持体育锻炼等。小孩成人后身高与其父母身高和自身性别密切相关。父亲、母亲、孩子 身高都用double,设faHeight为其父身高,moHeight为其母身高,基础身高预测公式为:
男性成人时身高 = (faHeight + moHeight) * 0.54(cm)
女性成人时身高 = (faHeight * 0.923 + moHeight) / 2(cm)
此外,如果喜爱体育锻炼,那么可在基础身高上增加身高 2%
如果有良好的卫生饮食习惯,那么可在基础身高上增加身高1.5%
程序要求:父亲的身高与母亲的身高、小孩的性别、是否喜爱体育锻炼和是否有良好的卫生饮食习惯也从键盘上输入,最终输出预测的身高。
提示:
小孩性别的输入方式,可在屏幕给出提示“请输入小孩的性别(男孩输入1,女孩输 0):”,
然后通过if语句来判断从键盘输入的字符是 1 还是 0。是否喜爱体育锻炼也可以通过类似的方式实现。
测试:
180 160 男 体 习 —>190.026 %.3f
#include int main(int argc, const char *argv[]){double faHeight = 0;double moHeight = 0;double childHeight = 0;double dpe = 0; //体育增量double dfood = 0; //习惯增量int sex = 0; //1 男 0 女int pe = 0;//1 喜欢 0 不喜欢int food = 0;//1 喜欢 0 不喜欢printf("请输入父亲的身高与母亲的身高:");scanf("%lf%lf", &faHeight, &moHeight);printf("请输入孩子的性别(1 男, 0 女):");scanf("%d",&sex);printf("是否喜爱体育锻炼(1 喜爱, 0 不喜爱):");scanf("%d",&pe);printf("是否有良好的卫生饮食习惯(1 有, 0 没有):");scanf("%d",&food);if(sex == 1){childHeight = (faHeight + moHeight) * 0.54;}else if(sex = 0){childHeight = (faHeight*0.923 + moHeight) / 2;}if(pe == 1){dpe = childHeight *0.02;//若pe = 0时,表示 dpe 还为初始值0}if(food == 1){ //若food = 0时,表示 dfood 还为初始值0dfood = childHeight *0.015;}childHeight = childHeight + dpe + dfood; printf("%.3f\n",childHeight);return 0;}
三、switch..case 语句练习题
练习7:实现一个简易的计算器功能
只能操作一个运算符即可 (+ – * / %)。输入表达式 输出结果
如: 5+4 = 9 3*4= 12 10%4 = 2
#include int main(int argc, const char *argv[]){int a = 0;int b = 0;char operator = 0;printf("请输入:");scanf("%d %c%d", &a, &operator, &b);//在%c前加一个空格,表示清理垃圾字符。若不加必须输入如:a+b 不能带空格switch(operator){case '+':printf("%d + %d = %d\n", a, b, a+b);break;case '-':printf("%d - %d = %d\n", a, b, a-b);break;case '*':printf("%d * %d = %d\n", a, b, a*b);break;case '/':printf("%d / %d = %f\n", a, b, (float)a/(float)b);//因为a和b本身是int类型 计算的结果会舍弃小数位,所以要转换成float参与运算break;case '%':printf("%d %% %d = %d\n", a, b, a%b); //要想打印 % 必须输入 %% 才行break;} return 0;}
练习8:学生成绩管理
输入一个学生的成绩,[90,100] A 、[80,90) B 、[70,80) C 、[60,70) D 、[0,60) 不及格 、其他 输入错误。使用switch..case 语句实现
#include int main(int argc, const char *argv[]){ int ret = 0;int score = 0;printf("输入一个学生的成绩:");ret = scanf("%d",&score); //scanf函数执行成功返回值是 按指定格式输入变量的个数//scanf函数未按照格式输入时,数据并没有存到变量中,此时返回值为0,即ret = 0。//在本代码中若按int格式输入则return 1,未按格式输入则return 0//输入'+'或其他非数字时,若不进行if语句的判断,则直接执行case 0:输出不及格 getchar(); //清理下垃圾字符if(ret==1){switch(score / 10){case 10: //利用case击穿原则case 9:printf("A\n");break;case 8:printf("B\n");break;case 7:printf("C\n");break;case 6:printf("D\n");break;default:printf("不及格\n");break;}}else{ printf("输入错误\n");} return 0;}
四、使用goto实现循环
练习9:使用goto计算 1+2+3+…+99+100 的和。
#include int main(int argc, const char *argv[]){int sum = 0; //sum必须初始化为0,否则随机值会影响计算的结果int i = 1; //用来控制循环次数的变量LOOP: sum += i;i++;if(i <= 100){goto LOOP; //goto XX; XX可以为其他的,上面跟这个相同即可。} printf("%d\n", sum);return 0;}
五、while 循环
练习10:使用while循环 计算 1~100 的和
#include int main(int argc, const char *argv[]){int sum = 0; //sum必须初始化为0,否则随机值会影响计算的结果int i = 1; //用来控制循环次数的变量while(i <= 100){sum += i;i++;}printf("%d\n", sum);return 0;}
练习11、猴子吃桃问题
一个猴子第一天摘了若干个桃,当即就吃了一半数量的桃,没吃过瘾,又多吃了一个,第二天,将剩下的桃又吃了一半数量,没吃过瘾,又多吃了一个,以后的每一天都吃一半数量多一个,到第十天再想吃桃的时候,发现只剩一个桃了。问:猴子第一天摘了多少个桃。
用while循环实现。把每天吃之前的桃子数量 都打印出来 应该怎么做?
#include int main(int argc, const char *argv[]){int num = 1; //第十天剩一个int i = 0; //循环变量 控制循环次数while(i < 9){printf("猴子第%d天有%d个桃\n",10-i,num);num = (num+1)*2;i++;}printf("猴子第一天有%d个桃\n",num);return 0;}
六、do..while 循环
练习12: do..while说明
#include int main(int argc, const char *argv[]){int i = 0;do{//不管while后面的条件为真还是为假//代码块都会先执行一次printf("hello world\n");i++;}while(i<5);return 0;}
七、for 循环
练习13:使用for循环 计算 1-100 的和
#include int main(int argc, const char *argv[]){int i = 0;int num = 0;for(i=1; i<101; i++){num += i;// += 为复合赋值运算符 相当于num = num +i;}printf("%d\n",num);return 0;}
练习14:输出 [100,999] 范围内所有的水仙花数
水仙花数:个*个*个 + 十*十*十 + 百*百*百 == 自身
例如 153:1*1*1 + 5*5*5 + 3*3*3 = 1 + 125 + 27 == 153
所以 153 就是一个水仙花数
答:153、370 、371、407
#include int main(int argc, const char *argv[]){int ge = 0;int shi = 0;int bai = 0;int i = 0;for(i = 100; i < 1000; i++){ // 不要在循环里面定义变量 因为循环里面定义的变量的生命周期和作用域都是循环的 // 循环每执行一次 都会释放原来的空间 然后重新分配 会有时间上的开销 效率低ge = i % 10;shi = i /10 % 10;bai = i / 100;if(ge*ge*ge + shi*shi*shi + bai*bai*bai == i){printf("%d 是一个水仙花数\n",i);}} return 0;}
练习15:输入一个日期 输出这个日期是这一年的第几天
注意,得考虑平年闰年的问题。如:输入:2021-3-24
输出:2021年3月24日是2021年的第 83 天
#include int main(int argc, const char *argv[]){//输入日期的变量int year = 0;int mon = 0;int day = 0;int mon2_day = 0; //2月天数变量int mon_day = 0;//月份的天数int sum_day = 0;//总天数int i = 1;//月份初始为1月printf("输入一个日期:");scanf("%d-%d-%d",&year,&mon,&day);//判断2月有多少天数if((year%4 == 0 )&& (year%100 != 0) || year%400 == 0){mon2_day = 29;}else{mon2_day = 28;}if(mon >= 0 && mon <= 12 ){ //判断输入月份是否正确while(i < mon ){ //若输入为5月,循环求出前几个月的月份天数switch(i){case 1:case 3:case 5:case 7:case 8:case 10:case 12:mon_day = 31;break;case 2:mon_day = mon2_day;break;case 4:case 6:case 9:case 11:mon_day = 30;break;}sum_day = sum_day + mon_day; //月份天数递加i++; //月份自增} }else{printf("请输入正确月份\n");} //当i 正好为 输入的月份时,注判断输入日期满足不超过当月的天数if(mon == i ){ switch(i){//求当月的天数case 1:case 3:case 5:case 7:case 8:case 10:case 12: mon_day = 31;break;case 2:mon_day = mon2_day;break;case 4:case 6:case 9:case 11:mon_day = 30;break;}if(day <= mon_day){//判断输入日期day 是否小于等于 当月天数sum_day = sum_day + day;//若满足 用之前满月的天数加上输入的 dayprintf("%d年%d月%d日是%d年的第%d天\n",year,mon,day,year,sum_day); }else{printf("请输入正确日期\n");} } return 0;}
八、控制语句综合练习
练习16:输出 [3,100] 范围内所有的偶数
#include int main(int argc, const char *argv[]){int i = 0;//遍历3-100for(i=3; i <= 100; i++){if( i%2 == 0){printf("偶数 %d\n",i);}} return 0;}
练习17:输入一个数,输出这个数的所有因子
如:输入 12 则输出 1 2 3 4 6 12
#include int main(int argc, const char *argv[]){int num = 0;int i = 0; printf("输入一个数:");scanf("%d",&num);//遍历1-num,寻找因子 for(i = 1; i <= num; i++){//如果整数A除B,得出结果是没有余数的整数,就称B是A的因子。if(num%i == 0){printf("因子: %d\n", i);}} return 0;}
练习18:输出 1000 以内的所有完数
完数:又叫完备数,也叫完美数。一个数除了自身之外的所有因子和还等于自身的数。
如: 6 就是一个完数 1 + 2 + 3 == 6
#include int main(int argc, const char *argv[]){int sum = 0;int i = 0; int j = 0;//遍历1~1000 因为每个数都有可能是完数for(i = 1; i <= 1000; i++){sum = 0;//注意:sum还保留着 上一个数的所有因子和,所有必须清0for(j = 1; j < i; j++){//先获取i所有因子的和if(i%j == 0){sum += j;}}//当for循环结束时 sum是i 除了自身之外所有因子的和//判断i是不是完数if(sum == i){ printf("%d 是完数\n", i);} } return 0;}
练习19:输出 [3,100] 范围内所有的质数
质数:因子只有1和本身的数
解法1:根据循环结束的状态处理。
#include int main(int argc, const char *argv[]){int i = 0;int j = 0;//遍历3-100for(i = 3; i<= 100; i++){// [2,i-1] 范围内 有任何一个能把i整除的数 都说明i不是质数for(j = 2; j < i; j++){//说明i不是质数if(i % j == 0){break;}}//上面的for循环有两种结束条件//1.由于 j==i 循环正常结束//2.由于break导致的退出,此种退出是j一定是小于i的if(i == j){printf("%d 是质数\n",i);}} return 0;}
解法2:使用标志位来处理
#include int main(){int i = 0;int j = 0;int flag = 0;//0不是质数 1 质数//遍历3-100for(i = 3; i <= 100; i++){flag = 1;//每次需要重新置1// [2,i-1] 范围内 有任何一个能把i整除的数 都说明i不是质数for(j = 2; j < i; j++){if(i%j == 0){//说明i不是质数flag = 0;}}if(flag == 1){printf("%d 是质数\n", i);}}return 0;}
九、一维数组练习
练习20:求数组中最大值,及最大值的下标
定义一个int类型的一维数组,长度为10,从终端给数组赋值
找出数组中最大值,及最大值的下标,并输出。
#include int main(int argc, const char *argv[]){int i = 0;int s[10] = {0};//循环给数组成员赋值for(i = 0;i < 10; i++){scanf("%d",&s[i]);}//找最大值及最大值下标 int max_index = 0;for(i = 1; i < 10; i++){if(s[max_index] < s[i]){//max_index = i;}}//当循环结束的时候 max_index 中记录的是最大值的下标//通过最大值的下标 也就找到了最大值printf("最大值:%d 下标:%d\n",s[max_index],max_index);return 0;}
练习21:斐波那契数列
斐波那契数列 1 1 2 3 5 8 13 21 …. 前两个数固定为 1 从第三个开始 依次是前两个数的和,
要求定义一个数组 类型为int 长度为20,给数组中的成员赋斐波那契数列的值,并输出
#include int main(int argc, const char *argv[]){int s[20] = {1,1}; //不完全初始化 没有初始化的位 默认用0初始化//循环给数组赋值 注:不要越界int i = 0;for(i = 0; i < 18; i++){s[i+2] = s[i] +s[i+1];}//输出数组的值for(i = 0; i < 20; i++){printf("%d ",s[i]);}printf("\n");return 0;}
练习22:使用循环打印下面的图案
F
_FE
__FED
___FEDC
____FEDCB
_____FEDCBA
#include int main(int argc, const char *argv[]){int i = 0;int j = 0;char ch = 0;//外层循环控制行数for(i = 0; i < 6; i++){ch = 'F'; //若使用后不置为F,就不是从F开始打印//内层循环控制每行的打印//打印每行的 下划线for(j = 0; j < i; j++){ printf("_");}//打印每行的字母for(j = 0; j <= i; j++){putchar(ch); //向终端输出字符 也可以用printfch--;}putchar(10); //换行 相当于printf("\n");}return 0;}
练习23:冒泡排序
将一维数组按照上升的顺序排列
#include int main(int argc, const char *argv[]){int i = 0;int j = 0;int s[9] = {9,5,6,8,2,7,3,4,1};//排序前for(i = 0; i < 9; i++){printf("%d ",s[i]);}putchar(10);//升序 整个排序的流程int temp = 0; int len = sizeof(s)/sizeof(s[0]);//外层循环控制比较的趟数 len-1 最后一趟只剩下一个元素就不用排序了for(i = 0; i < len-1; i++){//内层循环控制一趟排序比较的次数//每趟都能确定一个最值,最值在下一趟中就不用再参与比较了 所有len-i-1for(j = 0; j s[j+1]){//交换temp = s[j];s[j] = s[j+1];s[j+1] = temp ;} }}//排序后for(i = 0; i < 9; i++){printf("%d ",s[i]);}printf("\n");return 0;}
十、二维数组练习
练习24:找出数组中最大值以及最大值的行号、列号,并输出
定义一个int类型的3行4列的二维数组,并以行为单位完全初始化,找出数组中最大值,及最大值的行号,列号 并输出。
#include int main(int argc, const char *argv[]){int s[3][4] = {{12,32,42,11},{7,4,90,6},{1314,520,100,678}};int max_hang = 0;int max_lie = 0;int i = 0;int j = 0;for(i = 0; i < 3; i++){for(j = 0; j < 4; j++){if(s[max_hang][max_lie] < s[i][j]){max_hang = i;max_lie = j;}}}//当循环结束时max_hang 里存的就是最大值的行号//max_lie 里存的就是最大值的列号printf("最大值:%d 行号:%d 列号:%d\n",s[max_hang][max_lie],max_hang,max_lie); return 0;}
十一、字符串处理函数及字符串倒置
练习25:自己实现strlen函数的功能(计算字符串的长度)
#include int main(int argc, const char *argv[]){char s[32] = "book";int len = 0;//一般不确定长度的时候 使用while循环比较多while(s[len] != '\0'){//0 和'\0'都可以 '0'不可以len++;}//循环结束时 len 中保存的就是字符串的长度printf("%d\n",len);return 0;}
练习26:自己实现 strcpy 函数的功能(字符串的复制)
#include int main(int argc, const char *argv[]){char s1[32] = "homework";char s2[32] = "happy";//要保证 s1 足够大 否则会越界int i = 0;while(s2[i] != '\0'){s1[i] = s2[i];i++;} //将s2的'\0'也拷贝给 s1s1[i] = s2[i];printf("s1 = %s\n", s1);//happyprintf("s2 = %s\n", s2);//happyreturn 0;}
练习27:自己尝试实现 strcat 函数的功能(字符串的追加)
#include int main(int argc, const char *argv[]){char s1[32] = "homework";char s2[32] = "happy";int i = 0;int j = 0;//先找到s1 的 '\0'while(s1[i] != '\0'){i++;}//当上面循环结束的时候 i 就是s1 的 '\0' 的下标//开始追加while(s2[j] != '\0'){s1[i] = s2[j];i++;j++;}//将s2的 '\0' 也追加给s1s1[i] = s2[j];printf("%s\n",s1);printf("%s\n",s2);return 0;}
练习28:将字符串倒置输出
有一个以空格分隔的多个单词的字符串(空格的个数不确定有几个)
“this is a book”
将这个字符串 以单词为单位,倒置输出
“book a is this”
#include int main(int argc, const char *argv[]){char s[32] = "this isa book";//先将字符串整体倒置 --> koob asi sihtint i = 0;int j = 0;int temp = 0;//先找到字符串的最后一个字符while(s[j] != '\0'){j++;}//上面循环结束的时候, j是'\0'的下标j--; //让 j 做为 'k' 的下标//开始交换前面数据和后面数据while(i book ais thisint k = 0; //用来控制整体单词的循环,同时当个中间变量i = 0;//控制空格j = 0;//控制单词while(s[k] != '\0'){i = k;//当不是空格时,不执行while(s[i] == ' ' && s[i] != '\0'){ i++;}//交换完所有单词时,i的下标在'\0',跳出循环while(s[i] == '\0'){break;}// 没交换完单词时,i 的下标在每个单词的第一个字符上,将该下标给 jj = i; while(s[j] != ' ' && s[j] != '\0'){j++;}k = j; //j 的下标在空格上,将j 的值赋给 k ,让k 赋给i //若直接赋给i,会影响下面代码 i 的下标j--; // j 的下标 在单词的最后一个字符上,i 在单词的第一个字符上while(i < j){temp = s[i];s[i] = s[j];s[j] = temp;i++;j--;}}printf("第二次处理:[%s]\n",s);return 0;}
十二、指针练习题
练习29:看代码输出小练习题
int *p = NULL;
printf(“%d %d %d\n”, p+1, p, (p+1)-p);
上面代码会输出什么?
#include int main(int argc, const char *argv[]){int *p = NULL;printf("%d %d %d\n", p+1, p, (p+1)-p);//4 0 1//p = NULL;NULL 就是(void *)0//p+1 : 0 + 1 个int所以p+1 是4号地址 4//(p+1) - p:两个int * 指针做差得到的结果 相差的int的个数1return 0;}
练习30:根据要求写程序
定义一个普通变量a 类型为 int ,里面存储数据 9999
定义一个指针变量 p1 类型为 int *, 让p1指向a
然后通过p1将a中的内容修改为 0x12345678
再定义一个指针p2 类型为 char *,让p2也指向 a
用 %#x 输出 *p2 的值 以及 *(p2+1) *(p2+2) *(p2+3)的值
#include int main(int argc, const char *argv[]){int a = 9999;int *p1 = &a;*p1 = 0x12345678;char *p2 = (char *)&a;printf("%#x %#x %#x %#x\n",*p2,*(p2+1),*(p2+2),*(p2+3));return 0;}//我们使用的主机是小端存储//所有结果:0x78 0x56 0x34 0x12
练习31:请你设计一个程序,判断主机是大端存储还是小端存储?
#include int main(int argc, const char *argv[]){int a = 0x12345678;char *p = (char *)&a;if(0x78 == *p){printf("小端\n");}else if(0x12 == *p){printf("大端\n");}return 0;}
练习32:看代码输出小练习题
int x = 0x41424344;
printf(“%s\n”, &x);
上面的代码会输出什么?
答:小端存储的前提下,输出DCBA+不确定的东西。
练习33:使用指针实现 strlen 函数的功能
#include int main(int argc, const char *argv[]){char s[32] = "book";char *p = s;int count = 0; #if 0 // 法一while(*p != 0){count++;p++;}#endif //法二while(*p++){count++;}printf("%d\n",count);return 0;}
练习34:使用指针实现 strcpy 函数的功能
#include int main(int argc, const char *argv[]){char s1[32] = "hello world";char s2[32] = "book";char *p1 = s1;char *p2 = s2;while(*p2 != '\0'){*p1 = *p2;p1++;p2++;}*p1 = *p2;printf("%s\n", s1);printf("%s\n", s2); return 0;}
练习35:使用指针实现 strcat 函数的功能
#include int main(int argc, const char *argv[]){char s1[32] = "hello world";char s2[32] = "book";char *p1 = s1; //将p1指向s1char *p2 = s2;//先将p1 下标循环到最后一个字符while(*p1 != '\0'){p1++;}//循环结束的时候p指向 s1 的'\0'//循环将s2 的字符追加到 s1 的后面while(*p2 != '\0'){*p1 = *p2;p1++;p2++;}*p1 = *p2;printf("%s\n",s1);printf("%s\n",s2);return 0;}
十三、指针和一维数组的练习
练习36:字符串转换及统计数字个数
从终端输入一个字符串 gets,将所有的大写转成小写,将所有的小写转成大写,如果有数字,统计数字的个数,其他字符全部转换成 -,并输出转换后的字符串 及 数字的个数
#include int main(int argc, const char *argv[]){char buff[128] = {0};gets(buff);printf("处理前:[%s]\n",buff);char *p = buff;int count = 0;while(*p != '\0'){if(*p >= 'A' && *p = 'a' && *p = '0' && *p <= '9'){count++;}else{*p = '-';}p++;}printf("处理后:[%s] 共有数字 %d 个\n",buff,count); return 0;}
练习37:自己实现 atoi函数 的功能
atoi 将字符串的数字 转成整型的数
“12345678” —> 12345678
#include int main(int argc, const char *argv[]){char buff[32] = "12345678";char *p = buff;int sum = 0;while(*p != '\0'){sum *= 10 ; sum += (*p -'0');p++;}printf("%d\n",sum); return 0;}
练习38:使用命令行传参的方式 实现 简易计算器的加减功能
如: ./a.out 10 + 20 —> 30
./a.out 100 – 50 —> 50
#include #include #include int main(int argc, const char *argv[]){int left_value = atoi(argv[1]);int right_value = atoi(argv[3]);if(0 == strcmp(argv[2],"+")){printf("%d+%d=%d\n",left_value,right_value,left_value + right_value);}else if(0 == strcmp(argv[2],"-")){printf("%d-%d=%d\n",left_value,right_value,left_value + right_value);}return 0;}
十四、函数练习题
练习39:自己封装一个 能输出 1~n 求和结果的函数
n由参数传递,并调用测试
#include #include //函数声明时 可以只写类型 不写形参名void my_sum(int ); int main(int argc, const char *argv[]){int num = atoi(argv[1]);my_sum(num); return 0;}//定义时 必须要写 形参名 因为函数内部要使用这个名字void my_sum(int n){int i = 0;int sum = 0;for(i = 0; i <= n; i++){sum += i;}printf("%d\n",sum);}
练习40:实现 两个整数 加减乘除 的功能
编写4个函数,my_add, my_sub, my_mul, my_div ,分别实现 两个整数 加减乘除 的功能,并调用测试。
#include #include //函数声明 int my_add(int, int);int my_sub(int,int);int my_mul(int,int);float my_div(int,int);int main(int argc, const char *argv[]){int a = atoi(argv[1]);int b = atoi(argv[2]);printf("%d\n",my_add(a,b));printf("%d\n",my_sub(a,b));printf("%d\n",my_mul(a,b));printf("%.3f\n",my_div(a,b));return 0;}int my_add(int x,int y){return x+y;}int my_sub(int x,int y){return x - y;}int my_mul(int x,int y){return x * y;}float my_div(int x,int y){return (float)x/(float) y;}
练习41:将前面冒泡排序的功能 封装成函数
int sort(int *p, int len, int flag);
flag 1 升序 、 flag 0 降序
#include //flag 1 升序flag 0 降序void my_sort(int *p,int len,int flag){int i = 0;int j = 0;int temp = 0;for(i = 0; i <len -1; i++){for(j = 0; j p[j+1]){temp = p[j];p[j] = p[j+1];p[j+1] = temp;}}else if(flag == 0){ //降序if(p[j] < p[j+1]){temp = p[j];p[j] = p[j+1];p[j+1] = temp;}}}}}void my_print(int *p,int len){ //打印数组int i = 0;for(i = 0; i < len; i++){printf("%d ",p[i]);}printf("\n"); }int main(int argc, const char *argv[]){int s[10] = {2,1,8,5,4,3,7,9,6,10};//排序前my_print(s, 10);//升序排序my_sort(s, 10, 1);//排序后my_print(s, 10);//降序排序my_sort(s, 10, 0);//排序后my_print(s, 10); return 0;}
练习42:将 strlen 封装成函数
法一:
#include //函数调用void my_strlen(char *p){int len = 0;while(*p++){ //先进行 p++ 后 *(p++)len++;//统计字符个数}printf("%d\n",len);} int main(int argc, const char *argv[]){char s[32] = "book";my_strlen(s);return 0;}
法二:
#include int my_strlen(const char *str){int len = 0;while(*str != '\0'){len++;str++;}return len;}int main(int argc, const char *argv[]){char s[32] = "hello world";printf("%d\n", my_strlen(s));return 0;}
练习43:将strcpy封装成函数
#include int my_strcpy(char *dest, const char *str){while(*str != '\0'){*dest = *str;str++;dest++;}*dest = *str;return 0;}int main(int argc, const char *argv[]){char s1[32] = "hello world";char s2[32] = "book";my_strcpy(s1,s2);printf("%s\n", s1);printf("%s\n", s2);return 0;}
练习44:将 strcat 封装成函数
#include int my_strcat(char *dest, const char *str){//先让dest 的下标指向'\0'while(*dest != '\0'){dest++;}//让str 的字符循环追加到 dest的后面while(*str != '\0'){*dest = *str; str++;dest++;}*dest = *str;//将str 的 '\0' 赋给 destreturn 0;}int main(int argc, const char *argv[]){char s1[32] = "hello world";char s2[32] = "book";my_strcat(s1,s2);printf("%s\n", s1);printf("%s\n", s2);return 0;}
练习45:将 strcmp 封装成函数
#include int my_strcmp(char *s1, const char *s2){while(*s1 == *s2 && *s1 != '\0'&& *s2 != '\0'){s1++;s2++;}//如果循环结束时 *s1 == *s2说明 *s1 和 *s2 都是 '\0'if(*s1 == *s2){return 0;}else{return *s1-*s2;}}int main(int argc, const char *argv[]){char s1[32] = "hello";char s2[32] = "halloasdfqewr";int ret = my_strcmp(s1,s2);if(ret == 0){printf("s1 == s2\n");}else if(ret > 0){printf("s1 > s2\n");}else if(ret < 0){printf("s1 < s2\n");}return 0;}