过于简单的题目直接贴答案
习题4
(1)反向输出16进制数
#include<stdio.h>void main() {unsigned short a,b;scanf("%4X",&a);b = (a & 0x000F)<<12;b += (a & 0x00F0)<<4;b += (a & 0x0F00)>>4;b += (a & 0xF000)>>12;printf("%04X\n",b);}
【解析】
- 对一个十六进制数而言,若要取其中的某一位,如9AF0取其中的9,则只需要将9AF0与F000进行
&运算。如此一来,不需要的位数AF0在于0&时全部变为0。而需要的位数9,与F相&,即(1001)2 & (1111)2,为1的不变,为0的还是0,这样就巧妙地达到了保存的目的。 - 而后的移位操作,其实就是16进制的每一位对应四位2进制位,所以
9AF0&F000=9000右移12位后,相当于9往右移动3位,变成了0009,最后加上它就相当于低四位变成了0009。其余的各位数同理。
(2)不用辅助变量,交换a,b两个数
#include<stdio.h>void main() {int a,b;scanf("%d,%d",&a,&b);a = a+b;b = a-b;a = a-b;printf("%d,%d",a,b);}


(4)原样输出输入的负十六进制数
//参考答案#include<stdio.h>void main() {short int a;scanf("%X",&a);printf("-%hX\n",-a);}//第一次做的答案#include<stdio.h>void main() {char flag = getchar();unsigned int a;scanf("%X",&a);printf("%c",flag);printf("%0X",a);}
【解析】
- -FA98在计算机中以补码存放,其二进制原码为 1111 1010 1001 1000,求得补码为 0000 0101 0110 1000,即十六进制数0568。
- 则通过对0568进行取反操作,并在输出时加上符号“-”,达成题意要求。


(6)输入历经秒数,计算精确时间
#include<stdio.h>void main() {unsigned long seconds;scanf("%ld",&seconds);int day,hour,minute,second,remainSeconds,remainMinute;day = seconds/(1*24*60*60);remainSeconds = seconds%(1*24*60*60);hour = remainSeconds/(1*60*60);remainMinute = remainSeconds%(1*60*60);minute = remainMinute/60;second = remainMinute%60;printf("Have passed %d days.Now is %02d:%02d:%02d.",day,hour,minute,second);}//输入1234567,输出的结果为Have passed 14 days.Now is 06:56:07.标答中的06:57:06是错的。
习题5

#include<stdio.h>void main() {int x;scanf("%d",&x);if (x>0){printf("正数\n");} else {printf("负数\n");}if (x%2==0){printf("偶数\n");} else {printf("奇数\n");}}

#include<stdio.h>void main() {int x,sign;scanf("%d",&x);if (x>0){sign = 1;} else if (x==0){sign = 0;} else {sign = -1;}printf("%d",sign);}

#include<stdio.h>void main() {int num1,num2,num3,temp,max,min;scanf("%d %d %d",&num1,&num2,&num3);if (num1<=num2){if (num2<=num3){printf("%d,%d,%d",num1,num2,num3);} else {if (num1>=num3){printf("%d,%d,%d",num3,num1,num2);} else {printf("%d,%d,%d",num1,num3,num2);}}} else {if (num2>=num3){printf("%d,%d,%d",num3,num2,num1);} else {if (num1>=num3){printf("%d,%d,%d",num2,num3,num1);} else {printf("%d,%d,%d",num2,num1,num3);}}}}//另解,更新于2021/12/21#include<stdio.h>#include<string.h>int main() {int i, num[3];int min,mid,max;printf("输入三个数:\n");for(i=0;i<3;i++){scanf("%d", &num[i]);}min = num[0]<num[1]?num[0]:num[1];min = min<num[2]?min:num[2];max = num[0]>num[1]?num[0]:num[1];max = max>num[2]?max:num[2];mid = num[0]+num[1]+num[2]-max-min; //三个数的和减去另外两个数就是剩下的那个数printf("min=%d mid=%d max=%d",min, mid, max);return 0;}

