嵌入式0基础开始学习 ⅠC语言(5)数组

0.问题引入

            定义一个整型变量
                int a;
            如果要你来定义100个整型变量
              int a0,a1,a2,a3,...,a100
            很显然,上面的方法不是很聪明的样子
            有没有一种办法,让我们一次定义一组相同类型的变量呢?
            
            =>数组

1.什么是数组?

        一组具有相同类型的数据元素的有序集合
        有序:一段有序的存储空间
        
        在c语言中,数组:
                   一维数组
                   二维数组
                   三维数组
                   ....
            其实,C语言中只有一维数组
           

2.一维数组

        2.1定义格式

                如:
                       int a[10];
                       //a[0] a[1] ...a[9]
                
                类型说明符  数组名[整型表达式];
                or
                类型说明符  数组名[整型表达式] = {初始化列表};
                
                “类型说明符”:指定数组中每一个元素的类型,不是数组的类型!!!
                             可以是c语言中任意合法的类型(基本类型,构造类型,指针类型)
                            
                             typeof(a[0]) => int:数组中元素的类型
                             typeof (a)   => int[10] :整个数组的类型
                            
                ”数组名“ :
                            对象的名字,“标识符”
                            给数组取名字的时候,要符合C语言标识符的规定
                            
                整型表达式:
                            指定数组中数据元素的个数。
                            C语言规定在定义数组时,需要指定(隐含指定-编译器可以推断出)数组元素的个数
                            “常量表达式”
                            
                            int a = 5;
                            int b[a];//以前不能够通过编译的,现在ubuntu优化了。
                            建议大家在定义数组的时候,还是使用常量表达式。
                            
                        例子:
                              int a[5];//定义一个数组,数组名为a,里面有5个int类型的元素
                                         int是数组元素的类型,并不是数组a的类型
                                    

        2.2一维数组的引用

                    
                    int a[10];//定义了一个数组,数组名为a,里面含有10个int类型的元素
                            如何来访问(引用)这些元素呢?

                            引用数组元素:
                                           数组名[下标]
                                        “下标”    :C语言规定数组元素的下标是从0开始
                                                   0,1,2,3,4,...,n-1(n是表示,数组有n个元素)

                                引用数组元素和引用普通变量是一模一样的。
                                数组元素也是有左值和右值。
                                    
                                    int a[10];
                                    int b;
                                    a[0] = 1024; //把数值1024赋值给元素a[0]    
                                                 //a[0]代表元素a[0]的地址,把数值1024
                                                   存放到a[0]的地址中去。
                                    b = a[0];//把a[0]的值赋值给b,a[0]代表元素a[0]的值(右值)

        2.3一维数组在内存中的存放

                在C语言中,用一组连续的存储空间,从低地址到高地址
                依次存放数组中的每一个元素。
                    
                        如;
                             int a[10];
                             a[0]-------0x3000
                             a[1]-------0x3004
                            
                    练习;
                          1.请大家写一个程序,验证一下,数组的存储方式
                              int a[5];
                                      &a[0] ==>取元素a[0]的地址;
                                    printf("%p\n",&a[0]);
                                    printf("%p\n",&a[1]);
                                    .....
                            完整的C语言代码;
                                             #include <stdio.h>
                                              int main()
                                              {
                                                  int a[5];
                                                  for(int i =0;i<5;i++)
                                                  {
                                                     printf("%p\n",&a[i]);
                                                  }
                                              }
                              2.定义一个一维数组,通过键盘来给每一个元素赋值
                             再依次输出数组中元素的值。                            
                                    #include <stido.h>
                                    int main()
                                    {
                                       int a[5];
                                       for(int i = 0;i<5;i++)
                                       {
                                          scanf("%d",&a[i]);
                                       }
                                       for(int i=0;i<5;i++)
                                       {
                                          printf("%d\n",a[i]);
                                       }
                                    }
       

        2.4 一维数组的初始化
                   

                    类型说明符  数组名 [整型表达式] = {初始化列表};
                    初始化: 是指定义对象时,就指定对象的值。
                             数组的初始化使用{}
                            
                            例子;
                                    int a[5];
                                    printf("%d\n",a[0]);//undefine 未知的
 
                   (1)在定义一个数组时,给每一个元素进行初始化
                                int a[10] = {0,1,2,3,4,5,6,7,8,9};
                     
                   (2)可以只对前面的元素进行初始化,后面的元素会自动初始化为0
                                int a[10] = {1,2,3};
                                    a[0] =1;
                                    a[1] = 2;
                                    ..
                                    a[3] = 0;
                                    ....
                                    a[9] = 0;                                    
                                int a[10] = {0};//将数组中的每一个元素都初始化为0
                                
                    (3)如果对全部元素都赋初始值,在定义数组的时候,可以不指定数组的长度(元素个数)
                         编译器可以自己推断出你有多少个元素
                               int a[] = {1,2,3,4,5};
                               ===>
                               int a[5] = {1,2,3,4,5};
                               
                               int a[]={0};
                               ===>
                               int a[1] ={0};
                               
                          NOTE:只有在定义数组时,指定数组全部元素的值
                                只能在初始化时,给数组整体赋值

                                
                                int a[5] = {1,2,3,4,5};//OBJK
                                int a[5];
                                    a[5] = {1,2,3,4,5};//ERROR
                                    a = {1,2,3,4,5};//ERROR                                    
                    
            练习:
                    1.定义一个一维数组,并从键盘随机输入每一个元素的值,
                      求该一维数组的元素之和,最大值,最小值。
                        #include <stdio.h>
                         int main()
                        {
                          int a[10];
                          int i;
                          int sum =0;                          
                          for(i=0;i<10;i++)
                          {
                             scanf("%d",&a[i]);
                          }
                          int max =a[0];
                          int min = a[0];
                          for(i=0;i<10;i++)
                          {                            
                             sum += a[i];
                             if(a[i]>max)
                             {
                                max = a[i];
                             }
                             if(a[i]<min)
                             {
                               min = a[i];
                             }
                          }
                          printf("sum = %d,max=%d,min=%d\n",sum,max,min);
                        }                        
                       
                    2.判断一个一维数组是否递增
                    思路:
                            a[0]<=a[1]<=a[2]<=....a[n-1]
                            只要找到一个》符号,那么就能证明这个数组就不是递增。
                            a[i] PK a[i+1]                            
                       #include <stdio.h>
                       int main()
                       {
                          int a[10];
                          int i;
                          for(i=0;i<10;i++)
                          {
                             scanf("%d",&a[i]);
                            
                          }
                          int flag =0;// 0 -递增;1- 不是递增
                          for(i=0;i<9;i++)
                          {
                             if(a[i]>a[i+1])
                             {
                                flag = 1;
                                break;
                             }
                          }
                          if(flag==1)
                          {
                            printf("NO");
                          }
                          if(flag==0)
                          {
                            printf("YES");
                          }
                       }
                     

