Advertisement

这些关于数组的基础知识点你都知道吗?

阅读量:

各位同学,你觉得你数组学会了吗?不妨看看下面的问题,你能看一眼程序就回答上来吗?

引子:观察下面的程序,这个程序有安全隐患吗?

复制代码
 #include<stdio.h>

    
  
    
 int main() {
    
  
    
     int x = 0;
    
     double sum = 0;
    
     int number[100] = { 0 };
    
     int cnt = 0;
    
  
    
     scanf("%d", &x);
    
     while (x != -1) {
    
         number[cnt] = x;
    
         sum += x;
    
         cnt++;
    
         scanf("%d", &x);
    
     }
    
  
    
     if (cnt > 0) {
    
         int i = 0;
    
         double average = sum / cnt;
    
         for (i = 0; i < cnt; i++) {
    
             if (number[i] > average)
    
                 printf("number %d: %d\n", i, number[i]);
    
         }
    
     }
    
  
    
 }
    
    
    
    

答案是有的 while循环种没有限制 cnt 有可能导致 数组越界

不能快速找到错误和找不到错误其实是一样的 ,因为不能快速找到这个错误说明你没有深刻的理解数组。这种基础的概念如果没有渗透到你的脑中,并不能说自己学好了数组吧!我学了一学期C,课设1000行代码都是自己独立完成的。依然没有立刻看出这个问题来,我也是自愧没有学好啊!

数组特性与一个注意

1.数组是一种容器(放东西的东西)
2.基本特点是:

  • 其中所有元素具有相同的数据类型
  • 一旦创建,不能改变大小
  • 在内存中连续依次排列

3.注意:
数组作为函数参数时,往往必须再用另一个参数来传入数组的大小
我们常用sizeof(arr) / sizeof(arr[0])来判断数组元素个数
但是这种情况下不能在函数中用sizeof(arr)判断数组大小

例1

//写一个程序,输入数量不确定的【0 ~ 9】范围内的整数,统计每一种数字出现的次数,输入 -1 表示结束

方法一:先看一个基础做法

复制代码
 #include<stdio.h>

    
  
    
 int main() {
    
  
    
     const int number = 10;//记录数组元素。用const修饰,数组大小规定后不可改变
    
     int count[10] = { 0 };
    
     int i = 0;
    
     int input = 1;
    
  
    
     while (input + 1) {//避免输入0时退出,-1 + 1 = 0 刚好满足退出要求
    
         printf("input a number\n");
    
         scanf("%d",&input);
    
         switch (input) {
    
             case 0:
    
                 count[0]++;
    
                 break;
    
             case 1:
    
                 count[1]++;
    
                 break;
    
             case 2:
    
                 count[2]++;
    
                 break;
    
             case 3:
    
                 count[3]++;
    
                 break;
    
             case 4:
    
                 count[4]++;
    
                 break;
    
             case 5:
    
                 count[5]++;
    
                 break;
    
             case 6:
    
                 count[6]++;
    
                 break;
    
             case 7:
    
                 count[7]++;
    
                 break;
    
             case 8:
    
                 count[8]++;
    
                 break;
    
             case 9:
    
                 count[9]++;
    
                 break;
    
              default:
    
                  break;
    
         }
    
  
    
  
    
  
    
     for (i = 0; i < 10; i++) 
    
         printf("%d:%d times\n", i, count[i]);
    
  
    
     return 0;
    
 }
    
    
    
    

方法2

当我们要统计的数是像 0 ~ 9 这样连续的数时,我们可以把数组下标与这些数一一对应起来,可以更方便,快捷

复制代码
 #include<stdio.h>

    
  
    
 int main() {
    
  
    
     int count[10] = { 0 };
    
     int i = 0;
    
     int input = 1;
    
     int error = 0;
    
  
    
  
    
     //更简单的方法:
    
     while (input + 1) {
    
         printf("input a number\n");
    
         scanf("%d", &input);
    
         if (input >= 0 && input <= 9)
    
             count[input]++;
    
         if (input == -1) 
    
                 break;
    
     }
    
  
    
     for (i = 0; i < 10; i++) {
    
         printf("%d:%d times\n", i, count[i]);
    
     }
    
  
    
     return 0;
    
 }
    
    
    
    

思考一下:字符常量可以做数组下标吗?
例如,形如arr['a'] 可以吗?

如果可以,那么当我们想要统计字符串种某个字母(或者任何ASCII码表上存在的字符)的具体个数时,就会很方便。可以自己尝试着写一下哦~思路和上面的数字判断差不多。
我写的供大家参考:https://github.com/hairrrrr/win.ccode/blob/master/Pactise/2020WinterVacation/Array/统计每个字母出现的次数(可拓展到统计所有ascii表内出现的字符次数).c


例2

复制代码
 #include<stdio.h>

    
  
    
 #define N 10 //数组元素个数
    
  
    
 int search(int want, int lenth, int* arr) {
    
  
    
     int right = lenth - 1;
    
     int left = 0;
    
     int mid = 0;
    
     int ret = 0;
    
  
    
     while (right >= left) {
    
         mid = (right + left) / 2;
    
         if (want > arr[mid])
    
             left = mid + 1;
    
         if (want < arr[mid])
    
             right = mid - 1;
    
         if (want == arr[mid]) {
    
             ret = mid;
    
             break;
    
         }
    
  
    
     }
    
  
    
     if (right < left)
    
         return -1;
    
     else
    
         return ret;
    
 }
    
  
    
 int main() {
    
  
    
     int arr[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    
     int lenth = sizeof(arr) / sizeof(arr[0]);//计算数组大小
    
     int want = 0;
    
     int index = 0;
    
  
    
     printf("input the number you want to search\n");
    
     scanf("%d", &want);
    
  
    
     index = search(want, lenth, arr);//切记:数组作为函数参数时,往往必须再用另一个参数来传入数组的大小
    
  
    
     if (index == -1)
    
         printf("Can't find!\n");
    
     else
    
         printf("the index of %d: %d\n", want, index);
    
  
    
     return 0;
    
 }
    
    
    
    

二维数组

1.初始化

int a[][3] = {{1, 1, 1}, {2, 2, 2}, {3},}
1.列数必须给出,行数可以空出
2.每行都有有一个单独的大括号 { }(可以不写,建议写上)
3.最后的逗号可以写上,老一代程序员们约定俗成的经验(如果你写上,可以装装逼)
4.缺省表示补零
5.强烈推荐的另一种书写方式:

复制代码
>       1. int a[][3] = {

>  
>       2.      {1, 1, 1},
>  
>       3.      {2, 2, 2},
>  
>       4.      {3},
>  
>       5. }
>  
>  
>  
>  
> ```
>
>
>
> 这样写的好处不言而喻,更加形象立体
>
>

#### 练习题

1.

若有定义:int a[2][3].则下列不越界的正确访问有:  
A: a[2][0]  
B: a[2][3]  
C: a[1 > 2][0]  
D: a[0][3]

2.

以下程序片段输出的结果是:

int m[][3] = {1, 4, 7, 2, 5, 8, 3, 6, 9,}

int i, j, k = 2;

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

printf("%d",m[k][j]);

}

复制代码
A: 369  
B: 不能通过编译  
C:789  
D:能编译,但是数组下标越界了

3

若有int a[][3] = {{0}, {1}, {2}};  
a[1][2] 的值是?

>
>
> 答案:C A 0
>
>

全部评论 (0)

还没有任何评论哟~