#include<stdio.h>void main() {printf("*****Time*****\n");printf("%d%5s%-7s\n",1," ","morning");printf("%d%5s%-9s\n",2," ","afternoon");printf("%d%5s%-5s\n",3," ","night");printf("Please enter your choice:");int choice;scanf("%d",&choice);//用这种方式获取选择也是可以的 choice = getchar()switch (choice){case 1:printf("Good morning");break;case 2:printf("Good afternoon");break;case 3:printf("Good night");break;default:printf("Selection error!");break;}}//标答的空格相当之简陋,某种意义应该是错的,因为跟题目里的空格根本对不上23333
(5)闰年判断
#include<stdio.h>void main() {int year,month;scanf("%d,%d",&year,&month);switch (month){case 1:case 3:case 5:case 7:case 8:case 10:case 12:printf("31天\n");break;case 4:case 6:case 9:case 11:printf("30天\n");break;case 2:if ((year%4==0&&year%100!=0) || (year%400==0)){printf("29天\n");} else {printf("28天\n");}break;default:printf("输入数据有误!\n");break;}}
(6)switch区间化简

这题主要就是switch区间化简的问题。根据题目给定的区间,发现都是250的倍数,因此自然联想到除250进行化简。这里的输出保留了两位小数,元角分。
习题6


(2)n x (n+1) x (n+2)
#include<stdio.h>void main() {int i;long mul=1,result=0;for (i = 1; i <= 99; i = i+2){mul = i*(i+1)*(i+2);result += mul;}printf("%ld",result);}
(3)阶乘累加
#include<stdio.h>void main() {long sum = 0;for (int i = 1; i <= 10; i++){long mul=1;for (int j = 1; j <= i; j++){mul *= j;}sum += mul;}printf("%ld",sum);}
(4)a+aa+aaa+…+n个a
#include<stdio.h>void main() {long sum=0,temp=0; //这里千万记得初始化int i,a,n;printf("input a,n:\n");scanf("%d,%d",&a,&n);for (i=1; i<=n; i++) {temp = temp*10 + a;sum += temp;}printf("%ld",sum);}
(5)π近似值估算
#include<stdio.h>void main() {float result=1, temp=1;int n;for ( n = 2; n <= 100; n+=2){temp = (float)(n*n)/((n-1)*(n+1));result*=temp;}printf("%f",2*result);}
(6)sinx 泰勒展开
#include<stdio.h>#include<math.h>void main() {float x;printf("input x:\n");scanf("%f",&x);double result=x,temp=x;int n=1,count=0;do{temp=(-temp*x*x)/((n+1)*(n+2));result+=temp;n+=2;count++;} while (fabs(temp)>=1e-5); //后面会越来越小,所以是大于等于1e-5时执行循环printf("sin(x)=%f,count=%d",result,count);}
(7)水仙花数
#include<stdio.h>void main() {int i;int count=0;for ( i = 100; i < 1000; i++){int a=i/100;int b=(i/10)%10;int c=i%10;if (a*a*a+b*b*b+c*c*c==i){printf("%d ",i);}}}

#include<stdio.h>#include<math.h>void main() {int x,x1,x2,x3,x4,k;printf("input x:\n");scanf("%d",&x);k = abs(x);x1 = k/1000;x2 = (k-x1*1000)/100;x3 = (k-x1*1000-x2*100)/10;x4 = k%10;printf("%d",x1+x2+x3+x4);} //以上为教材标答,不难发现是错的。例如输入12345就gg了,毕竟题目要求的是输入任意整数x#include<stdio.h>#include<math.h>void main() {int x,k,sum=0;printf("input x:\n");scanf("%d",&x);k = abs(x);while (k/10!=0){sum = sum+(k%10);k=k/10;}sum = sum+k;printf("%d",sum);} //这个更贴近标答。之所以是更贴近,是因为没有考虑整数的位数问题。

#include<stdio.h>#include<math.h>void main() {int x,k,r,new=0;printf("input x:\n");scanf("%d",&x);k=x;while (k!=0){r=k%10;new=10*new+r;k=k/10;}if (new==x){printf("yes\n");} else {printf("no\n");}}

