C语言 数组



  • 数组

    数组是一种数据结构,可以存储相同类型的元素的固定大小的顺序集合。数组用于存储数据集合,但是将数组视为相同类型的变量集合通常会更有用。无需声明单个变量(例如,number0,number1,...和number99),而是声明一个数组变量(例如,numbers),并使用numbers [0],numbers [1]和...,numbers [99]表示各个变量。数组中的特定元素由索引访问。所有数组均包含连续的内存位置。最低地址对应于第一个元素,最高地址对应于最后一个元素。
    images
  • 声明数组

    在要在C中声明数组,程序员可以指定元素的类型和数组所需的元素数量,如下所示-
    
    type arrayName [ arraySize ];
    
    
    这称为一维数组。arraySize必须是整数大于零的常数和类型可以是任何有效的C数据类型。例如,要声明一个称为double类型的balance的10元素数组,请使用以下语句-
    
    double balance[10];
    
    
    这里的balance是一个可变数组,足以容纳10个double。
  • 初始化数组

    您可以在C中一个接一个地初始化数组,也可以使用单个语句来初始化数组,如下所示:
    
    double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
    
    
    大括号{}之间的值的数量不能大于我们为方括号[]之间的数组声明的元素数。如果省略数组的大小,则会创建一个大小足以容纳初始化的数组。因此,如果您写-
    
    double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
    
    
    您将创建与上一个示例完全相同的数组。以下是分配数组的单个元素的示例-
    
    balance[4] = 50.0;
    
    
    上面的语句为数组中的第5个元素赋值为50.0。所有数组的第一个元素的索引都为0,也称为基索引,而数组的最后一个索引为数组的总大小减去1。下面显示的是我们上面讨论的数组的图形表示-
    images
  • 访问数组元素

    通过索引数组名称来访问元素。这是通过将元素的索引放在数组名称后面的方括号内来完成的。例如-
    
    double salary = balance[9];
    
    
    上面的语句将从数组中获取第10个元素,并将值分配给salary变量。以下示例显示如何使用上述所有三个概念。声明,赋值和访问数组-
    
    #include <stdio.h>
     
    int main () {
    
       int n[ 10 ]; /* n is an array of 10 integers */
       int i,j;
     
       /* initialize elements of array n to 0 */         
       for ( i = 0; i < 10; i++ ) {
          n[ i ] = i + 100; /* set element at location i to i + 100 */
       }
       
       /* output each array element's value */
       for (j = 0; j < 10; j++ ) {
          printf("Element[%d] = %d\n", j, n[j] );
       }
     
       return 0;
    }
    
    
  • 数组详细知识

    数组对C很重要,应该多加注意。C程序员应该清楚以下与数组有关的重要概念-
    多维数组 - C支持多维数组。多维数组的最简单形式是二维数组。
    声明:
    
     type name[size1][size2]...[sizeN];
    
    
    例如,以下声明创建三维整数数组-
    
     int threedim[5][10][4];
    
    
    多维数组的最简单形式是二维数组。本质上,二维数组是一维数组的列表。要声明大小为[x] [y]的二维整数数组,应编写如下内容:
    
    type arrayName [ x ][ y ];
    
    
    其中type可以是任何有效的C数据类型,而arrayName是有效的C标识符。可以将二维数组视为具有x个行和y个列的表。包含三行四列的二维数组a可以显示如下-
    images
    因此,数组a中的每个元素都由a [i] [j]形式的元素名称标识,其中“a”是数组的名称,“i”和“j”是唯一标识下标的元素“a”中的每个元素。“i”是一维的索引,“j”是二维的索引。
    可以通过为每行指定括号中的值来初始化多维数组。以下是具有3行的数组,每行有4列。
    
    int a[3][4] = {  
       {0, 1, 2, 3} ,   /*  initializers for row indexed by 0 */
       {4, 5, 6, 7} ,   /*  initializers for row indexed by 1 */
       {8, 9, 10, 11}   /*  initializers for row indexed by 2 */
    };
    
    
    指示所需行的嵌套括号是可选的。以下初始化等效于先前的示例-
    
    int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
    
    
    通过使用下标(即数组的行索引和列索引)访问二维数组中的元素。例如-
    
    int val = a[2][3];
    
    
    上面的语句将从数组的第三行获取第4个元素。您可以在上图中进行验证。让我们检查以下程序,其中我们使用了嵌套循环来处理二维数组-
    
    #include <stdio.h>
     
    int main () {
    
       /* an array with 5 rows and 2 columns*/
       int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};
       int i, j;
     
       /* output each array element's value */
       for ( i = 0; i < 5; i++ ) {
    
          for ( j = 0; j < 2; j++ ) {
             printf("a[%d][%d] = %d\n", i,j, a[i][j] );
          }
       }
       
       return 0;
    }
    
    
    将数组传递给函数 - 您可以通过指定不带索引的数组名称,将指向数组的指针传递给该函数。
    如果要在函数中将一维数组作为参数传递,则必须使用以下三种方式之一声明一个形式参数,并且所有三种声明方法都将产生相似的结果,因为每种方法都告诉编译器整数指针正在运行被接收。同样,您可以将多维数组作为形式参数传递。
    方式1- 指针作为形式参数
    
    void myFunction(int *param) {
       .
       .
       .
    }
    
    
    方式2- 数组尺寸作为形式参数
    
    void myFunction(int param[10]) {
       .
       .
       .
    }
    
    
    方式3- 未调整大小的数组作为形式参数
    
    void myFunction(int param[]) {
       .
       .
       .
    }
    
    
    现在,考虑以下函数,该函数将数组作为参数以及另一个参数,并基于传递的参数,返回通过数组的数字的平均值,如下所示:
    
    double getAverage(int arr[], int size) {
    
       int i;
       double avg;
       double sum = 0;
    
       for (i = 0; i < size; ++i) {
          sum += arr[i];
       }
    
       avg = sum / size;
    
       return avg;
    }
    
    
    现在,让我们调用上述函数,如下所示:
    
    #include <stdio.h>
     
     
    /* function declaration */
    double getAverage(int arr[], int size);
    
    int main () {
    
       /* an int array with 5 elements */
       int balance[5] = {1000, 2, 3, 17, 50};
       double avg;
    
       /* pass pointer to the array as an argument */
       avg = getAverage( balance, 5 ) ;
     
       /* output the returned value */
       printf( "Average value is: %f ", avg );
        
       return 0;
    }
    
    
    从函数返回数组 - C允许函数返回数组。
    C语言不允许将整个数组作为函数的参数返回。但是,您可以通过指定不带索引的数组名称来返回指向数组的指针。 如果要从函数返回一维数组,则必须声明一个返回指针的函数,如以下示例所示:
    
    int * myFunction() {
       .
       .
       .
    }
    
    
    要记住的第二点是C不主张将局部变量的地址返回到函数外部,因此您必须将局部变量定义为静态变量。 现在,考虑以下函数,该函数将生成10个随机数并使用数组返回它们,并按如下所示调用此函数:
    
    #include <stdio.h>
     
    /* 生成并返回随机数的函数 */
    int * getRandom( ) {
    
       static int  r[10];
       int i;
    
       /* set the seed */
       srand( (unsigned)time( NULL ) );
      
       for ( i = 0; i < 10; ++i) {
          r[i] = rand();
          printf( "r[%d] = %d\n", i, r[i]);
       }
    
       return r;
    }
    
    /* 调用上面定义的函数的main函数 */
    int main () {
    
       /* a pointer to an int */
       int *p;
       int i;
    
       p = getRandom();
            
       for ( i = 0; i < 10; i++ ) {
          printf( "*(p + %d) : %d\n", i, *(p + i));
       }
    
       return 0;
    }
    
    
    指向数组的指针 - 您可以通过简单地指定数组名称而无需任何索引来生成指向数组第一个元素的指针。
    在您通读“指针”一章之前,您很可能不了解本节。 假设您对C中的指针有一些了解,让我们开始:数组名称是指向数组第一个元素的常量指针。因此,在声明中-
    
    double balance[50];
    
    
    balance是指向&balance[0]的指针,它是数组balance的第一个元素的地址。因此,以下程序片段将p分配为balance的第一个元素的地址-
    
    double *p;
    double balance[10];
    
    p = balance;
    
    
    将数组名称用作常量指针是合法的,反之亦然。因此,*(balance + 4)是访问balance[4]数据的合法方法。一旦将第一个元素的地址存储在'p'中,就可以使用* p,*(p + 1),*(p + 2)等访问数组元素。下面给出的示例显示了上面讨论的所有概念-
    
    #include <stdio.h>
     
    int main () {
    
       /* an array with 5 elements */
       double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
       double *p;
       int i;
    
       p = balance;
     
       /* output each array element's value */
       printf( "Array values using pointer\n");
            
       for ( i = 0; i < 5; i++ ) {
          printf("*(p + %d) : %f\n",  i, *(p + i) );
       }
    
       printf( "Array values using balance as address\n");
            
       for ( i = 0; i < 5; i++ ) {
          printf("*(balance + %d) : %f\n",  i, *(balance + i) );
       }
     
       return 0;
    }
    
    
    在上面的示例中,p是指向double的指针,这意味着它可以存储double类型的变量的地址。一旦我们在p中有了地址,* p将为我们提供在p中存储的地址处可用的值,如上面的示例所示。