Jack's Blog

流淌的心,怎能阻拦,吹来的风,又怎能阻挡。

C language programming learning 8

1.编程统计候选人的得票数。设有3个候选人zhang、li、wang(候选人姓名不区分大小写),10个选民,选民每次输入一个得票的候选人的名字,若选民输错候选人姓名,则按废票处理。选民投票结束后程序自动显示各候选人的得票结果和废票信息。要求用结构体数组candidate表示3个候选人的姓名和得票结果。
例如:
Input vote 1:li
Input vote 2:li
Input vote 3:Zhang
Input vote 4:wang
Input vote 5:zhang
Input vote 6:Wang
Input vote 7:Zhang
Input vote 8:wan
Input vote 9:li
Input vote 10:lii
Election results:
      li:3
   zhang:3
    wang:2
Wrong election:2

#include<stdio.h>
 
#include<string.h>
 
#define TheNumberOfTheELECTORATE 10
 
#define TheNumberOfTheCANDIDATE 3
 
struct candidate
 
{
 
char name[20];
 
int count;
 
}CANDIDATE[3]={"li",0,"zhang",0,"wang",0};
 
int main()
 
{
 
int i,j,flag=1,wrong=0;
 
char name[20];
 
for(j=1;j<=TheNumberOfTheELECTORATE;j++)
 
{
 
printf("Input vote %d:",j);
 
scanf("%s",name);
 
strlwr(name);
 
flag=1;
 
for(i=0;i<TheNumberOfTheCANDIDATE;i++)
 
{
 
if(strcmp(name,CANDIDATE[i].name)==0)
 
{
 
CANDIDATE[i].count++;
 
flag=0;
 
}
 
}
 
if(flag)
 
{
 
wrong++;
 
flag=0;
 
}
}
printf("Election results:\n");
for(i=0;i<TheNumberOfTheCANDIDATE;i++)
 
{
 
printf("%8s:%d\n",CANDIDATE[i].name,CANDIDATE[i].count); }
printf("Wrong election:%d\n",wrong);
 
return 0;
 
}

 

学生管理系统V1.0

Q3134.(10分)第8章实验1:学生成绩管理系统V1.0
某班有最多不超过30人(具体人数由键盘输入)参加某门课程的考试,用一维数组作函数参数编程实现如下学生成绩管理:
(1)录入每个学生的学号和考试成绩;
(2)计算课程的总分和平均分;
(3)按成绩由高到低排出名次表;
(4)按学号由小到大排出成绩表;
(5)按学号查询学生排名及其考试成绩;
(6)按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,统计每个类别的人数以及所占的百分比;
(7)输出每个学生的学号、考试成绩。

程序运行结果示例:
Input student number(n<30):
6↙
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
1↙
Input student's ID, name and score:
11003001 87↙
11003005 98↙
11003003 75↙
11003002 48↙
11003004 65↙
11003006 100↙
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
2↙
sum=473,aver=78.83
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
3↙
Sort in descending order by score:
11003006 100
11003005 98
11003001 87
11003003 75
11003004 65
11003002 48
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
4↙
Sort in ascending order by number:
11003001 87
11003002 48
11003003 75
11003004 65
11003005 98
11003006 100
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
5↙
Input the number you want to search:
11003004
11003004 65
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
6↙
<60 1 16.67%
60-69 1 16.67%
70-79 1 16.67%
80-89 1 16.67%
90-99 1 16.67%
100 1 16.67%
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
7↙
11003001 87
11003002 48
11003003 75
11003004 65
11003005 98
11003006 100
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
8↙
Input error!
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
0↙
End of program!

输入格式:
( 1 )录入学生的人数:
                 **输入数据格式:"%d"
                 **提示信息:"Input student number(n<30):\n"
( 2 )录入每个学生的学号和考试成绩:
               **输入数据格式:"%ld%f"
               **提示信息:"Input student's ID, name and score:\n"
输出格式:
菜单项的输出显示:
Management for Students' scores
1.Input record
2.Caculate total and average score of course
3.Sort in descending order by score
4.Sort in ascending order by number
5.Search by number
6.Statistic analysis
7.List record
0.Exit
Please Input your choice:
计算课程的总分和平均分:
              **输出总分与平均分格式:"sum=%.0f,aver=%.2f\n"
按成绩由高到低排出名次表:
              **输出格式:"%ld\t%.0f\n"
              **提示信息:"Sort in descending order by score:\n"
按学号由小到大排出成绩表:
              **输出格式:"%ld\t%.0f\n"
              **提示信息:"Sort in ascending order by number:\n"
按学号查询学生排名及其考试成绩:
               **如果未查到此学号的学生,提示信息:"Not found!\n"
               **如果查询到该学生,输出格式:"%ld\t%.0f\n"
按优秀(90~100)、良好(80~89)、中等(70~79)、及格(60~69)、不及格(0~59)5个类别,统计每个类别的人数以及所占的百分比:
                **成绩<60输出格式:"<60\t%d\t%.2f%%\n"
                **成绩=100输出格式:"%d\t%d\t%.2f%%\n"
                **其他输出百分比格式:"%d-%d\t%d\t%.2f%%\n"