3.排序的问题

        把数组中的每一个元素按一定的规律(升序或降序)放置到合适的位置上面去。
        
        冒泡排序 <-----
        希尔排序
        快速排序
        选择排序 <-----
        插入排序
        堆排序
        .....
       

    冒泡排序:

             相邻的两个元素,两两比较,把较大者往后移(升序)
                   “两两比较”
                   
                   假设有N个元素:
                   
                   第0趟排序:
                              if(a[0]>a[1])
                                  a[0]<->a[1]
                              if(a[1]>a[2])
                                  a[1]<->a[2]
                                  
                              if(a[N-2]>a[N-1])
                                  a[N-2]<->a[N-1]
                                  
                            序列中,最大值已经保存到a[N-1]
                            
                        =>
                             i来表示数组元素的下标
                             所以:要比较的式子可以用i来替代
                                    if(a[i]>a[i+1])
                                        a[i]<->a[i+1]
                                    
                                    for(i=0;i<N-1;i++)
                                    {
                                       if(a[i]>a[i+1])
                                       {
                                          int temp;
                                          temp = a[i];
                                          a[i] = a[i+1];
                                          a[i+1] = temp;
                                       }
                                    }
                    第一趟排序:
                              if(a[0]>a[1])
                                  a[0]<->a[1]
                              if(a[1]>a[2])
                                  a[1]<->a[2]
                                  
                              if(a[N-3]>a[N-2])
                                  a[N-3]<->a[N-2]
                            此时,序列中,第二大的值已经保存在a[N-2]

                        =>
                             i来表示数组元素的下标
                             所以:要比较的式子可以用i来替代
                                if(a[i]>a[i+1])
                                        a[i]<->a[i+1]
                                     
                                    for(i=0;i<N-2;i++)
                                    {
                                        if(a[i]>a[i+1])
                                       {
                                          int temp;
                                          temp = a[i];
                                          a[i] = a[i+1];
                                          a[i+1] = temp;
                                       }
                                    }
                            
                            只需要将上面的冒泡,进行N-1趟,就可以把所有的元素都放置在合适的位置上面
                            每一趟冒泡的代码形式都一样的,所以说,只要将上面的代码,想办法让他循环N-1,
                            那么整个序列就有序了嘛!!!
                            
                            for(m=0;m<N-1;m++) //冒泡趟数 N:代表的是数组元素个数
                            {
                                for(i=0;i<N-1-m;i++)//数组下标范围
                                {
                                   if(a[i]>a[i+1])
                                   {
                                      int temp;
                                      temp = a[i];
                                      a[i] = a[i+1];
                                      a[i+1] = temp;
                                   }
                                }
                            }
                            printf();
                            
                        m 用来标记第m趟冒泡      第m趟冒泡要比较多少次
                            m = 0                     N-1(i<N-1)
                            m = 1                     N-2(i<N-1-1)
                            m = 2                     N-3(i<N-1-2)
                            m = x                     N-1-x(i<N-1-m)
                        

    选择排序

            (1)选择一个最大的元素(遍历数组)
            (2)把最大的元素与最后面一个位置的元素进行交换
                
            times =1:表示第一次选择排序
                     int max = a[0];
                     int max_i = 0;
                     for(i=0;i<N;i++)
                     {
                         if(a[i]>max)
                         {
                            max = a[i];
                            max_i = i;
                         }
                        
                     }
                     if(max_i !=N-1)
                     {
                        a[max_i]<->a[N-1];
                     }
                    
            times = 2:表示第二次选择排序
                    int max = a[0];
                    int max_i = 0;
                    for(i = 0;i<N-1;i++)
                    {
                         if(a[i]>max)
                         {
                           max = a[i];
                           max_i = i;
                         }
                    }
                    if(max_i !=N-2)
                    {
                       a[max_i]<-->a[N-2];
                    }
                    
            times = t:表示第t次交换
                    int max = a[0];
                    int max_i = 0;
                    for(i = 0;i<N-t+1;i++)
                    {
                         if(a[i]>max)
                         {
                           max = a[i];
                           max_i = i;
                         }
                    }
                    if(max_i != N-t)
                    {
                       a[max_i]<-->a[N-t];
                    }
                    
            第几次选择交换     数组下标的范围   交换位置
               times = 1            i<N            N-1
               times = 2            i<N-1          N-2
               .....
               times = t            i<N-t+1        N-t
               
               最多需要选择交换N-1次
               for(t=1;t<N;t++)
               {
                    int max = a[0];
                    int max_i = 0;
                    for(i = 0;i<N-t+1;i++)
                    {
                         if(a[i]>max)
                         {
                           max = a[i];
                           max_i = i;
                         }
                    }
                    if(max_i != N-t)
                    {
                       a[max_i]<-->a[N-t];
                    }
                    
               } 