#include<stdio.h>#include<math.h>void main() {int x,y,z,count=0;for ( x = 1; x <= 30; x++){for ( y = 1; y <= 75; y++){z=100-x-y;if (5*x+2*y+z==150){count++;printf("%02d,%02d,%02d ",x,y,z);if (count%6==0){printf("\n");}}}}printf("%d",count);}


#include<stdio.h>#include<math.h>void main() {int i=0, sum=0, flag=0;char man = ' ';for ( i = 0; i <= 3; i++){man = 'A' + i;sum = (man!='A') + (man=='C') + (man=='D') + (man!='D');if (sum == 3){printf("target is %c",man);flag = 1;}}if (flag==0){printf("can't found");}}





习题7
xodo yyds!
新版教材还要统计非负数个数。
#include <stdio.h>void main() {int num[20],i,sum=0,count=0;for(i=0;i<20;i++) {scanf("%d",&num[i]);if(num[i]>=0) {count++;sum+=num[i];}}printf("非负数个数为%d个,其总和为%d\n",count,sum);}

#include <stdio.h>void main() {int num[10],i,j,k,t;int ji=0,ou=9; //分别表示奇数和偶数,奇数从数组左边开始,偶数从右边开始for(i=0;i<10;i++) {scanf("%d",&t);if(t%2==0) {num[ou--]=t;} elsenum[ji++]=t;}//选择排序,奇数for(i=0;i<ji-1;i++) { //最后一个奇数存入后,ji++,会变到偶数的位子,所以这里<ji-1k=i;for(j=i+1;j<ji;j++) {if(num[k]>=num[j]) {k=j;}}if(k!=i) {t = num[i];num[i] = num[k];num[k] = t;}}//选择排序,偶数for(i=ji;i<9;i++) { //同理,ji最后+1就到了偶数的位子。然后10个数排9个,最后一个不用排,因此i<9k=i;for(j=i+1;j<10;j++) {if(num[k]>=num[j]) {k=j;}}if(k!=i) {t = num[i];num[i] = num[k];num[k] = t;}}for(i=0;i<10;i++) {printf("%d ",num[i]);}}

#include <stdio.h>void main() {int num[10];int i,max=0,min=0xffffffff,t=0;int maxIndex=0,minIndex=0;for(i=0;i<10;i++) {scanf("%d",&num[i]);//输入时就找出最大最小值if(num[i]>=num[maxIndex])maxIndex = i;if(num[i]<=num[minIndex])minIndex = i;}//交换极值t = num[maxIndex];num[maxIndex] = num[minIndex];num[minIndex] = t;for(i=0;i<10;i++)printf("%d ",num[i]);}


#include <stdio.h>void main() {int num[6];int i,j,temp;for(i=0; i<6; i++)scanf("%d",&num[i]);for(i=0; i<5; i++) { //输出5行,每行最后一个数移到第一位构成下一行temp = num[5]; //先把最后一位数存着for(j=5; j>0; j--)num[j] = num[j-1]; //用前一位值覆盖后一位,即逐位右移num[0] = temp;for(j=0; j<6; j++)printf("%d ",num[j]);printf("\n");}}

#include <stdio.h>void main() {int a[5][5] = {0};int i,j,sum=0,mul=1;for(i=0;i<5;i++) {for(j=0;j<5;j++) {scanf("%d",&a[i][j]);}}//左上角到右下角对角线for(i=0;i<5;i++) {sum+=a[i][i];if(i%2==0) {mul*=a[i][i];}}//另一条对角线for(i=0,j=4; i<5&&j>-1; i++,j--) {sum+=a[i][j];if(i%2==0 && j%2==0) {mul*=a[i][j];}}//两条对角线相交元素算了两次printf("两条对角线和为%d\n",sum-a[2][2]);printf("两条对角线上下标为偶数的元素乘积为%d\n",mul/a[2][2]);}


#include <stdio.h>#define N 6void main() {int i,j,a[N][N];for(i=0;i<N;i++) {a[i][0] = 1; //每行的头尾两个数为1a[i][i] = 1;for(j=1;j<i;j++) { //中间部分索引为1~i-1a[i][j] = a[i-1][j-1] + a[i-1][j]; //每个数等于左上角的数加正上方的数(不要看图形中的位置,看索引)}}for(i=0; i<N; i++) { //6阶三角有6行for(j=0; j<N-i-1; j++) { //第一行输出5个空格,第二行4个...printf(" ");}for(j=0; j<=i; j++) { //只输出到i,右边的空格自然就出来了printf("%2d ",a[i][j]);}printf("\n");}}