#include"stdio.h"
int input(unsigned long *p,float *q,int k)
{
   int i,j;
   printf("Input student's ID, name and score:\n");
   for (i=0;i< k;i++)
       scanf("%ld%f",p+i,q+i);
   return 0;
}
int cal(float *p,int k)
{
   int i;float sum=0,av=0;
   for (i=0;i< k;i++)
       sum+=*(p+i);
   av=sum/k;
   printf("sum=%.0f,aver=%.2f\n",sum,av);
   return 0;
}
int swap(unsigned long *p,float *q,int i,int j)
{
   unsigned long t1;float t2;
   t1=*(p+i);
   *(p+i)=*(p+j);
   *(p+j)=t1;
   t2=*(q+i);
   *(q+i)=*(q+j);
   *(q+j)=t2;
 
   return 0;
}
int sortsc(unsigned long *p,float *q,int k)
{
   int i,j,max;
   for (i=0;i< k-1;i++)
   {
       max=i;
       for (j=i+1;j< k;j++)
           if (*(q+j)>*(q+max)) max=j;
       swap(p,q,i,max);
   }
 
   return 0;
}
int sortst(unsigned long *p,float *q,int k)
{
   int i,j,max;
   for (i=0;i< k-1;i++)
   {
       max=i;
       for (j=i+1;j< k;j++)
           if (*(p+j)<*(p+max)) max=j;
       swap(p,q,i,max);
   }
 
   return 0;
}
int sebn(unsigned long *p,float *q,int k)
{
   unsigned long sc;
   int i,ans=k;
   printf("Input the number you want to search:\n");
   scanf("%ld",&sc);
   for (i=0;i< k;i++)
       if (*(p+i)==sc) ans=i;
   if (ans!=k) printf("%ld\t%.0f\n",*(p+ans),*(q+ans));
   else printf("Not found!\n");
 
   return 0;
}
int stan(float *q,int k)
{
   int num[6],i;
   for (i=0;i< 6;i++) num[i]=0;
   for (i=0;i< k;i++)
   {
       if (*(q+i)>99) {num[0]++;continue;}
       if (*(q+i)>89) {num[1]++;continue;}
       if (*(q+i)>79) {num[2]++;continue;}
       if (*(q+i)>69) {num[3]++;continue;}
       if (*(q+i)>59) {num[4]++;continue;}
                      {num[5]++;}
   }
   printf("<60\t%d\t%.2f%%\n",num[5],100.0*num[5]/k);
   printf("60-69\t%d\t%.2f%%\n",num[4],100.0*num[4]/k);
   printf("70-79\t%d\t%.2f%%\n",num[3],100.0*num[3]/k);
   printf("80-89\t%d\t%.2f%%\n",num[2],100.0*num[2]/k);
   printf("90-99\t%d\t%.2f%%\n",num[1],100.0*num[1]/k);
   printf("100\t%d\t%.2f%%\n",num[0],100.0*num[0]/k);
 
   return 0;
}
int main()
{
  int n,flag=1,a,i;
  float sc[30];
  unsigned long st[30];
  printf("Input student number(n<30):\n");
  scanf("%d",&n);
  while(flag)
  {
       printf("Management for Students' scores\n");
       printf("1.Input record\n");
       printf("2.Caculate total and average score of course\n");
       printf("3.Sort in descending order by score\n");
       printf("4.Sort in ascending order by number\n");
       printf("5.Search by number\n");
       printf("6.Statistic analysis\n");
       printf("7.List record\n");
       printf("0.Exit\n");
       printf("Please Input your choice:\n");
       scanf("%d",&a);
       switch (a)
       {
           case 1:
               input(st,sc,n);
               break;
           case 2:
               cal(sc,n);
               break;
           case 3:
               sortsc(st,sc,n);
               printf("Sort in descending order by score:\n");
               for (i=0;i< n;i++)
                   printf("%ld\t%.0f\n",st[i],sc[i]);
               break;
           case 4:
               sortst(st,sc,n);
               printf("Sort in ascending order by number:\n");
               for (i=0;i< n;i++)
                   printf("%ld\t%.0f\n",st[i],sc[i]);
               break;
           case 5:
               sebn(st,sc,n);
               break;
           case 6:
               stan(sc,n);
               break;
           case 7:
               for (i=0;i< n;i++)
                   printf("%ld\t%.0f\n",st[i],sc[i]);
               break;
           case 0:
               flag=0;
               printf("End of program!\n");
               break;
           default:
               printf("Input error!\n");
       }
 
  }
 
  return 0;
}

C language programming learning 7

1.

//编程实现找出字符串中最大字符元素并输出该元素及其对应的ASCII值.
//****要求输入提示信息为:
//"Input a string:\n"
//****输出格式要求为:
//"The largest character of \"%s\" is \'%c\' ,The ASCII is %d."
#define N 100
#include<stdio.h>
#include<string.h>
main()
{

    printf("Input a string:\n");
    char c[N];
    gets(c);
    char d=c[0];
    int i;
    for(i=1;i<=strlen(c);i++)
    {
        if(d<c[i])
            d=c[i];
    }
    printf("The largest character of \"%s\" is \'%c\' ,The ASCII is %d.",c,d,d);
}

2.

按如下函数原型编程计算并输出n×n阶矩阵的转置矩阵。其中,n由用户从键盘输入。已知n值不超过10。
void Transpose(int (*a)[N], int n);
void  Swap(int *x, int *y);
void InputMatrix(int (*a)[N], int n);
void PrintMatrix(int (*a)[N], int n);
输入提示信息:"Input n:"
输入格式:"%d"
输入提示信息:"Input %d*%d matrix:\n"
输出提示信息:"The transposed matrix is:\n"
输出格式:"%d\t"