4.查找一个元素

        在数组a[N]查找一个元素x,如果找到了就返回下标,没有找到就返回-1
        (1)查找可以用“遍历”
              for(i=0;i<N;i++)
                {
                   if(a[i]==x)
                   {
                      return i;
                   }
                }    
               return -1;

        (2)在一个有序数组中查找,用遍历,就显得有点LOW。
              “二分查找法”/“折半查找法”

        练习:
               在一个有序的数组中,去查找一个值为x的元素
               找到了就打印其下标,没有找到,那么打印:没有此元素  4

                int L,R;
                int a[N];
                int i,x;
                for(i=0;i<N;i++)
                {
                   scanf("%d",&a[i]);
                }
                scanf("%d",&x);
                L = 0;
                R = N-1;
                
                while(L<=R)
                {
                    mid =(L+R)/2;
                    if(a[mid]<x)//x比中间元素大,所以舍弃mid以及它左边的
                    {
                       L = mid +1;
                    }
                    else if (a[mid]>x)//x比中间元素小,所以舍弃mid以及它右边的
                    {
                       R = mid -1;
                    }
                    else
                    {
                      printf("x=>%d\n",mid);//mid表示下标
                    }
                }
                //没有找到值为x的那一个元素
            
总结:
            1.数组概念问题
            
            2.一维数组
                   2.1 定义
                   2.2 数组元素的引用
                   2.3 数组元素的存储问题
                   2.4 数组的初始化
            
            3.排序
                  冒泡
                  选择
                      时间复杂度:o(n^2)
                      
            4.二分查找法
            