#include <stdio.h>#define N 6#include<string.h>void main() {char srcStr[20]="abcde";char dstStr[20]="12345";int i;int j=strlen(dstStr); //dstStr的长度值即为'\0'的索引。标答中是通过for循环找'\0'的位置for(i=0; srcStr[i]!='\0'; i++) {dstStr[j++] = srcStr[i];}dstStr[j] = '\0'; //最后一个数挂载后,j++,所以此时的j就是'\0'应该所处的位置printf("%s\n",dstStr);}
#include <stdio.h>void main() {int num[10]={1,3,5,7,9};int x,i;scanf("%d",&x);printf("插入前\n");for(i=0; i<5; i++)printf("%d ",num[i]);printf("\n插入后\n");for(i=4; i>=0; i--) {if(num[i] >= x)num[i+1] = num[i]; //数组右移给插入数腾地方。当然,这是建立在数组足够大的基础上elsebreak; //就在当前数的右边插入就行了。因为上面的if已经右移好了,所以直接退出循环插入即可。}num[i+1] = x;for(i=0; i<6; i++)printf("%d ",num[i]);}
习题8

#include <stdio.h>#include<math.h>int isPrimeNumber(int number);void main() {int number;printf("input number:\n");scanf("%d",&number);if(isPrimeNumber(number)==1)printf("yes");elseprintf("no");}int isPrimeNumber(int number) {int i;if(number <= 1) {return 0;}for(i=2; i<=sqrt(number); i++) { //教材标答此处为<而不是<=,其实是错的,一试便知if(number%i==0)return 0;}return 1;}
(2)最大公约数
//计算两个正整数的最大公约数int maxCommonFactor(int a, int b) {if(a<=0 || b<=0) {return -1;}while(a!=b) {if(a>b)a = a-b;elseb = b-a;}return a;}

#include <stdio.h>#include<math.h>//选择排序void Sort(int a[], int n) {int i,j,k,t;for(i=0; i<n-1; i++) {k=i;for(j=i+1; j<n; j++) {if(a[i]<=a[j])k=j;}if(k!=i) {t = a[i];a[i] = a[k];a[k] = t;}}}//整型数组输入void getData(int a[], int n) {int i;printf("input number:\n");for(i=0; i<n; i++) {scanf("%d",&a[i]);}}void main() {int a[10];int i;getData(a,10);Sort(a,10);for(i=0; i<10; i++)printf("%d ",a[i]);}

#include <stdio.h>#include<string.h>void JsSort(char str[]) {int i,j,k,len;char ch;len = strlen(str);for(i=1; i<len-1; i=i+2) { //只对下标为奇数的排序k=i;for(j=i+2; j<len; j=j+2) {if(str[i]<=str[j])k=j;}if(k!=i) {ch = str[i];str[i] = str[k];str[k] = ch;}}}void main() {char str[80];gets(str);JsSort(str);puts(str);}

#include <stdio.h>//p为编号数组,共有n个人,从第s个人开始报数,每次报数到第m个人void Josegh(int p[], int n, int s, int m) {int i,j,s1,w;s1 = s; //s1从1开始for(i=1; i<=n; i++) {p[i-1] = i; //30人,数组0-29分别置为30人的编号1-30}for(i=n; i>=2; i--) { //30个人,报数出圈29人后,最后一个人无需进行操作s1 = (s1 + m -1)%i; //出圈人下一位的下标if(s1 == 0) //报数正好到最后一个s1 = i;w = p[s1-1]; //将出圈人编码记录下for(j=s1; j<i; j++) { //从出圈的位置开始,所有人左移一位,等价于将出圈人删除p[j-1] = p[j];}p[i-1] = w; //将刚刚记录下的出圈人逐次放置于倒数位置上}}void main() {int i,p[N];Josegh(p,N,1,10);for(i=N-1; i>=0; i--) { //将数组倒过来输出,即为出圈人的次序printf("%4d", p[i]);if(i%10==0)printf("\n");}}
(6)串的简单匹配
#include <stdio.h>#include<string.h>int StrLoc(char str1[], char str2[]) {unsigned int i, len1, len2;len1 = strlen(str1);len2 = strlen(str2);if(len1>len2)return -1;for(i=0; i<=len2-len1; i++) { //当i>len2-len1时,说明str2剩下的位数已经小于str1,则必不可能相等if(strncmp(str1,str2+i,len1)==0) //str2+i是地址,等价于从str2[i]开始的字符串return i;}return -1;}void main() {int loc;char str1[] = "do";char str2[] = "how do you do?";loc = StrLoc(str1,str2);printf("%d",loc);}