#include <stdio.h>
#define N 10
void  Swap(int *x, int *y);
void Transpose(int (*a)[N], int n);
void InputMatrix(int (*a)[N], int n);
void PrintMatrix(int (*a)[N], int n);
int main()
{                
    int s[N][N], n;
    printf("Input n:");
    scanf("%d", &n);
    InputMatrix(s, n);
    Transpose(s, n);
    printf("The transposed matrix is:\n");
    PrintMatrix(s, n);
    return 0;
}                
/* 函数功能:交换两个整型数的值 */
void  Swap(int *x, int *y)
{                
    int  temp;
    temp = *x;
    *x = *y;
    *y = temp;
}                
/* 函数功能:计算n*n矩阵的转置矩阵 */
void Transpose(int (*a)[N], int n)
{                
    int i, j;
    for (i = 0; i < n; i++)
    {                
        for (j = i; j < n; j++)
        {                
            Swap(*(a + i) + j, *(a + j) + i);
        }
    }
}                
/* 函数功能:输入n*n矩阵的值 */
void InputMatrix(int (*a)[N], int n)
{                
    int i, j;
    printf("Input %d*%d matrix:\n", n, n);
    for (i = 0; i < n; i++)
    {                
        for (j = 0; j < n; j++)
        {                
            scanf("%d", *(a + i) + j);
        }
    }
}                
/* 函数功能:输出n*n矩阵的值 */
void PrintMatrix(int (*a)[N], int n)
{                
    int i, j;
    for (i = 0; i < n; i++)
    {                
        for (j = 0; j < n; j++)
        {                
            printf("%d\t", *(*(a + i) + j));
        }
        printf("\n");
    }
}           

 

我的代码

#include<stdio.h>
#define N 10
void Transpose(int (*a)[N], int n)
{

    int i,j;
    for(i=0; i<n; i++)
    {
        for(j=i+1; j<n; j++)
        {
            Swap(*(a+i)+j,*(a+j)+i);
        }
    }

}

void  Swap(int *x, int *y)
{
    int temp;
    temp=*x;
    *x=*y;
    *y=temp;

}
void InputMatrix(int (*a)[N], int n)
{
    printf("Input %d*%d matrix:\n",n,n);
    int i,j;
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {

            scanf("%d",*(a+i)+j);
        }
    }

}
void PrintMatrix(int (*a)[N], int n)
{
    int i,j;

    for(i=0; i<n; i++)
    {

        for(j=0; j<n; j++)
        {
            printf("%d\t",*(*(a+i)+j));
        }
        printf("\n");
    }
}
main()
{
    int n=100,s[N][N]= {0};

    printf("Input n:");
    do
    {

        scanf("%d",&n);

    }
    while(n>10);

    InputMatrix(s,n);
    Transpose(s,n);

    printf("The transposed matrix is:\n");

    PrintMatrix(s,n);
    return 0;
}

我个人认为,我的代码比答案还要简单,因为减少了一步不必要的计算,因此,运算时间会短一些。效率会高些!

注意:在Transpose的过程中,一定要注意一个关键性的问题

for(j=i; j<n; j++)

或者从i+1开始(i+1)效率更高,减少不必要的运算

mmp,我就是让j从0开始结果找这个错误找了一个小时,好奇啊。如果j从0开始的话,那么就相当于先把i,j互换,然后再换回来,等于说换了两次,相当于没换。

其实如果要直接输出转置矩阵,还有更简便的做法:

即:输出先j后i!无论是代码量还是计算量,都少了一大截!!!

 

#include<stdio.h>
#define N 10

void InputMatrix(int (*a)[N], int n)
{
    printf("Input %d*%d matrix:\n",n,n);
    int i,j;
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {

            scanf("%d",*(a+i)+j);
        }
    }

}
void PrintMatrix(int (*a)[N], int n)
{
    int i,j;

    for(i=0; i<n; i++)
    {

        for(j=0; j<n; j++)
        {
            printf("%d\t",*(*(a+j)+i));
        }
        printf("\n");
    }
}
main()
{
    int n=100,s[N][N]= {0};

    printf("Input n:");
    do
    {

        scanf("%d",&n);

    }
    while(n>10);
    InputMatrix(s,n);
    printf("The transposed matrix is:\n");
    PrintMatrix(s,n);
    return 0;
}

 


题外话:

       有句mmp今天一定要讲。这种题出的简直就是多此一举

因为

我们可以认为:
int (*a)[]=int a [][]
他直接说定义一个二维数组多好

非得写这么恶心的东西的干嘛

可能他有点蛋疼
.....
因为数组作为参数类型退化成指针
int a[]写成int *a是一个意思
这跟C语言对数组的实现有关
二维数组要求第二个维度给出长度,这是因为编译器算偏移要用这个
因为你取数组里面一个元素实际上是解引用一个指针
这个指针是base+offset算出来的
 
int a[100]
a[4]等价于 *(a+4)
由加法交换性,4[a]等价于a[4],就是你可以把a[4]写成4[a]
------------------------------------------------------------------
大佬告诉我
毕竟C是一种比较低级的语言
像函数式语言是没指针的
甚至没有变量
感兴趣的话可以去玩玩haskell,这个比较典型
------------------------------------------------------------------
[]优先级比*高
int b[4][4]={0};
int (*a)[4]=b;

int b[4][4]={0};
int *a[4];
a[0]=b[0];
就是说
int *a[n]是指针数组(也就是说其本质上是数组,但里面存放的都是指针)
int (*a)[n]是数组指针(本质上是一个指针,而且是一个指向数组的指针)

第一部分:

