zoukankan      html  css  js  c++  java
  • 小学生都看得懂的C语言入门(3): 数组与函数

    #include <stdio.h>
    int main()
    {
    int x;
    double sum=0;
    int cnt=0;
    scanf("%d",&x){
        sum+=x;
        cnt++;
        scanf("%d",&x);
    }
    printf("the mean is %d",sum/cnt);
    

    这是之前求平均数的代码, 

    上述没有记录每一个输入的数, 一旦输入就加上去, 没有记录
    //现在问题变了, 需要你求平均数 并且输出大于平均数的值 , 那么有必要记录每一个
    输入的数字, 如何实现?

    现在需要用到数组进行记录. 在上述代码基础上增加 number[10] 定义,在while 循环中增加number[cnt]=x记录输入的值

    #include <stdio.h>
    int main()
    {
    int x;
    double sum=0;
    int number[10];  //长度是10的数组, 可以放10个int 
    int cnt=0;
    scanf("%d",&x);
    while(x!=-1){
        number[cnt]=x; //记录 赋值 
        sum+=x;
        cnt++;
        scanf("%d",&x);
    }
    if (cnt>0){
        printf("the mean is %f
    ",sum/cnt);
        
        int i; //遍历每一个数 找到大于平均数的值 
        for(i=0;i<cnt;i++){
            if(number[i]>sum/cnt){
            printf("%d
    ",number[i]); 
        } 
    } 
    }
    return 0;
    }

    为了清楚的知道number[cnt]=x 的存储机制,增加一段调试代码

    #include <stdio.h>
    int main()
    {
    int x;
    double sum=0;
    int number[10];  //长度是10的数组, 可以放10个int 
    int cnt=0;
    scanf("%d",&x);
    while(x!=-1){
        number[cnt]=x; //记录 赋值 
        // --用于调试 
        {
            int i;
            printf("%d	",cnt);
            for(i=0;i<=cnt;i++){ 
                printf("%d	",number[i]);
            }
        }printf("
    "); 
        //--用于调试 
        sum+=x;
        cnt++;
        scanf("%d",&x);
    }
    if (cnt>0){
        printf("the mean is %f
    ",sum/cnt);
        
        int i; //遍历每一个数 找到大于平均数的值 
        for(i=0;i<cnt;i++){
            if(number[i]>sum/cnt){
            printf("%d
    ",number[i]); 
        } 
        
    } 
    }return 0; 
    }

     

    这是每次的number 数组的存储情况,再输入-1终止计算,得到

    但是上述存在很明显的问题: 定义了number [10] ,如果实际输入了超过10 怎么办?

    别急啊, 首先掌握下数组的定义

    int grades[100];

    double weight[20];

    数组的特点: 1.数组中的每个元素具有相同的数据类型, 2. 一旦创建数组, 之后不能改变大小,

    int a[10] 的顺序是 a[0], a[1],... a[9] ,[] 中的数字是索引, 索引从0开始计数!!

    编译器不会检查数组下标是否越界, 越界就出现segmentation fault ,

    int a[0] 可以存在, 但是没有任何用处..

    实例: 输入数量不定的在[0,9]之间的整数, 统计每一种数字出现的次数, 输入-1表示结束

    程序如下, 用一个10元数组来作为计数器,

    #include <stdio.h>
    int main(void)
    {
        const int num=10; //num决定数组大小 
        int x;
        int i;
        int cnt[num];
        for (i=0;i<num;i++){
            cnt[i]=0;
        } //初始化数组的每一个元素, 
        
        scanf("%d",&x);
        while(x!=-1){
            if (x>=0 && x<=9){
                cnt[x] ++;
            }
            scanf("%d",&x);
        } 
        for (i=0;i<num;i++){
            printf("%d出现了%d次
    ",i,cnt[i]);
        }
        return 0;
    }

    结果

    (二) 定义函数

    实例: 求从m -n 之间所有素数的和sum

    #include <stdio.h>
    int main()
    {
        int m,n;
        int sum=0;
        int cnt=0;
        int i;
        // 求素数的和 
        scanf("%d %d",&m,&n); //m=10 n=31
        if (m==1)m=2;
        for (i=m;i<=n;i++){
            int isprime=1;
            int k;
            for (k=2;k<i-1;k++){
            if (i%k==0){
                isprime=0;
                break;
            }
            }
            if(isprime){
                sum+=i;
                cnt++;
            }
        }
        printf("有%d个素数, 和为%d
    ",cnt,sum);
        return 0;
    }

    我们可以将上述素数判别的单独拿出来 形成一个函数.

    #include <stdio.h>
    // 定义一个函数 isprime
    int isprime(int i)
    {
        int ret=1; 
        int k;
        for (k=2;k<i-1;k++){
            if (i%k==0){
                ret=0;
                break;
            }
            }
        return ret;
    }
    //    
    int main()
    {
        int m,n;
        int sum=0;
        int cnt=0;
        int i;
        // 求素数的和 
        scanf("%d %d",&m,&n); //m=10 n=31
        if (m==1)m=2;
        for (i=m;i<=n;i++){
            if(isprime(i)){ 
                sum+=i;
                cnt++;
            }
        }
        printf("有%d个素数, 和为%d
    ",cnt,sum);
        return 0;
    }

    实例 : 求 1-10 , 20-30  35-45 三者的和

     '代码复制是程序不良的表现'!!!! keep it  in mind~~, 不利用与将来程序的维护.

    #include <stdio.h>
    
    void sum(int begin ,int end)
    {
        int i;
        int sum=0;
        for (i=begin;i<=end;i++){
            sum+=i;
        }
        printf("%d到%d 的和是%d 
    ",begin,end,sum);
     } 
        
    int main()
    {
    sum(1,10);
    sum(20,30);
    sum(35,45);
        return 0;
    }

    综合上述两个例子, 我们来看什么是函数, 如何定义?

    void sum(int begin ,int end) 称为函数头, sum是函数名, void 表示函数没有返回的东西, ()内是参数, 参数用逗号, 分开

     以下部分称为函数体

    {
     int i;
     int sum=0;
     for (i=begin;i<=end;i++){
      sum+=i;
     }
     printf("%d到%d 的和是%d ",begin,end,sum);
     }

    函数头中的圆括号很重要, 调用函数也要加(), 否则出错

    #include <stdio.h>
    void fun()
    {
        printf("nihao");
     } 
     int main()
     { 
        fun();   // 要加() !!!
        return 0;
    }

    而判断别素数的函数 是有返回值的

    int isprime(int i)

    函数体中有return ret

    定义一个最大值函数

    int max(int a, int b)
    {
        int ret ;
        if(a>b){
            ret=a;
        }
      else{
          ret=b;
     }
     return ret; 
     }
    #include <stdio.h>
    int max(int a, int b)
    {
        int ret ;
        if(a>b){
            ret=a;
        }
      else{
          ret=b;
     }
     return ret; 
     }
    
    int main()
    {
     int x;
     x=max(10,20);// 将函数值赋给x
     printf("%d
    ",x);
    }

    上述函数头也可以写成 

    #include <stdio.h>
    int max(int a, int b)
    {
        int ret ; if(a>b){
        return a;
        }
      else{
        return b;
    }
    //return ret; 

    但是这样不好, 使得函数有多个出口(多个return), 可行但是不建议用这种!!

    函数可以嵌套用 比如max(10, max(100,11));

    没有返回值的函数 则定义为

    void 函数名(参数表)

    那么之后不能用 return 某个值;

    如果函数有返回值, 则必须使用带值的return.

    注意: 在书写时, 先定义函数再之后进行调用, 不要把函数的定义放在main  后面, 但是也可以通过函数声明实现

    #include <stdio.h>
    
    int max(int a, int b); // 函数声明!! , 加分号!! 也可以不加 参数, int max(int , int )
    int main()
    {
     int x;
     x=max(10,20);// 将函数值赋给x
     printf("%d
    ",x);
    }
    
    int max(int a, int b)
    {
        int ret ;
        if(a>b){
            ret=a;
        }
      else{
          ret=b;
     }
     return ret; 
     }

    其他问题: 

    C语言不允许函数的嵌套定义

    int main () 实际上也是一个函数,

    ---- 二维数组

    int a[3][5]  表示3*5矩阵 

    a[0][0], a[0][1],... a[0][4]

    ..

    a[2][0], a[2][1], ...a[2][4]

     

    int a[][3]={
    {0,1,2},{3,4,5}, 
    };  // 定义数组列数一定要给出, 行数可以不给, 计算机会自己数

     实例:   // tic-tac -toe game, 3*3 矩阵中,写1 或者0 ,当有一行 一列或者对角线

    可以连成线, 则一方胜出, 游戏结束, 如何判别游戏结束?
     遍历每行 每列, 每个对角线 进行判别

    #include <stdio.h>
    int main()
    {
     const int size=3;
     int board[size][size];
     int i,j;
     int n1;
     int n0;
     int result=-1; // -1没有人胜出,1 表示写1方胜出, 0表写0方胜出 
     //下面读入矩阵 
     for (i=0;i<size;i++){
         for(j=0;j<size;j++){
             scanf("%d",&board[i][j]); 
         }
     } 
     
     // 检查行 
     for (i=0;i<size&&result==-1;i++){
         n0=n1=0;
         for(j=0;j<size;j++){
             if(board[i][j]==1){
                 n1++;
             }else{
                 n0++; 
             }
         }
         if (n0==size){
             result=0;
         }else if(n1==size){
             result=1;
         }
     } 
     
      //再检查列 
     if (result==-1){ 
     for (j=0;j<size&&result==-1;j++){
         n0=n1=0;
         for(i=0;i<size;i++){
             if(board[i][j]==1){
                 n1++;
             }else{
                 n0++; 
             }
         }
         if (n0==size){
             result=0;
         }else if(n1==size){
             result=1;
         }
     } 
     } 
    
    // 再检查正对角线 
     if (result==-1){ 
         n0=n1=0;
         for(i=0;i<size;i++){
             if(board[i][i]==1){
                 n1++;
             }else{
                 n0++; 
             }
         }
         if (n0==size){
             result=0;
         }else if(n1==size){
             result=1;
         } 
     } 
     
     // 最后检查次对角线 
     if (result==-1){ 
         n0=n1=0;
         for(i=0;i<size;i++){
             if(board[i][size-1-i]==1){
                 n1++;
             }else{
                 n0++; 
             }
         }
         if (n0==size){
             result=0;
         }else if(n1==size){
             result=1;
         } 
     } 
     
    // 下结论
    if (result==1){
        printf("1 win"); 
    } else if(result==0){
        printf("0 win");
    }else{
        printf("nobody win, have an another try"); 
    }
    
    return 0;
    }

    接下来, 学习数组的搜索等其他

     数据的集成初始化

    #include <stdio.h>
    int main(void)
    {
        int a[]={1,2,3,4};// 数组的集成初始化 
        for (int i=0;i<4;i++){
            printf("%d	",a[i]); 
        }
        
    }

    换一种形式

    #include <stdio.h>
    int main(void)
    {
        int a[4]={1};// 数组的集成初始化 
        for (int i=0;i<4;i++){
            printf("%d	",a[i]); 
        }    
    }

     得到第一个是1 ,后面自动补0

    由此若要初始化一个长度n 的数组a 为0, 只需要int a[n]={0}; 

    对于稀疏数组, 大部分是0 ,只有少数几个值非零, 则可以

    #include <stdio.h>
    int main(void)
    {
        int a[4]={[1]=1,[3]=4};// 没给定义的位置自动填充0 ,但是只有C99 才可以这样做 
        for (int i=0;i<4;i++){
            printf("%d	",a[i]); 
        }    
    }

    如何让编译器自动数数组长度?, 用sizeof

    #include <stdio.h>
    int main(void)
    {
     int a[]={1,2,3,4};
      printf("%d ",sizeof(a)); //16
      printf("%d ",sizeof(a[0])); //4
      printf("数组长度是%d ",sizeof(a)/sizeof(a[0])); 
    }

    得到数组长度是sizeof(a)/sizeof(a[0])

    注意数组的赋值

    #include <stdio.h>
    int main(void)
    {
        int a[]={1,2,3,4};
        int b[]=a; // 错误! 不能这么赋值    
    }

    数组赋值必须采用遍历

     for(int i=0;i<length;i++) {
     b[i]=a[i]; 
     }

    实例:

    #include <stdio.h>
    //搜索一个数是否在数组中存在
    int search(int key, int a[],int length);
    int main(void)
    {
        int a[]={1,2,3,4,10,21,32,18,19};
        int x;
        int loc;
        printf("please input a number
    ");
        scanf("%d",&x);
        int length=sizeof(a)/sizeof(a[0]);
        loc=search(x,a,length); // 调用search函数 
        if(loc!=-1){
            printf("%d在%d位置上
    ",x,loc);
        }else{
            printf("%d doesn't exist
    ",x); 
        }
        return 0;
    }
    
    
    int search(int key, int a[],int length)
    {
        int ret=-1; // 记录key 在数组x 中的位置, 0 表示位置1 
        int i;
        for(i=0;i<length;i++){
            if (a[i]==key){
                ret=i;
                break;
            }
        } 
        return ret; 
    }
    
    // 注意,数组作为函数参数时, 必须再用另一个参数传入该数组的大小,
    //因为不能在[] 中给出数组的大小, 不能再利用sizeof 来计算数组的元素个数 
    ----END---- HAVE A GOOD ONE! 以上为本人课余自学工具书/blog的笔记整理, 常有更新, 非100%原创!且读且学习。
  • 相关阅读:
    014.Nginx跨域配置
    013.Nginx动静分离
    附002.Nginx代理相关模块解析
    附001.Nginx location语法规则
    016.Nginx HTTPS
    015.Nginx重定向
    Blazor带我重玩前端(四)
    数据结构中的树(二叉树、二叉搜索树、AVL树)
    Flask前后端分离项目案例
    LeetCode-位运算相关题解
  • 原文地址:https://www.cnblogs.com/xuying-fall/p/9254695.html
Copyright © 2011-2022 走看看