练习:
         1.求斐波拉契数列的前20项之和
               斐波拉契数列
                        1 1 2 3 5 8 13 21
                        a[i] = a[i-1]+a[i-2]
                    
                    S1: 先求第i项 =>ai
                    S2: 累加sum +=ai
                    
                    int a[20] = {0};
                    a[0] = a[1] = 1;
                    sum = a[0]+a[1];
                    for(i=2;i<20;i++)
                    {
                       a[i] = a[i-1] + a[i-2];
                       sum +=a[i];
                    }
                            
         2.不用排序,把一个数组中的负数放置数组的前面
               如;
                    2 4 -3 5 -4 8 -2
                   -2 -3 -1 1 2 3 4
                            i
                思路:
                       用一个i来记录负数存放的下标
                       用j来遍历数组,遇到负数,那么就交换
                         a[i]<--->a[j]
                          i++,
                       继续从下标为j的地方遍历数组
                       
                       int a[N];
                       i = 0; //存放负数的下标
                       for(j=0;j<20;j++)
                       {
                         
                          if(a[j]<0)   //交换位置,并且i+1
                          {
                             a[i]<->a[j];
                             i++;
                          }
                       }
         3.不用排序,求数组中第二大的那一个元素的值(只能遍历一次)
                思路;
                       int max;
                       int max_2;
                       max = a[0]>a[1]?a[0]:a[1];
                       max_2 = a[0]>a[1]?a[1]:a[0];

                      for(i=2;i<N;i++)
                    {
                       if(a[i]>max)
                       {
                          max_2 = max;
                          max = a[i];
                       }
                       else
                       {
                         if(a[i]>max_2)
                         {
                           max_2 = a[i];
                         }
                       }
                    } 

回顾一下,一维数组
          定义格式:
                   元素类型   数组名[数组元素的个数];
                例子:
                      int a[4];//定义了一个数组,数组名为a,里面有4个int类型的元素。
                              //在定义数组a的时候,也声明了一个新类型
                                “像a这样的类型”
                                typeof(a) =》int [4]
                                a[0] int
                                a[1] int
                    
                    问题:  定义3个像a这样类型的变量,该如何定义
                             元素类型  数组名 [数组元素个数]
                             typeof(a) b [3];
                        ==>   int [4] b[3];
                          
                        ==>   int b[3][4];  //二维数组
                            b的含义:b是一个数组,里面含有3个int[4]类型的元素                            