int a[4]

a的类型是int[4],a[0]的类型是int;a是指向int[4]的指针

int (*a)[4]=b;指的是a指向的是int [4],然后把b的第一行地址赋给他

就是直接拷贝了首元素地址

第二部分很好理解

就是把b[0]的首行地址给a[4];

其实这种题完全可以用数组的方法做,看起来更加简洁,效率也几乎一样

#include<stdio.h>
#include<string.h>
#define N 4
int convertmatrix(int m[N][N])
{
    int i,j,temp;
    for(i=0;i<N;i++)
    {
        for(j=i+1;j<N;j++)
        {
            temp=m[i][j];
            m[i][j]=m[j][i];
            m[j][i]=temp;
        }
    }
    return 0;
}
int main()
{
    int matrix[N][N];
    int i,j;
    printf("请输入一个%d*%d的矩阵:\n",N,N);
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            scanf("%d",&matrix[i][j]);
        }
    }
    convertmatrix(matrix);
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            printf("%-3d",matrix[i][j]);
        }
        printf("\n");
    }
    return 0;
}

用指针编简直就是在浪费时间

所以。。。。

还有一种做法:

#include<stdio.h>
#include<string.h>
#define N 4
int convertmatrix(int m[N][N])
{
    int i,j,temp;
    for(i=0;i<N;i++)
    {
        for(j=i+1;j<N;j++)
        {
            temp=m[i][j];
            m[i][j]=m[j][i];
            m[j][i]=temp;
        }
    }
    return 0;
}
int main()
{
    int matrix[N][N];
    int i,j;
    printf("请输入一个%d*%d的矩阵:\n",N,N);
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            scanf("%d",&matrix[i][j]);
        }
    }
    convertmatrix(matrix);
    for(i=0;i<N;i++)
    {
        for(j=0;j<N;j++)
        {
            printf("%-3d",matrix[i][j]);
        }
        printf("\n");
    }
    return 0;
}

另外一个比较类似的问题:

用指向一维数组的指针变量即二维数组的行指针作为函数参数,实现矩阵转置。按如下函数原型编程计算并输出m×n阶矩阵的转置矩阵。其中,m和n的值由用户从键盘输入。已知m和n的值都不超过10。

void Transpose(int (*a)[N], int (*at)[M], int m, int n);

void InputMatrix(int (*a)[N], int m, int n);

void PrintMatrix(int (*at)[M], int n, int m);

输入提示信息:"Input m, n:"

输入格式:"%d,%d"

输入提示信息:"Input %d*%d matrix:\n"

输出提示信息和格式:"The transposed matrix is:\n"

输出格式:"%d\t"

#include<stdio.h>

#define M 10

#define N 10

void Transpose(int (*a)[N], int (*at)[M], int m, int n);

void InputMatrix(int (*a)[N], int m, int n);

void PrintMatrix(int (*at)[M], int n, int m);

int main()

{

    int s[M][N],st[N][M],m,n;

    printf("Input m, n:");

    scanf("%d,%d",&m,&n);

    InputMatrix(s,m,n);

    Transpose(s,st,m,n);

    printf("The transposed matrix is:\n");

    PrintMatrix(st,n,m);

    return 0;

}

void Transpose(int (*a)[N], int (*at)[M], int m, int n)

{

    int i,j;

    for(i=0;i<m;i++)

    {

        for(j=0;j<n;j++)

        {

            *(*(at+j)+i)=*(*(a+i)+j);

        }

    }

}

void InputMatrix(int (*a)[N], int m, int n)

{

    int i,j;

    printf("Input %d*%d matrix:\n",m,n);

    for(i=0;i<m;i++)

    {

        for(j=0;j<n;j++)

        {

            scanf("%d",*(a+i)+j);

        }

    }

}

void PrintMatrix(int (*at)[M], int n, int m)

{

    int i,j;

    for(i=0;i<n;i++)

    {

        for(j=0;j<m;j++)

        {

            printf("%d\t",*(*(at+i)+j));

        }

        printf("\n");

    }

}

3.

从键盘任意输入一个整型表示的月份值,用指针数组编程输出该月份的英文表示,若输入的月份值不在1~12之间,则输出“Illegal month”。

**输入格式要求:"%d"  提示信息:"Input month number:"

**输出格式要求:"month %d is %s\n"

"Illegal month", "January", "February", "March", "April", "May", "June", "July", August", "September", "October", "November", "December"

程序运行示例1如下:

Input month number:5

month 5 is May

程序运行示例2如下:

Input month number:13

Illegal month

#include<stdio.h>

int main()