(8)递归求斐波那契

(9)求组合数Cnm
#include <stdio.h>long fun(int m, int n) {if(m==n||n==0)return 1;elsereturn (m*fun(m-1,n)/(m-n)); //Cmn = m/(m-n)*C(m-1)n}void main() {int m,n;long c;printf("input m and n(m>=n):");scanf("%d%d",&m,&n);c = fun(m,n);printf("c=%ld\n",c);}

#include <stdio.h>#include<string.h>char str[80] = {0};//将一整形数(不可为0)转换成字符串,str需足够大void intToStr(int num) {int i;if(num==0) //数字为0时结束递归return;for(i=strlen(str)-1; i>=0; i--) //将整个字符串往后移一位str[i+1] = str[i];str[0] = num%10 + 0x30; //取得末位数字并转为字符存放在数组首位。由于每次操作前都会移位,因此无需担心字符顺序颠倒intToStr(num/10); //剩余数位组成的数字继续递归}void main() {int num;printf("input number:\n");scanf("%d",&num);intToStr(num);printf("the string is:%s\n",str);}
习题9

#include <stdio.h>void exchange(int *x, int *y) {int temp;temp = *x;*x = *y;*y = temp;}void main() {int a[10],b[10],i,n;printf("input array length<10\n");scanf("%d",&n);printf("input array a:\n");for(i=0;i<n;i++)scanf("%d",&a[i]);printf("input array b:\n");for(i=0;i<n;i++)scanf("%d",&b[i]);for(i=0;i<n;i++)exchange(&a[i],&b[i]);printf(">>>>>>>>\n");for(i=0;i<n;i++)printf("%d ",a[i]);printf("\n");for(i=0;i<n;i++)printf("%d ",b[i]);}

#include <stdio.h>#include<string.h>void sstrcat(char *x, char *y) {while(*x!='\0')x++;while(*y!='\0') {*x=*y;x++;y++;}*x='\0';}void main() {char str1[100],str2[100];gets(str1);gets(str2);sstrcat(str1,str2);puts(str1);}

#include<stdio.h>#include<string.h>void main() {char str[100];char *start,*end;gets(str);start=str;end=str+strlen(str)-1;while(*start==*end && start<=end) {start++;end--;}if(start<end)printf("no");elseprintf("yes");}

#include<stdio.h>#include<string.h>char *substr(char *s, int startloc, int len) {static char temp[100];int i;char *p;if(startloc<0 || startloc>=strlen(s) || len<0)return 0;for(i=startloc; i<startloc+len; i++) {temp[i] = *(s+startloc);s++;}temp[i]='\0';return temp;}void main() {char str[20];gets(str);char *p=substr(str,0,5);printf("%s",p);}


#include<stdio.h>#include<string.h>//将字符串s循环左移n个字符void strlshif(char *s, int n) {int i, len;char ch;len = strlen(s);for(i=0; i<n; i++) { //循环n次,左移n位ch = s[0]; //保存第一个变量strncpy(s, s+1, len-1); //从第二个字符开始的字符串左移s[len-1] = ch; //第一个字符置于末尾}}void main() {char str[] = "0123456789";strlshif(str,3);printf("%s\n",str);}