5.二维数组

          由上面的推导过程可以得出
                        c语言中,二维数组实际上就是一个一维数组,只不过该一维数组中的每一个元素
                        又是一个一维数组
                    
                    例子:   int b[3][4]
                                   <=>int[4] b[3];
                                   数组名为b,里面有三个元素
                                      b[0] _ _ _ _》里面含有4个int类型的元素,b[0]又是一个数组,数组名b[0]
                                      b[1] _ _ _ _》里面含有4个int类型的元素,b[1]又是一个数组,数组名b[1]
                                      b[2] _ _ _ _》里面含有4个int类型的元素,b[2]又是一个数组,数组名b[2]
                                      
                            矩阵角度来看;
                                           三行四列                            
                       

        5.1二维数组的定义格式
    


                从矩阵角度来说
                        类型说明符   数组名[行数][列数]    
                
                连续的存储空间,从低地址到高地址
                按行存放,先顺序存放第0行的元素,然后再存放第一行的元素
                
            练习:
                  1.请大家,来验证一下,二维数组的元素存储方式
                    #include <stdio.h>
                    int main()
                    {
                       int a[3][4];
                       
                       i = 0;
                            a[0] _ _ _ _
                            printf("%p\n",&a[0][0])
                               printf("%p\n",&a[0][1])    
                            printf("%p\n",&a[0][2])    
                            printf("%p\n",&a[0][3])    
                        for(j=0;j<4;j++)
                        {
                           printf("%p\n",&a[0][j])
                        }
                       
                      i = 1;
                           a[1] _ _ _ _
                            printf("%p\n",&a[1][0])
                            printf("%p\n",&a[1][1])    
                            printf("%p\n",&a[1][2])    
                            printf("%p\n",&a[1][3])
                        for(j=0;j<4;j++)
                        {
                           printf("%p\n",&a[1][j])
                        }
                    ....
                    
                        for(i=0;i<3;i++)
                        {
                            for(j=0;j<4;j++)
                            {
                               printf("%p\n",&a[i][j]);
                            }
                        }
                    }
                    
                  
                  2.从键盘按行来给二维数组的每一个元素赋值,然后按列打印输出每个数组元素的值
                      1 2 3 4
                      5 6 7 8
                      9 10 11 12
                      
                    #include <stdio.h>
                    #define M 3
                    #define N 4
                    int main()
                    {
                       for(i=0;i<3;i++)
                       {
                         for(j=0;j<4;j++)
                         {
                           scanf("%d",&a[i][j]);
                         }
                       }
                       
                       for(j=0;j<4;j++)
                       {
                         for(i=0;i<3;i++)
                         {
                            printf("%d\n",a[i][j]);
                         }
                       }
                       
                    }
       

        1.2二维数组的引用
                   

                    数组元素的引用:
                                   数组名[下标]
                            
                            例子:   int a[3][4];
                                            //int[4] a[3]
                                            a[0] _ _ X _ //a[0]是一个数组名,里面含有4个int类型的元素
                                            a[1] _ _ _ _                                            
                  
                                    要访问上面的元素X,该如何访问?
                                        数组名[下标]
                                         a[0][2] <==>X
                                        
                                         以矩阵的角度:
                                                        数组名[行号][列号]
                                                        a[0][2]
                                                        
                            引用二维数组的元素和引用普通变量是一模一样,
                            它也有左值和右值之分
                            
                            例子:
                                   a[0][2] = 1024; //把数值1024,写到a[0][2]的存储空间中去(变量的地址)
                                   int b = a[0][2];//把a[0][2]的值,赋值给b(变量的值)
                                   
                                   scanf("%d",&a[0][2])
                                   printf("%d\n",a[0][2]);//右值
                                   printf("%p\n",&a[0][2]);//左值
                                  

        1.3二维数组元素的存放

                连续的存储空间,连续的存储空间,从低地址到高地址
                按行存放,先顺序存放第0行的元素,然后再存放第一行的元素

        1.4二维数组的初始化

                在定义二维数组时,可以指定每个元素或部分元素的初始值。
               
                (1)分行给二维数组赋初值
                        int a[3][4]     = {{1,2,3,4},
                                        {5,6,7,8},
                                        {9,10,11,12}
                                                   }            
                (2)将所有二维数组的初始值写在一个{}内,
                   按数组的排列顺序一一对应各个元素
                        int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
                                  a[0][0] = 1;
                                  a[1][0] = 5;
                                  a[2][3] = 12;
                                  a[2][0] = 9;
                            
                            #define M 3
                            #define N 4
                            int a[M][N]
                          ===>int a[3][4]
                                a[3][4],很显然越界了!!!(段错误)
       
                (3)对部分元素赋初始值,其余的元素自动置0
                        int a[3][4]={{1,2},{5},{9,10,11}};
                          <=> {{1,2,0,0},{5,0,0,0},{9,10,11,0}};
                          
                (4)如果对全部元素都赋初始值,则定义二维数组时,对一维数组的长度可以省略
                   但是第二维的长度不能省略
                        int [][4] = {1,2,3,4,5,6,7,8,9,10,11};
                
                NOTE:
                      只有在数组定义时,才能对数组整体赋值。

            练习;
                   1.定义一个二维数组,将数组中的元素随机进行初始化,然后要求该二维数组
                     的所有元素之和,最大值,最小值。

                   2.把一个二维数组,行列互换
                        1 2 3 4               1 5 9
                        5 6 7 8               2 6 10
                        9 10 11 12    ===>    3 7 11
                                              4 8 12
                                              
                             #include <stido.h>                            
                            #define M 3
                            #define N 4
                            int a[M][N] = {1,2,3,4,5,6,7,8,9,10,11,12};
                            int b[N][M];
                             for(int i =0;i<N;i++)
                             {
                               for(int j = 0;j<M;j++)
                               {
                                  b[i][j] = a[j][i];
                               }
                             }
                             //按行输出b
                             for(int i =0;i<N;i++)
                             {
                                for(int j = 0;j<M;j++)
                                {
                                    printf("%d ",b[i][j]);
                                }
                                printf("\n");
                             }
                            
                   3.实现矩阵乘法
                        A[M][K] * B[K][N] = C[M][N]
                        
                        {1 2 4    { 1 2         7(1*1 +2*3 +4*0)    26 (1*2+2*2+4*5)
                         2 0 3}  *  3 2     =   2 (2*1+0*3+3*0)     19(2*2+0*2+3*5)
                                    0 5 }
                    第一个的列数必须要等于第二个的行数    
                     #include <stdio.h>
                    #define M 3
                    #define N 4
                    #define K 2
                    int main()
                    {
                        int A[M][K];
                        int B[K][N];
                        int C[M][N] = {0};
                        int i, j, k;
                        printf("给数组A[3][2]赋值:\n");
                        for(i = 0; i < M; i++)
                        {
                            for(j = 0; j < K; j++)
                            {
                                scanf("%d", &A[i][j]);
                            }
                        }
                        printf("给数组B[2][4]赋值:\n");
                        for(i = 0; i < K; i++)
                        {
                            for(j = 0; j < N ; j++)
                            {
                                scanf("%d", &B[i][j]);
                            }
                        }
                        //-------矩阵乘法---------------
                        for(i = 0; i < M; i++)
                        {
                            for(j = 0; j < N; j++)
                            {
                                /*
                                C[i][j] :
                                        i = 0, j = 0 :
                                            A[i][0] * B[0][j] +
                                            A[i][1] * B[1][j] +
                                            ......
                                            A[i][K-1]* B[K-1][j]
                                */
                                
                                C[i][j] = 0;
                                for(k = 0; k < K; k++)
                                {
                                    C[i][j] += A[i][k] * B[k][j];
                                }    
                            }
                        }
                        for(i = 0; i < M; i++)
                        {
                            for(j = 0; j < N; j++)
                            {
                                printf("%d ", C[i][j]);
                            }
                            printf("\n");
                        }
                    }

