文章目录
- 实验一:简单循环
- 题目
- 代码一
- 代码二
- 实验二:数组操作
- 题目
- 代码
- 实验三:调用函数
- 题目
- 代码
- 实验四:指针,处理字符串
- 题目
- 代码
- 课程设计:销售业绩管理系统
- 【感想】
实验一:简单循环
题目
- 求1-1/2+1/3-1/4……+1/99-1/100之值。
- 求出200到300之间的数,且满足条件:它们三个数字之积为42 ,三个数字之和为12。
代码一
#include<stdio.h>
int main()
{
int i,f=1;
double sum=0;
for(i=1;i<=100;i++)
{
sum+=f*1./i;//累加
f=-f;//用于控制符号
}
printf("%f",sum);
return 0;
}
↑
利用1相反数得-1,-1去相反数得1
#include<stdio.h>
#include<math.h>
#define N 100
int main()
{
int i;
double sum=0.0;
for (i = 1; i <= N; i++)//运用循环,累加
sum = sum + pow(-1, i + 1) / i;//加减用-1的乘方表示
printf("结果为%lf", sum);
return 0;
}
↑
利用(-1)的乘方控制符号
代码二
#include<stdio.h>
int main()
{
int n, a, b, c;
for (n = 200; n <= 300; n++)
{
a = n % 10;//个位上的数字
b = (n - a) / 10 % 10;//十位上的数字
c = (n - 10*b- a) / 100;//百位上的数字
if (a + b + c == 12 && a * b * c == 42)
printf("%d\n", n);
}
return 0;
}
↑
个位:该数据除以10后取余
十位:该数据减去个位上的数字,除以10,再除以10取余
百位:该数据减去个位,再减去十位上数字乘以10的数,最后再除以100
明显此方法较麻烦,优化一下:
#include<stdio.h>
int main()
{
int i,g,s,b;
for(i=200;i<=300;i++)
{
g=i%10;//个位
s=i/10%10;//十位
b=i/100%10;//百位
if(g+s+b==12&&g*s*b==42)//同时满足两个条件则输出
printf("%d\n",i);
}
return 0;
}
↑
直接除以10降位!妙啊~
实验二:数组操作
题目
从键盘输入若干个整数,输入整数的个数小于100 ,其值在 0~100 范围内,用-1 作为输入结束的标志。统计每个整数的个数并从大到小排序,输出排序后的结果。提示:定义两个数组,一个用来存放输入整数,另一个用来存放统计信息。
代码
#include<stdio.h>
int main()
{
int a[100];//记录输入所有的数字
int b[100];//记录不重复的数字
int c[100];//记录每个数字出现的次数
int i,j;//循环变量
int n=0;//输入了多少数字
int k=0;//有多少不重复的数字
int repetition=0 ;//检验是否重复
int max;//;记录次数最大的数字的下标
int m,z;
printf("请输入数字");
for (i = 0; i < 100; i++)
{
scanf_s("%d", &a[i]);
if (a[i] == -1)
break;
n++;
}
for (i = 0; i < 100; i++)
{
for (j = 0; j < i; j++)
{
if (a[i] == b[j])
{
c[j]++;
repetition = 1;
break;
}
}
if (repetition == 0)
{
b[k] = a[i];
c[k] = 1;
k++;
}
repetition = 0;
}
for (i = 0; i < k-1; i++)
{
max= i;
for (j = i + 1; j < k; j++)
{
if (c[max] < c[j])
max = j;
}
if (max != i)
{
m = b[i];
b[i] = b[max];
b[max] = m;
z = c[i];
c[i] = c[max];
c[max] = z;
}
}
for (i=0;i<k-1;i++)
printf("数字%d出现的次数为%d\n", b[i], c[i]);
return 0;
}
↑
小白的思路很原始,但代码很复杂:先输入数字a[i],记录一共输入了多少个数字→检查里面有多少个不一样的数字b[i]→记录每个不一样的数字出现的次数c[i]→再用c[i]排序
接下来让大佬来优化一下↓:
#include<stdio.h>
#include<string.h>
int a[101];
void maxn(int *b,int n)
{
int i,max,book=0;
max=b[0];
for(i=0;i<n;i++)
if(max<b[i])
{
max=b[i];
book=i;
}
if(max==-1)//找出需要的数之后就结束
return ;
printf("%-3d is %d times\n",book,max+1);
b[book]=-1;
maxn(b,n);//递归
}
int main()
{
int b[101],i,j;
memset(b,-1,sizeof(b));//b数组初始化为-1
for(i=0;;i++)
{
scanf("%d",&a[i]);
if(a[i]==EOF)
break;
}
for(j=0;j<i;j++)
{
b[a[j]]++;//一个数出现一次就加一
}
maxn(b,101);
return 0;
}
↑
将输入的数直接作为计数数组的下标,这样就省去了检测有多少种不一样的数,可以直接计数了。
在排序时,还用到了递归(我们当时还没学,这位大佬自己学了,膜拜)
实验三:调用函数
题目
编写函数,从标准输入中读取字符,直到遇到 EOF 。程序要输出每个字符是否是字母。如果是,还要求输出该字母在字母表中的数值位置。
代码
#include<stdio.h>
void check(char a)
{
if (a >= 65 && a <= 90) //判断字符是否为大写字母
printf("%c是大写字母,排在第%d位\n", a, a - 64);
else if (a >= 97 && a <= 122) //判断字符是否为小写字母
printf("%c是小写字母,排在第%d位\n", a, a - 96);
else
printf("%c不是字母\n", a); //判断字符是否为字母
}
int main()
{
char a[100];
gets(a);
for (int i = 0; i < 100; i++)
{
if (a[i] == '#') //输入#,则退出循环
break;
check(a[i]); //执行子函数判断
}
return 0;
}
#include<stdio.h>
#include<string.h>//回车也被记录为字符,若想检测多个,请一次全部输入
int panduan(char c)
{
if(c>='A'&&c<='Z')
return 2;
else if(c>='a'&&c<='z')
return 1;
return 0;
}
int main()
{
char c;
int s=0;
while(scanf("%c",&c)!=EOF)
{
if(panduan(c)==1)
printf("YES %d",(int)(c-'a'+1));
else if(panduan(c)==2)
printf("YES %d",(int)(c-'A'+1));
else if(!panduan(c))
printf("NO");
printf("\n");
}
return 0;
}
这次两个代码差不多,都是利用字符的ASCII码判断是不是字母
实验四:指针,处理字符串
题目
定义函数 void mystrcat(char *s1,char *s2, char *new_s) 实现对两个字符串进行交叉连接。
例如:有两个字符串“abcd”、“1234”,交叉连接后结果为“a4b3c2d1”。
代码
#include<stdio.h>
#include<string.h>
void mystrcat(char *s1,char *s2,char *new_s)
{int i1,i2,i=0,j=0,m; //i用于新的重组数组的循环计数,j用于字符串1,2循环时计数
char *a,*b,*c,t;
i1=strlen(s1); //记录s1字符串的长度
i2=strlen(s2); //记录s2字符串的长度
a=s1;
b=s2;c=s2+i2-1;
m=(i2-1)/2; //交换停止的位置
for(;b<=s2+m;b++,c--)
{t=*b;*b=*c;*c=t;} //将第二个字符数组反向存放
while(*(s1+j)!='\0' && *(s2+j)!='\0') //两个数组先同时一个一个往新的数组里放字符
{
*(new_s+ (i++) )= *(s1+j);
*(new_s+ (i++) )= *(s2+(j++) );
}
if(*(s1+j)=='\0') //如果数组一先结束,那么将数组二里剩余的字符依次填入
{
while( *(s2+j) != '\0')
*(new_s+ (i++) )=*(s2+(j++) );
}
else //如果数组二先结束,同上
{
while( *(s1+j) != '\0')
{*(new_s+ (i++) )=*(s1+(j++) );
}
}
*(new_s+ i )='\0'; //结束,防止出现烫烫烫
printf("两个字符串交叉连接结果:");
puts(new_s);
return;
}
int main()
{char a1[100],a2[100],b[201];
char *s1,*s2,*new_s;
s1=a1;
s2=a2;
new_s=b;
printf("请输入第一个字符串:");
scanf("%s",a1);getchar();//吸收回车键
printf("请输入第二个字符串:");
scanf("%s",a2);getchar();
mystrcat(s1,s2,new_s);
return 0;
}
↑
思路:输入两个字符串→将字符串2反向→将字符串1和新的字符串2依次填入到另一个字符数组中→最后在末尾加上‘\0’
优化↓
#include<stdio.h>
#include<string.h>
void mystrcat(char *s1, char *s2, char *new_s);
int main()
{
char a[50], b[50], str[101];
memset(str,'\0',sizeof(str));
printf("please input str1 and str2\n");
scanf("%s%s", a, b);
mystrcat(a, b, str);
printf("%s",str);
return 0;
}
void mystrcat(char *s1, char *s2, char *str)
{
int len1, len2, i, j, ss=1;
len1 = strlen(s1);
len2 = strlen(s2);
len2--;
for(i = 0, j = 0;; i++)
{
if(j == len1 )//存完了第一个字符串 退出
{
ss*=2;
break;
}
if(len2 == -1)//存完了第二个字符串 也是退出
{
ss*=0;
break;
}
if(i % 2 == 0)//交叉存入
*(str + i) = s1[j++];//将第一个字符串正序往新的数组里存
else
*(str + i) = s2[len2--];//将第二个字符串反序往新的数组里存
}
if(ss==2)//如果是第一个先存完 那么把第二个剩余部分存进去
{
for(;len2 != -1;)
str[i++] = s2[len2--];
}
if(!ss)//如果是第二个先存完 那么把第一个剩余部分存进去
{
for(;j < len1 ;)
str[i++] = s1[j++];
}
}
↑
这个代码就是把两个字符串直接交叉往新的数组里面存,省去了将字符串二反向。
刚开始没加注释,小白没看懂(ŎдŎ;);相信现在大家应该都能理解了~
所以,以后大佬们要多加一些注释哦,让小白们理解你的思路,向你学习!在这里替小白们谢谢大佬了~
课程设计:销售业绩管理系统
这个大作业是很多个子函数拼在一起的,代码超级多,这就不展示了,但总结几个问题吧。
- 鲁棒性:
针对用户(不怀好意的老师)不按要求输入,如:需要输入数字的地方输入字母或其他字符
解决方法:将用户的输入全部存为字符数组,依次判断每个字符是否为数字或小数点。只要遇到一个不是的,就提示用户输入错误;如果全部正确,再用atof函数将其转换为实数。 - 在输入字符和数字之间加getchar(),吸收回车键;
- 用while( scanf("",)!=EOF ) ,可以方便用户多次查询
- 文件里一共有几个公司的信息?
解决方法:在读取文件前,先把结构体里的公司号全部赋值为0,从文件里读取信息,若公司号大于0,则n计数加一。