#include<stdio.h>#include<string.h>//删除字符串中的数字void deleteNum(char *s) {char *pstr;for(pstr=s; *pstr!='\0'; pstr++) {while(*pstr>='0' && *pstr<='9')strcpy(pstr, pstr+1);}}void main() {char str[] = "a1b2c3d4e5";deleteNum(str);printf("%s\n",str);}

#include<stdio.h>#include<string.h>//统计子串在主串中的出现次数int totsubstrnum(char *str, char *substr) {int i=0, count=0, len1, len2;len1 = strlen(str);len2 = strlen(substr);while(i <= len1-len2) {if(strncmp(str+i, substr, len2)==0) {count++;i = i+len2;} else {i++;}}return count;}void main() {char str[] = "abcabcabc";char substr[] = "abc";int c = totsubstrnum(str,substr);printf("%d",c);}

#include<stdio.h>#include<string.h>#include<stdlib.h>int getWeek(char *str) {int k, i=0;while(str[i]!=0) {if(str[i]<'0' || str[i]>'9') //要是数字return -1;elsei++;}k = atoi(str); //字符串转为数字if(k<0 || k>6) //1-6为周一到周六,0为周天return -1;return k;}void main(int n, char *args[]) {int k;static char *weekStr[] = {"sunday","mondat","2","3","4","5","6"};if(n!=2) {printf("invalid input!");exit(-1);}k = getWeek(args[1]);if(k==-1) {printf("invalid input!");exit(-1);}printf("%s\n",weekStr[k]);}
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<conio.h>#define N 30void beep();void getNumStr(char *s);void subNumStr(char *a, char *b, char *c);char subChar(char ch1, char ch2);void leftTrim(char *str,char sign);int tag=0;#if defined (N)int a=666;#endifvoid main() {char a[21]={0},b[21]={0},c[22];//输入被减数a,减数bprintf("a=");while(strlen(a)==0)getNumStr(a);printf("\nb=");while(strlen(b)==0)getNumStr(b);//计算差数csubNumStr(a,b,c);printf("\na-b=%s\n",c);}//读取数字字符串void getNumStr(char *s) {int i=0;char ch;while(1) {ch = getch();if(ch=='\r') { //回车符break;}if(ch=='\b') { //退格符if(i>0) {printf("%c %c",ch, ch);i--;} elsebeep();continue;}if(ch<'0' || ch>'9') { //非数字字符beep();continue;}if(i<20) {printf("%c",ch);s[i++]=ch;} elsebeep();}s[i]='\0';}//报警响铃void beep() {printf("\07");}//计算两个数字字符串之差,放在c中void subNumStr(char *a, char *b, char *c) {int i,j,k;char t[20+1],sign=' ';//大数放在a中,小数放在b中if(strlen(a)<strlen(b) || strlen(a)==strlen(b)&&strcmp(a,b)<0) {sign = '-';strcpy(t,a);strcpy(a,b);strcpy(b,t);}memset(c, ' ', 20+2); //将c全部清空i=strlen(a)-1;j=strlen(b)-1;k=20;while(i>=0 && j>=0) //将被减数和减数按从右到左的顺序相减c[k--]=subChar(a[i--],b[j--]);while(i>=0)c[k--]=subChar(a[i--],'0');c[21]='\0';leftTrim(c,sign); //去掉字符串c左边的空格和0}//计算两个字符的差char subChar(char ch1, char ch2) {char ch;ch=ch1-ch2-tag; //两字符对应数字与借位相减if(ch>=0) { //结果>=0tag=0; //没借位return ch+0x30; //差数转换为对应数字字符} else { //结果小于0tag=1; //有进位return ch+10+0x30; //差数+10再转换为数字字符}}//去掉字符串左边的空格和0void leftTrim(char *str, char sign) {int i;for(i=0; str[i]==' '||str[i]=='0'; i++); //查找第一个非0非空格的字符if(str[i]=='\0') //如果差值为0i--;if(sign=='-') //如果为负数,添加负号str[--i]=sign;strcpy(str, str+i);}
习题11