6.关于数组的类型

            关于xxx的类型,给它定性
            它是个什么东西。
            
            int a[4] //a是一个含有4个int类型元素的数组
                 typeof(a) =》int [4]
                
            float b[10] //b是一个含有10个float类型的数组
                typeof(b) => float [10]
                
            int a[3][4] //a是一个含有3个元素并且每个元素又含有4个int类型元素的数组
                typeof(a) ==>int[4] [3]
               

7.回顾

        关于数组定义:
                     数组元素的类型  数组名[元素个数];
                    
            二维数组:
                      可以从矩阵的角度来看:
                           几行几列
                        元素的类型  数组名[行号][列号]
                        
            二维数组的元素引用:
                      数组名[行下标][列下标]
                      
            二维数组的存储;
                     连续的存储空间,从低地址到高地址
                     从第0行开始,按顺序存储每一个元素。
            
            二维数组的初始化:
                     只能省略行号不能省略列号
                    
将一个整数m,插入到一个升序的数组(一维数组)中去,使得插入后,数组a仍然有序。
                把一个m,插入到有序数组中去,使得插入后仍然有序
            (1)找到插入的位置
                 a,遍历数组
                       从头开始,一个一个去找,找到数组中第一个比m大的那一个元素,那么,那个元素的
                       位置,就是我要插入m的位置
                        for(i=0;i<N;i++)
                        {
                           if(a[i]>m)
                           {
                              //找到了
                              //待插入的位置,下标为i
                               break;
                           }
                        }
                 b,折半查找法
                       通过分析:
                    当循环结束后,那么得到待插入的位置pos
                        
                        if(a[mid] > m) //往中间插入,或往数组最前面插入一个元素
                        {
                            pos = mid ;
                        }
                        else if(a[mid] == m)
                        {
                            pos = mid; //找到了元素的值为m,那么这个元素的位置就是m要插入的位置
                        }
                        else //a[mid] < m  往数组最后面去插入一个元素
                        {
                            pos = mid+1;
                        }
            (2)插入操作
                    假设待插入元素的位置是 pos  
                    将pos及其以后的元素,统统往后移(给待插入元素腾出位置)
                    再将m赋值给 a[pos]
                    int L, R, mid, pos; //L 记录数组左边的下标
                                    //R 记录数组右边的下标
                                    //mid 记录 L,R的中间的下标
                                    //pos 记录待插入的位置的下标
                            L = 0;
                            R = n-1;

                            while(L <= R)
                            {
                                mid = (L + R)/2;
                                if(a[mid] > m)
                                {
                                    R = mid - 1;
                                }
                                else if(a[mid] < m)
                                {
                                    L = mid + 1;
                                }
                                else //a[mid] == m
                                {
                                    //pos = mid;
                                    break;
                                }
                            }

                            if( a[mid] == m )
                            {
                                pos = mid;
                            }
                            else if(a[mid] > m)
                            {
                                pos = mid;
                            }
                            else //a[mid] < m
                            {
                                pos = mid+1;
                            }
                            
                            //(2) 插入m
                            for(i = N-2; i >= pos; i--)
                            {
                                a[i+1] =  a[i];
                            }
                            a[pos] = m;
                            }