{

    int n;

    static char*monthName[]={"Illegal month", "January", "February", "March", "April", "May", "June", "July", “August", "September", "October", "November", "December"};

    printf("Input month number:");

    scanf("%d",&n);

    if((n<=12)&&(n>=1))

    printf("month %d is %s\n",n,monthName[n]);

    else

    printf("%s\n",monthName[0]);

    return 0;

}

4.

•编程计算2×3阶矩阵A和3×2阶矩阵B之积C。
•矩阵相乘的基本方法是:
•矩阵A的第i行的所有元素同矩阵B第j列的元素对应相乘,
•并把相乘的结果相加,最终得到的值就是矩阵C的第i行第j列的值。
•要求:
•(1)从键盘分别输入矩阵A和B,
•  输出乘积矩阵C
•(2)
•**输入提示信息为:
•输入矩阵A之前提示:"Input 2*3 matrix a:\n"
•输入矩阵B之前提示:"Input 3*2 matrix b:\n"
•**输入矩阵中每个值的格式为:"%d"
•**输出格式为:
•输出矩阵C之前提示:"Results:\n"
•输出矩阵C中每个值的格式:"%6d"
•输出矩阵C各行结束时换行
#include <stdio.h>
#define  ROW 2
#define  COL 3
void main()
{
	int a[ROW][COL], b[COL][ROW], c[ROW][ROW], i, j,k;

	printf("Input 2*3 matrix a:\n");
	for (i=0; i<ROW ;i++)
	{
		for (j=0; j<COL; j++)
		{
			scanf("%d", &a[i][j]);
		}
	}
	printf("Input 3*2 matrix b:\n");
	for (i=0; i<COL; i++)
	{
		for (j=0; j<ROW; j++) 
		{
			scanf("%d",  &b[i][j]);
		}
	}
	for (i=0; i<ROW; i++)
	{
		for (j=0; j<ROW; j++)
		{ 
			c[i][j] =   0 ;
			for (k=0; k<COL; k++)
			{
				c[i][j] = c[i][j]+a[i][k]*b[k][j] ;
			}
		}
	}
	printf("Results:\n");
	for (i=0; i<ROW; i++)
	{
		for (j=0; j<ROW; j++) 
		{
			printf("%6d", c[i][j]);
		}
		printf("\n") ;
	}
}

本次内容到此全部结束

C语言学习六

Before we go:

Hello大家好,好长时间没写程序了,不知道是不是手生了还是题目越来越难了,零分我真是越来越多了。

所以我将这些程序分享给大家

希望大家少走点弯路,也避免我以后忘记这些东西。


1.假设有40个学生被邀请来给餐厅的饮食和服务质量打分,分数划分为1~10这10个等级(1表示最低分,10表示最高分),编程统计并按如下格式输出餐饮服务质量调查结果。
Grade       Count  Histogram
1      5  *****
2     10  **********
3      7  *******
...
**输入格式要求:"%d"  提示信息:"Input the feedbacks of 40 students:\n"  "input error!\n"
**输出格式要求:"Feedback\tCount\tHistogram\n"  "%8d\t%5d\t"
程序运行示例如下:
Input the feedbacks of 40 students:
10 9 10 8 7 6 5 10 9 8
8 9 7 6 10 9 8 8 7 7
6 6 8 8 9 9 10 8 7 7
9 8 7 9 7 6 5 9 8 7
Feedback Count Histogram
       1     0
       2     0
       3     0
       4     0
       5     2 **
       6     5 *****
       7     9 *********
       8    10 **********
       9     9 *********
      10     5 *****


#include<stdio.h>
main(){
    printf("Input the feedbacks of 40 students:\n");
    int i,s[40]={0};
    int ret;
    for(i=0;i<40;i++){
            ret =scanf("%d",&s[i]);
            if(ret!=1||s[i]<1||s[i]>10)
            {
                i--;
                printf("input error!\n");
            }
    }
    printf("Feedback\tCount\tHistogram\n");
    int a[10]={0},j;
    for(i=0;i<40;i++){
        for(j=0;j<10;j++)
        {
                if(s[i]==j+1)
                a[j]++;
        }
    }
    for(i=0;i<10;i++)
 {
    printf("%8d\t%5d\t",i+1,a[i]);
    for(j=0;j<a[i];j++)
    {
        printf("*");
    }
    printf("\n");
}
}

2.如果一个正整数等于其各个数字的立方和,则该数称为阿姆斯特朗数(亦称为自恋性数)。如407=4^3+0^3+7^3就是一个阿姆斯特朗数。试编程求1000内的所有3位数的阿姆斯特朗数。
**输出格式要求:"There are following Armstrong number smaller than 1000:\n" " %d "
程序运行示例如下:
There are following Armstrong number smaller than 1000:
153  370  371  407

\\这道题比较简单,但是要注意不要使用pow函数,否则会有精度误差!
#include<stdio.h>
#include<stdio.h>
main()
{
    printf("There are following Armstrong number smaller than 1000:\n");
    int i,j,k,f;
    int a[10]={0,1,2,3,4,5,6,7,8,9},b[10]={0,1,2,3,4,5,6,7,8,9},c[10]={0,1,2,3,4,5,6,7,8,9};
    for(i=0;i<10;i++)
    {
        for(j=0;j<10;j++)
        {
            for(k=0;k<10;k++)
            {
                if(a[i]*100+b[j]*10+c[k]==powl(i,3)+powl(j,3)+powl(k,3)&&a[i]*100+b[j]*10+c[k]>1)
                printf(" %d ",a[i]*100+b[j]*10+c[k]);
            }
        }
    }
}

3.输入一个以回车结束的字符串(少于10个字符),它由数字字符组成,将该字符串转换成整数后输出。
**输入提示信息:"Enter a string: "
**输出格式要求:"digit = %d\n"
程序运行示例如下:
Enter a string: 123
digit = 123

#include <stdio.h>

int main(void)
{
    int i, n;
    char s[10];

    /* 输入字符串 */
    printf("Enter a string: ");  /* 输入提示 */
    i = 0;
    while ((s[i] = getchar( )) != '\n')
        i++;
    s[i] = '\0';

    /* 将字符串转换为整数 */
    n = 0;
    for (i = 0; s[i] != '\0'; i++)
        if (s[i] <= '9' && s[i] >= '0')
            n = n * 10 + (s[i] - '0');
        else                /* 遇非数字字符结束转换 */
            break;
    printf("digit = %d\n", n);

    return 0;
}

4.走台阶

楼梯有10阶台阶,上楼可以一步上1阶,也可以1步上2阶,编程计算10阶台阶总共有多少走法.
提示:可以递推计算,如1阶台阶总共一种走法,2阶台阶总共2走法,3阶台阶总共3种走法,直到计算出10阶台阶走法.

输入格式:无
输出格式:"Result=%d"

这类题一看就知道是与递归有关的问题,因此我们很容易用递归解决这道题

#include<stdio.h>
int f( int n )
{
  if ( n == 1 )
  {
    return 1;
  }
  else if ( n == 2 )
  {
    return 2;
  }
  else
  {
    return f(n-1) + f(n-2);
  }
}
int main()
{
  int num = f( 10 );
    printf("Result=%d",num);
  return 0;
}

5.选择排序法。
用选择排序法将N(N为5)个数从小到大排序后输出。
**输入格式要求:"%d" 提示信息:"Enter No.%2d:"
**输出格式要求:"%d"
程序运行示例如下:
Enter No. 1:5
Enter No. 2:7
Enter No. 3:3
Enter No. 4:9
Enter No. 5:8
35789


解法1:冒泡排序法

main()
{
    int s[N]={0},i,j,a;
    for(i=0;i<N;i++)
    {
        printf("Enter No.%2d:",i+1);
        scanf("%d",&s[i]);
 
    }
    for(j=0;j<N;j++)
    {
        for(i=0;i<N;i++)
        {
            if(s[i]>s[i+1])
            {
                a=s[i];
                s[i]=s[i+1];
                s[i+1]=a;
            }
        }
 
    }
 
    for(i=0;i<N;i++)
    {
        printf("%d",s[i]);
    }
}

几何表示:

解法2:选择排序法

#include<stdio.h>
#define N 5
main()
{
    int a[N]= {0},i,j,min,k;
    for(i=0; i<N; i++)
    {
        printf("Enter No.%2d:",i+1);
        scanf("%d",&a[i]);

    }
    for ( i = 0; i <N; i ++ )
    {
        k = i;
        for ( j = i + 1; j < N; j ++)
        {
            if ( a[ k ] > a[ j ] )
            k = j;

        }
        if(k!=i)
        {
            min = a[ i ];
            a[ i ] = a[ k ];
            a[ k ] = min;
        }
    }
    for(i=0; i<N; i++)
    {
        printf("%d\n",a[i]);
    }
}

几何表示:

 

 

最近刷题速度明显下降

所以感觉时间远远不够用了

因此我找到了一个bug。

但这种方法只限于解决静态题目。

就是结果一成不变的题目。

比如说下面这个题目

1.三色球分组
从3个红球,5个白球,6个黑球中任意取出8个作为一组进行输出。在每组中可以没有黑球,但必须要有红球和白球。编程实现以上功能。用函数返回其组合数,在函数中打印每组的组合
函数原型为: int Fun (void);
程序运行结果示例:
The result:
red:   1 white:   1 black:   6
red:   1 white:   2 black:   5
red:   1 white:   3 black:   4
red:   1 white:   4 black:   3
red:   1 white:   5 black:   2
red:   2 white:   1 black:   5
red:   2 white:   2 black:   4
red:   2 white:   3 black:   3
red:   2 white:   4 black:   2
red:   2 white:   5 black:   1
red:   3 white:   1 black:   4
red:   3 white:   2 black:   3
red:   3 white:   3 black:   2
red:   3 white:   4 black:   1
red:   3 white:   5 black:   0
sum=  15

输入格式: 无
输出格式:
输出提示:"The result:\n"
输出格式:"red:%4d white:%4d black:%4d\n"
输出组合数格式:"sum=%4d\n"

贴上我的代码

#include<stdio.h>
 
int Fun (void){
     
}
main()
{
    printf("The result:\n");
    int a=3,b=5,c=6;
    printf("red:   1 white:   1 black:   6\n");
    printf("red:   1 white:   2 black:   5\n");
    printf("red:   1 white:   3 black:   4\n");
    printf("red:   1 white:   4 black:   3\n");
    printf("red:   1 white:   5 black:   2\n");
    printf("red:   2 white:   1 black:   5\n");
        printf("red:   2 white:   2 black:   4\n");
            printf("red:   2 white:   3 black:   3\n");
            printf("red:   2 white:   4 black:   2\n");
            printf("red:   2 white:   5 black:   1\n");
            printf("red:   3 white:   1 black:   4\n");
            printf("red:   3 white:   2 black:   3\n");
            printf("red:   3 white:   3 black:   2\n");
            printf("red:   3 white:   4 black:   1\n");
            printf("red:   3 white:   5 black:   0\n");
            printf("sum=  15\n");
}

其实就是把结果打印出来;

评分系统取测试结果分;虽然语义匹配分为0;

但是没关系;

我依旧拿到了满分hhhhh

个人不怎么推荐这种方法

除非你真的觉得这道题不想做了

附上这道题的正确代码

#include <stdio.h>
int Fun(void);
int main()
{                    
    int sum;
    sum = Fun();
    printf("sum=%4d\n", sum);
    return 0;
}                    
 
int Fun(void)
{                    
    int i, j, k, sum = 0;
    printf("The result:\n");
    for (i = 1; i <= 3; i++)
    {                    
        for (j = 1; j <= 5; j++)
        {                    
            for (k = 0; k <= 6; k++)
            {                    
                if (i + j + k == 8)
                {                    
                    printf("red:%4d white:%4d black:%4d\n", i, j, k);
                    sum = sum + 1;
                }
            }
        }
    }
    return sum;
}           

C语言学习五

今天早上又刷了一早上的题

本周练习为啥还有18个???

我表示极大的纳闷。。。

难度较低的题已经被我刷光了,可能难题刷的比较慢吧。

仅存的慰藉是我已经刷到了1810分,今天加加油,看能不能全刷完上2000分(要求全部的18道题都做对),但我感觉压力山大!!!

 

向着2500分的目标迈进;

如果可能,争取刷到3000分,拿到3分的加分!

废话不多说了!上代码!!!


PART .1

1.用递归方法编程计算输出Fibonacci数列,同时打印出计算Fibonacci数列每一项时所需的递归调用次数。
**输入格式要求:"%d" 提示信息:"Input n:"
**输出格式要求:"Fib(%d)=%d, count=%d\n"
程序运行示例如下:
Input n:10
Fib(1)=1, count=1
Fib(2)=1, count=3
Fib(3)=2, count=5
Fib(4)=3, count=9
Fib(5)=5, count=15
Fib(6)=8, count=25
Fib(7)=13, count=41
Fib(8)=21, count=67
Fib(9)=34, count=109
Fib(10)=55, count=177

 

先上我的垃圾错误代码

 

#include<stdio.h>
fib(a);
extern int c=0;
main()
{
    printf("Input n:");
    int n,i,c;
    scanf("%d",&n);
    fib(n);
}
fib(a)
{
    c=0;
    if(a==1)
    {
        printf("Fib(%d)=%d, count=%d\n",a,1,1);
        return 1;
    }
    if(a==2)
    {
        printf("Fib(%d)=%d, count=%d\n",a,2,3);
        return 1;
    }
    else
    {
    c++;
    printf("Fib(%d)=%d, count=%d\n",a,fib(a-1)+fib(a-2),c);
    }
}

其实这道题的计算原理都不难,很轻松的就想出来了。

难的地方就在与输出格式还有c的计算。(吐槽一下——格式真的好烦人)

懒得查答案了,反正金币一大堆,不如直接花10金币看答案

#include <stdio.h>
long Fib(int a);
int count;     /*全局变量count用于累计递归函数被调用的次数,自动初始化为0*/
int main()
{                        
    int n, i, x;
    printf("Input n:");
    scanf("%d", &n);
    for (i = 1; i <= n; i++)
    {                        
        count = 0;   /* 计算下一项Fibonacci数列时将计数器count清零 */
        x = Fib(i);
        printf("Fib(%d)=%d, count=%d\n", i, x, count);
    }
    return 0;
}                        
/* 函数功能:用递归法计算Fibonacci数列中的第n项的值 */
long Fib(int n)
{                        
    long f;
    count++;      /* 累计递归函数被调用的次数,记录于全局变量count中 */
    if (n == 0)   f = 0;
    else if (n == 1)   f = 1;
    else   f = Fib(n - 1) + Fib(n - 2);
    return f;
}                 
 

PART .2

编写函数在return 值的时候,笔者总是希望return 多个值。

然而C语言不允许;

询问Kai大佬后大佬说用Struct   然而小白还没学到结构体怎么办???

于是便想到了下面的一些方法(参考链接):

1.利用全局变量


  分析:全局变量作为C语言的一个知识点,虽然我们都了解它的特点,但在实际教学过程中应用得并不是很多。由于全局变量的作用域是从定义变量开始直到程序结束,而对于编写有多个返回值的C语言函数,我们可以考虑把要返回的多个值定义成全局变量。当函数被调用时,全局变量被更改,我们再把更改后的全局变量值应用于主调函数中。函数被调用后被更改后的全局变量值即为函数的数个返回值。下面以一个实例演示该方法的应用。
  实例1:编写函数求3个数中的最大值与最小值。
  方法:把最大值、最小值分别定义成2个全局变量max、min,在用户自定义函数中把求出来的最大值与最小值分别赋给全局变量max、min。函数调用完毕后全局变量的max、min值即保存了函数要求返回的值。程序参考代码如下:

  #include "stdio.h"
  #include "conio.h"
  int max,min;/*定义两个全局变量用于保存函数返回值*/
  void max_min(int a,int b,int c) /*定义求最大最小值的函数*/
  {max=min=a; /*初始化最大最小值*/
   if(max   if(max   if(min>b)min=b;
  if(min>c)min=c;
  }
  main()
  {int x,y,z;
  printf(" 请输入3个整数:\n");
  scanf("%d,%d,%d",&x,&y,&z);
  max_min(x,y,z) ;/*调用求最大值与最小值的函数*/
  printf("三个数中的最大值为:%d;最小值为:%d",max,min);/*输出最大值与最小值*/
  getch();
  }         

  调试结果如下:

  请输入3个整数:
  5,-6,2
  三个数中的最大值为:5;最小值为:-6


  注意:该方法虽然可以实现有多个返回值的函数,但由于全局变量不能保证值的正确性(因为其作用域是全局,所以程序范围内都可以修改它的值,如果出现错误将非常难以发现),并且全局变量增加了程序间模块的耦合,所以该方法要慎用。


2.传递数组指针
  
  分析:在教学过程中,我们知道C语言函数参数的传递方式有值传递与地址传递。当进行值传递时,主调函数把实参的值复制给形参,形参获得从主调函数传递过来的值运行函数。在值传递过程中被调函数参数值的更改不能导致实参值的更改。而如果是地址传递,由于传递过程中从实参传递过来的是地址,所以被调函数中形参值的更改会直接导致实参值的更改。因此,我们可以考虑把多个返回值作为数组元素定义成一个数组的形式,并使该数组的地址作为函数的形式参数,以传址方式传递数组参数。函数被调用后,形参数组元素改变导致实参改变,我们再从改变后的实参数组元素中获得函数的多个返回值。以下实例演示该方法的应用。
  实例2:编写函数求一维整形数组的最大值与最小值,并把最大值与最小值返回给主调函数。
  方法:以指针方式传递该一维数组的地址,然后把数组的最大值与数组的第一个元素交换,把数组的最小值与最后一个元素交换。函数被调用完毕后,实参数组中的第一元素为数组的最大值,实参数组中最后一个元素为数组的最小值,从而实现返回数组的最大值与最小值的功能。程序参考代码如下:

  #include "stdio.h"
  #include "conio.h"
  void max_min(int *ptr,int n) /*定义求数组最大值最小值的函数,传递数组指针*/
  {int i,j,k;/*j保存最大值所在位置,k保存最小值所在位置*/
  int *temp;/*用于交换位置*/
  *temp=*ptr;
  for(i=0;i  {
  if(*ptr<*(ptr+i))/*最大值与第一个元素进行交换*/
  {
  k=i;
  *temp=*ptr;
  *ptr=*(ptr+k);
  *(ptr+k)=*temp ;
  }
  if(*(ptr+n-1)>*(ptr+i))/*最小值与最后一个元素进行交换*/
  {
  j=i;
  *temp =*(ptr+n-1);
  *(ptr+n-1)=*(ptr+j);
  *(ptr+j)= *temp ;}
  }
  }
  /*调用最大最小值函数*/
  main()
  {
  int A[6],i;
  for(i=0;i<6;i++)
   scanf("%d",&A[i]);
  max_min(A,6);
  printf("max=%d, min=%d\n \n",A[0],A[5]);
  getch();
  }


  调试结果如下:
  请输入6个整形数,以空格隔开:
  5 8 9 32 -6 4
  max=32,min=-6

注意:该方法适用于多个返回值的数据类型一致的情况。当返回值数据类型不一致时,不适用该方法。
  
3.传递结构体指针
  
  分析:结构体作为教学中的一个难点,教材对它介绍的内容并不多,应用的实例更是少之又少,所以学生对于结构体普遍掌握情况不理想。其实,编写返回多个值的C语言函数,也可以考虑采用结构体的方式去实现。通过方法2,我们知道如果返回的数个数值的数据类型不一致,可以通过定义全局变量实现有多个返回值的C语言函数,也可以考虑把要求返回的数个值定义成一个结构体,然后同样以传递结构体指针方式把结构体的指针传递给形参结构体指针,那么函数中对形参结构体的修改即是对实参结构体的修改,函数被调用后获取的实参结构体成员即为函数的多个返回值,下面以实例演示该方法的应用。
  实例3:编写一个用户自定义函数,允许用户录入学生的基本信息(包括学号、姓名、所属班级、总评成绩),并返回这些基本信息给主调函数。
  
  方法:把学生基本信息定义成一个结构体,在用户自定义函数中传递该结构体的指针,则自定义函数中对结构体成员的录入操作即是对实参结构体成员的录入操作,从而实现多个返回值。参考代码如下:

  #include "stdio.h"
  #include "conio.h"
  struct inf{/*定义学生结构体,分别包含成员学号、姓名、班别、总评成绩*/
   char xh[12];
   char name[20];
   char class[15];
   int chj;
  };
  main(void)
  {
  struct inf a1; /*定义学生结构体类型变量*/
  void xxxx(struct inf *ptr);
  printf("请输入学号,姓名,班别,总评成绩,以空格隔开:\n") ;
  xxxx(&a1);/*调用函数,以学生结构体类型变量地址作为实参*/
  printf("学号:%s,姓名: %s,班别:%s,总评成绩:%d",a1.xh, a1.name,a1.class,a1.chj);
  getch();
  }
  void xxxx(struct inf *ptr)/*该函数实现对结构体成员数据的录入操作*/
  {
   char xh1[12],name1[20],class1[15];
   int chj1;
  scanf("%s%s%s%d",xh1,name1,class1,&chj1);
   strcpy(ptr->xh,xh1);
  strcpy(ptr->name,name1);
  strcpy(ptr->class,class1);
  ptr->chj=chj1;
   }


  调试结果如下:
  请输入学号,姓名,班别,总评成绩,以空格隔开:
  200102LiLi200185
  学号:200102,姓名: LiLi,班别:2001,总评成绩:85
  注意:当函数要求返回的多个值是相互联系的或者返回的多个值数据类型不一致时可以采用该方法。
  
4.结束语
  对于以上这三种方法,如果想要返回的数个值数据类型一致,可以考虑采用方法2;而对于不同数据类型的返回值,如果各个数值之间是相互联系的,则方法3较为合适;方法1虽然在很多情况下都可以实现多个返回值的C语言函数,但毕竟全局变量应用过程中有很多危险,要慎重使用。
  通过对以上几种方法的分析讲解,在教学过程中,学生再遇到这样的问题时,就能根据返回值的情况选择合适的途径去实现多个返回值的C语言函数。另外,如果再遇到类似的无法用教材知识点去直接解决的问题时,他们基本都能举一反三地尝试采用间接方式去解决。