#include<stdio.h>#include<stdlib.h>struct Student {char no[10]; //学号float score; //成绩};//根据学生人数录入信息struct Student *input(int num) {int i;struct Student *p;p=(struct Student *)malloc(num*sizeof(struct Student));for(i=0; i<num; i++) {printf("student %d\n",i+1);scanf("%s%f",p[i].no,&p[i].score); //不能用p[i]->,因为p是指针,但p[i]不是}return p;}//查找最低成绩的学生记录struct Student getMin(struct Student *p, int num) {int i,k=0;for(i=1; i<num; i++) {if(p[i].score<p[k].score)k=i;}return p[k];}void main() {int num;printf("input student number:\n");scanf("%d",&num);struct Student *p=input(num),minStu;if(p==NULL) {printf("memory is not enough!");exit(-1);}minStu = getMin(p,num);printf("the lowest score is:%.1f\n",minStu.score);printf("no is:%s",minStu.no);free(p);}

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Product {
char dm[5];
char mc[11];
int dj;
int sl;
long je;
};
//输入(多少个产品)
struct Product *input(int num) {
int i;
struct Product *p;
p=(struct Product *)malloc(num*sizeof(struct Product));
if(p==NULL) {
printf("memory is not enough!");
exit(-1);
}
for(i=0; i<num; i++) {
printf("Product %d:\n",i+1);
scanf("%4s%10s%d%d", &p[i].dm, &p[i].mc, &p[i].dj, &p[i].sl);
p[i].je = p[i].dj * p[i].sl; //金额=单价*数量
}
return p;
}
//输出(产品,数量)
void output(struct Product *p, int num) {
int i;
printf("代码\t名称\t单价\t数量\t金额\t\n");
for(i=0; i<num; i++) {
printf("%s\t%s\t%d\t%d\t%d\t\n", p[i].dm, p[i].mc, p[i].dj, p[i].sl, p[i].je);
}
}
//按产品代码排序(降序,产品代码相同按金额排)
void pro_sort(struct Product *p, int num) { //冒泡排序
int i,j;
struct Product temp;
for(i=0; i<num-1; i++) {
for(j=i+1; j<num; j++) {
if(strcmp(p[j].dm ,p[i].dm)>0 || strcmp(p[j].dm ,p[i].dm)==0 && p[j].je>p[i].je) { //注意先 && 后 ||
temp = p[j];
p[j] = p[i];
p[i] = temp;
}
}
}
}
void main() {
int num;
struct Product *p;
printf("input product quantity:\n");
scanf("%d",&num);
p=input(num);
if(p==NULL) {
printf("memory is not enough!");
exit(-1);
}
pro_sort(p,num);
output(p,num);
free(p);
}

#include<stdio.h>
#include<stdlib.h>
typedef struct Student {
float score;
struct Student *next;
} stu;
void main() {
int i;
float score;
stu *p,*q;
stu *head = (stu *)malloc(sizeof(stu));
if(head==NULL) {
printf("memory not enough");
exit(-1);
}
head->next=NULL;
for(i=0; i<10; i++) {
stu *node = (stu *)malloc(sizeof(stu));
if(node==NULL) {
printf("memory not enough");
exit(-1);
}
printf("input %d score:\n",i+1);
scanf("%f",&score);
node->score = score;
p=head;
while(p->next!=NULL) {
if(p->next->score < node->score)
break;
p=p->next;
}
node->next = p->next;
p->next = node;
}
printf("after sort:\n");
p=head;
while(p->next!=NULL) {
printf("%.1f ", p->next->score); //注意,头结点没有数据
p = p->next;
}
//链表销毁
p=head;
while(p->next!=NULL) {
q=p->next;
p->next = q->next;
free(q);
}
free(head);
}

#include<stdio.h>
void main() {
int i,j,k,z=0;
char *color[5]={"red", "yellow", "blue", "whight", "black"};
for(i=0; i<5; i++) {
for(j=i+1; j<5; j++) {
for(k=j+1; k<5; k++) {
z++;
printf("%d:%s, %s, %s\n", z, color[i], color[j], color[k]);
}
}
}
}