练习
        1.求一个二维数组中山顶元素的个数
           山顶:此处比周围(上下左右)高,就是山顶。
           思路:
                 遍历整个数组,如果此元素比周围的元素值都要大
                 此处就是一个山顶,count++
                 int a[M][N];
                 int count = 0;
                 for(i=0;i<M;i++)
                 {
                   for(j=0;j<N;j++)
                   {
                      if(a[i][j]比上下左右的元素值要大)
                      {
                          count++;
                      }
                   }
                 }
                 a[i][j]比上下左右的元素值要大
                            它比上面大&&比下面大&&比左边大&&比右边大
                            
                            它比上面大:
                                上面不存在元素 || 真比上面大
                                (i==0)         ||   a[i][j]>a[i-1][j]
                            它比下面大:
                                下面不存在元素 ||真比下面大
                                 (i == M-1)    || a[i][j]>a[i+1][j]
                            ....
                            

        2.求一个二维数组中的鞍点
            鞍点:行最大,列最小
            思路;
                   遍历二维数组,看数组是不是一个鞍点
                    for(i=0;i<M;i++)
                 {
                   for(j=0;j<N;j++)
                   {
                      if(a[i][j]是鞍点)
                      {
                          printf("a[%d][%d]==%d\n",i,j,a[i][j]);
                      }
                   }
                 }
                
                 a[i][j]是鞍点
                       a[i][j] 是第i行最大值 &&是第j列的最小值
                       
                定义两个辅助数组:
                      int b[M];//保存每一行的最大值
                      int c[N];//保存每一列的最小值
                      
                    a[i][j] 是第i行的最大值 ==>a[i][j] == b[i]
                &&  a[i][j] 是第j列的最小值 ==>a[i][j] == c[j]
             
                    b[0] = a[0][0]
                    for(j = 0;j<N;j++)
                    {
                       if(a[0][j]>b[0])
                       {
                          b[0] = a[0][j];
                       }
                    }
                    ....
     
                    for(i=0;i<M;i++)
                    {
                        b[i] = a[i][0];
                         for(j = 0;j<N;j++)
                        {
                           if(a[i][j]>b[i])
                           {
                              b[i] = a[i][j];
                           }
                        }
                    }                    
                    c[N]....
                             c[j] = a[i][j]
                    
                    if(a[i][j]==b[i] && a[i][j]==c[j])
                    
                
        3.最长上升子序列的长度(选做)
            1 4 -3 -9 5 9 0
          思路:
                int a[N];
               定义辅助数组L[N]
                L[i]表示以a[i]结尾的最长上升子序列的长度              

         4,以下叙述中错误的是?(C)

A,对于double类型数组,不可以直接用数组名对数组进行整体输入或输出

B,数组名代表的是数组所占存储区的首地址,其值不可改变

C,当程序执行中,数组元素的下标超出所定义的下标范围时,系统将给出“下标越界”的出错信息

D,可以通过赋初值的办法确定数组元素的个数

5,以下程序的输出结果是?(45)

main()

{

int p[8]={11,12,13,14,15,16,17,18};

int i=0,j=0;

while(i++<7)  if(p[i]%2)  j+=p[i];

printf("%d\n",j));

}

6,有以下程序,程序输出的结果是?(25)

main()

{
int i,s=0,t[]={1,2,3,4,5,6,7,8,9};

for(i=0;i<9;i+=2) s+=*(t+i);

printf("%d\n",s);

}

7,有以下程序,如果运行时输入:2 4 6 <回车>,则输出结果为?   (2,0,4)

main()

{

int x[3][2]={0},i;

for(i=0;i<3;i++)   scanf("%d",x[i]);

printf("%3d%3d%3d",x[0][0],x[0][1],x[1][0]);

}

8,有以下程序,以下叙述中正确的是(B)

#include <string.h>  main()

{

char p[]={'a','b','c'},q[10]={'a','b','c'};

printf("%d %d\n",strlen(p),strlen(q));

}

A,在给p,q数组置初值时,系统会自动添加字符串结束符,故输出的长度为3

B,由于p数组中没有字符串结束符,长度不能确定,但q数组中字符串长度为3

C,由于q数组中没有字符串结束符,长度不能确定,但p数组中字符串长度为3

D,由于p,q数组中都没有字符串结束符,故长度不能确定

9,以下能正确定义一维数组的一项是?(B)

A, int a[5]={0,1,2,3,4,5};

B,char a[]={0,1,2,3,4,5};

C,char a={'A','B','C'};

D,int a[5]="0123"

10,设有如下定义,则正确的叙述为(C)

char  x[]={"abcdefg"};

char  y[]={'a','b','c','d','e','f','g'};

A,数组x和数组y等价

B,数组x和数组y长度相同

C,数组x的长度大于数组y的长度

D,数组x的长度小于数组y的长度

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值