#include<stdio.h>
#include<stdlib.h>
typedef struct Link {
int data;
struct Link *next;
} link;
link *head;
link *createNode(int nodeNumbers) {
link *p;
p=(link *)malloc(sizeof(link));
if(p==NULL) {
printf("memory is not enough");
exit(-1);
}
p->next = NULL;
p->data = nodeNumbers+1;
return p;
}
void displayLink(link *head) {
link *p;
int i=1;
p=head;
// while(p!=NULL) {
// printf("%5d%10d\n", i++, p->data);
// p=p->next;
// }
do
{
printf("%5d%10d\n", i, p->data);
p=p->next;
i++;
} while(p!=NULL);
}
link *deleteNode(link *current, link *pre) { //删头或尾节点返回新的头节点,删普通节点返回下一个节点
if(current == head) { //当前要删除的结点是头结点
head = current->next;
free(current);
return head;
}
if(current->next == NULL) { //尾结点
pre->next = NULL;
free(current);
return head;
} else { //普通结点
pre->next = current->next;
free(current);
return pre->next;
}
}
void main() {
int i=0, nodeNum=25;
link *current, *pre;
head = NULL;
for(i=0; i<25; i++) {
if(i==0) {
head = createNode(i);
pre = head;
} else {
pre->next = createNode(i);
pre = pre->next;
}
}
printf("first print\n");
displayLink(head);
i=1;
current = head;
while(1) {
if(i%3==0) {
current = deleteNode(current,pre);
i++; //报数+
nodeNum--; //人数-
if(nodeNum < 3) {
break; //人数小于3结束
}
} else {
pre = current;
current = current->next;
if(current == NULL) {
current = head;
}
i++;
}
}
printf("last is:\n");
displayLink(head);
}
习题12

#include<stdio.h>
#include<stdlib.h>
#define MAX 256
void main() {
FILE *fp;
char string[MAX];
int i=1;
if((fp = fopen("aaa.txt","r"))==NULL) {
printf("can't open the file");
exit(-1);
}
while(fgets(string, MAX, fp) != NULL) {
printf("%d %s",i++,string);
}
fclose(fp);
}


#include<stdio.h>
#include<stdlib.h>
#define MAX 256
void main(int arg, char *argv[]) {
FILE *input1, *input2, *output;
char string[MAX];
if(arg!=4) {
printf("input error");
exit(-1);
}
input1 = fopen(argv[1],"r");
input2 = fopen(argv[2],"r");
output = fopen(argv[3],"w");
if(input1==NULL || input2==NULL || output==NULL) {
printf("open or create file error!");
exit(-1);
}
while(fgets(string, MAX, input1) != NULL) {
fputs(string, output);
}
while(fgets(string, MAX, input2) != NULL) {
fputs(string, output);
}
fclose(input1);
fclose(input2);
fclose(output);
}

#include<stdio.h>
#include<stdlib.h>
#define MAX 256
void main(int arg, char *argv[]) {
FILE *fp;
char string[MAX];
//以下5行为测试用,按题意运行需命令行输入参数
argv[0] = "test2.exe";
argv[1] = "aaa.txt";
argv[2] = "2";
argv[3] = "4";
arg=4;
int i, m, n, tag=0;
if(arg!=2 && arg!=4) {
printf("parameters error!");
exit(-1);
}
if(arg==4) { //参数为4个,获取行区间
m = atoi(argv[2]);
n = atoi(argv[3]);
if(m>n) {
printf("parameters error!");
exit(-1);
}
}
if((fp = fopen(argv[1],"r"))==NULL) {
printf("open file error!");
exit(-1);
}
if(arg==4) {
for(i=1; i<m; i++) { //不输出前m-1行
if(fgets(string, MAX, fp) == NULL) { //读到文件尾或出错
tag = 1;
break;
}
//不为空则无操作,跳过
}
//为什么有上面这一段?FILE*内部存在一个读写指针,只要不关闭、不人为移动,它会根据读写过程不断后移
//上述操作正是为了让其移动到第m行为止
if(tag==0) { //4个参数,输出m-n行
for(; i<=n&&fgets(string, MAX, fp) != NULL; i++) {
printf("%s",string);
}
}
} else { //两个参数,输出所有
while(fgets(string, MAX, fp) != NULL) {
printf("%s",string);
}
}
fclose(fp);
}

