C语言数组

1.数组的概念

数组是若干个相同类型的变量在内存中有序存储的集合。

int a[10];//定义了一个整型的数组 a, a 是数组的名字, 数组中有 10 个元素, 每个元素的类型

都是 int 类型, 而且在内存中连续存储

这十个元素分别是 a[0] a[1] a[0]~a[9]在内存中连续的顺序存储


2.数组的分类

2.1按元素的类型分类

1) 字符数组

即若干个字符变量的集合, 数组中的每个元素都是字符型的变量

char s[10]; s[0],s[1]....s[9];

2) 短整型的数组

short int a[10]; a[0] ,a[9]; a[0]=4;a[9]=8;

3) 整型的数组

int a[10]; a[0] a[9]; a[0]=3;a[0]=6;

4) 长整型的数组

lont int a[5];

5) 浮点型的数组(单、 双)

float a[6]; a[4]=3.14f;

double a[8]; a[7]=3.115926;

6) 指针数组

char *a[10]

int *a[10];

7) 结构体数组

struct stu boy[10];


2.2按维数分类

一维数组

int a[30];

类似于一排平房

二维数组

int a[2][30];

二维数组可以看成由多个一维数组构成的。

有行, 有列,

多维数组

int a[4][2][10];

三维数组是由多个相同的二维数组构成的

int a[5][4][2][10];


3.数组的定义

定义一个数组, 在内存里分配空间

3.1一维数组的定义

格式:数据类型 数组名 [数组元素个数];

int a[10];
char b[5];//定义了 5 个 char 类型变量的数组 b,5 个变量分别为 b[0],b[1],b[2],b[3],b[4];
在数组定义的时候可以不给出数组元素的个数, 根据初始化的个数来定数组的大小

例 1:

#include <stdio.h>
int main(int argc, char *argv[])
{
    int a[]={1,2,3,4,5};
    printf("%d\n",sizeof(a));//5*4=20
    return 0;
}

3.2二维数组的定义

格式: 数据类型 数组名[行的个数][列的个数]

int a[4][5];
定义了 20 个 int 类型的变量 分别是
a[0][0] ,a[0][1],a[0][2] ,a[0][3] ,a[0][4];
a[1][0] ,a[1][1],a[1][2] ,a[1][3] ,a[1][4];
a[2][0] ,a[2][1],a[2][2] ,a[2][3] ,a[2][4];
a[3][0] ,a[3][1],a[3][2] ,a[3][3] ,a[3][4];

3.3多维数组定义

int a[3][4][5];
int a[8][3][4][5];
扩展:二维数组在定义的时候, 可以不给出行数, 但必须给出列数, 二维数组的大小根据初始化的行数来定

例 2:

#include <stdio.h>
int main(int argc, char *argv[])
{
    int a[][3]={
        {1,2,3},
        {4,5,6},
        {7,8,9},
        {10,11,12}
    };
    printf("%d\n",sizeof(a));
    return 0;
}

4.定义并初始化

开辟空间的同时并且给变量赋值

4.1一维数组的初始化

a、 全部初始化
int a[5]={2,4,7,8,5};
代表的意思: a[0]=2; a[1]=4;a[2]=7;a[3] = 8;a[4]=5;
b、 部分初始化
int a[5]={2,4,3};//初始化赋值不够后面补 0
a[0] = 2; a[1]= 4;a[2]=3;a[3]=0;a[4]=0;
注意: 只能省略后面元素, 可以不初始化, 不能中间的不初始化

例 3:

#include <stdio.h>
int main(int argc, char *argv[])
{
    int a[5]={2,3,5};
    int i;
    for(i=0;i<5;i++)
    {
        printf("a[%d]=%d\n",i,a[i]);
    }
    return 0;
}
a[0]=2
a[1]=3
a[2]=5
a[3]=0
a[4]=0

4.2二维数组的定义并初始化

4.2.1按行初始化

a、 全部初始化
int a[2][2]={{1,2},{4,5}};
a[0][0] =1; a[0][1] = 2; a[1][0] = 4,a[1][1]=5;
b、 部分初始化
int a[3][3]={{1,2},{1}};
a[0][0] = 1;a[0][2] =0;

int a [2][3]={2,5,4,2,3,4};
int a[2][3]={3,5,6,8};

5. 数组元素的引用方法

5.1一维数组元素的引用方法

数组名 [下标];

下标代表数组元素在数组中的位置

int a[10];

a[2];


5.2 二维数组元素的引用方法

数组名[行下标][列下标];

int a[3][4];

a[1][2]

例 4:

#include <stdio.h>
int main(int argc, char *argv[])
{
    int a[3][4]={{1,2,3,4},{5,6},{5}};
    int b[3][4]={11,12,13,14,15,16,17,18,19};
    int i,j;
    for(i=0;i<3;i++)//遍历所有行
    {
        for(j=0;j<4;j++)//遍历一行的所有列
        {
            printf("a[%d][%d]=%d ",i,j,a[i][j]);
        } 
        printf("\n");
    } 

    for(i=0;i<3;i++)//遍历所有行
    {
        for(j=0;j<4;j++)//遍历一行的所有列
        {
            printf("b[%d][%d]=%d ",i,j,b[i][j]);
        } 
        printf("\n");
    } 
    return 0;
}

6.字符数组的定义

char c1[] ={‘c’ ,’ ’ ,’ p’ ,’ r’ ,’ o’ ,’ g’ };
char c2[] = “c prog” ;
char a[][5] = {
{‘B’ ,’ A’ ,’ S’ ,’ I’ ,’ C’ },
{‘d’ ,’ B’ ,’ A’ ,’ S’ ,’ E’ }
};
char a[][6] = {“hello” ,“world” };

7.字符数组的引用

1.用字符串方式赋值比用字符逐个赋值要多占 1个字节,用于存放字符串结束标志‘\0’ ;

2.上面的数组 c2 在内存中的实际存放情况为:

注: '\0'是由 C 编译系统自动加上的

3.由于采用了'\0'标志, 字符数组的输入输出将变得简单方便.

例 5:

int main( )
{
    char str[15];
    printf("input string:\n");
    scanf("%s",str);//hello
    printf("output:%s\n",str);
    return 0;
}

8. 传递数组给函数

8.1 方式 1

形式参数是一个指针(您可以在下一章中学习到有关指针的知识):

void myFunction(int *param){.
.
.
}

8.2 方式 2

形式参数是一个已定义大小的数组:

void myFunction(int param[10]){.
.
.
}

方式 3

形式参数是一个未定义大小的数组:

void myFunction(int param[]){.
.
.
}

实例

现在,让我们来看下面这个函数,它把数组作为参数,同时还传递了另一个参数,根据所传的参数,会返回数组中元素的平均值:

double getAverage(int arr[], int size)
{  
  int    i;
  double avg;
  double sum;
   for (i = 0; i < size; ++i)
  {
    sum += arr[i];
  } 
  avg = sum / size;
   return avg;
}

现在,让我们调用上面的函数,如下所示:

//实例
#include <stdio.h> 
/* 函数声明 */
double getAverage(int arr[], int size);

int main ()
{
   /* 带有 5 个元素的整型数组 */
   int balance[5] = {1000, 2, 3, 17, 50};
   double avg;
    /* 传递一个指向数组的指针作为参数 */
   avg = getAverage( balance, 5 ) ;
    /* 输出返回值 */
   printf( "平均值是: %f ", avg );
       return 0;
} 
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;
}

当上面的代码被编译和执行时,它会产生下列结果:

平均值是: 214.400000
您可以看到,就函数而言,数组的长度是无关紧要的,因为 C 不会对形式参数执行边界检查。

9. 从函数返回数组

C 语言不允许返回一个完整的数组作为函数的参数。但是,您可以通过指定不带索引的数组名来返回一个指向数组的指针。我们将在下一章中讲解有关指针的知识,您可以先跳过本章,等了解了 C 指针的概念之后,再来学习本章的内容。

如果您想要从函数返回一个一维数组,您必须声明一个返回指针的函数,如下:

int * myFunction(){.
.
.
}

另外,C 不支持在函数外返回局部变量的地址,除非定义局部变量为 static 变量。

现在,让我们来看下面的函数,它会生成 10 个随机数,并使用数组来返回它们,具体如下:

实例

#include <stdio.h>
#include <stdlib.h>
#include <time.h> 

/* 要生成和返回随机数的函数 */
int * getRandom( )
{
  static int  r[10];
  int i;
   /* 设置种子 */
  srand( (unsigned)time( NULL ) );
  for ( i = 0; i < 10; ++i)
  {
     r[i] = rand();
    printf( "r[%d] = %d\n", i, r[i]);
   } 
  return r;
} 
/* 要调用上面定义函数的主函数 */
int main ()
{
   /* 一个指向整数的指针 */
   int *p;
   int i;
    p = getRandom();
   for ( i = 0; i < 10; i++ )
   {
       printf( "*(p + %d) : %d\n", i, *(p + i));
   } 
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

r[0] = 313959809
r[1] = 1759055877
r[2] = 1113101911
r[3] = 2133832223
r[4] = 2073354073
r[5] = 167288147
r[6] = 1827471542
r[7] = 834791014
r[8] = 1901409888
r[9] = 1990469526
*(p + 0) : 313959809
*(p + 1) : 1759055877
*(p + 2) : 1113101911
*(p + 3) : 2133832223
*(p + 4) : 2073354073
*(p + 5) : 167288147
*(p + 6) : 1827471542
*(p + 7) : 834791014
*(p + 8) : 1901409888
*(p + 9) : 1990469526

10. 指向数组的指针

数组名是一个指向数组中第一个元素的常量指针。因此,在下面的声明中:

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 ()
{
   /* 带有 5 个元素的整型数组 */
   double balance[5] = {1000.0, 2.0, 3.4, 17.0, 50.0};
   double *p;
   int i;
    p = balance;
    /* 输出数组中每个元素的值 */
   printf( "使用指针的数组值\n");
   for ( i = 0; i < 5; i++ )
   {
       printf("*(p + %d) : %f\n",  i, *(p + i) );
   } 
   printf( "使用 balance 作为地址的数组值\n");
   for ( i = 0; i < 5; i++ )
   {
       printf("*(balance + %d) : %f\n",  i, *(balance + i) );
   } 
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

使用指针的数组值
*(p + 0) : 1000.000000
*(p + 1) : 2.000000
*(p + 2) : 3.400000
*(p + 3) : 17.000000
*(p + 4) : 50.000000
使用 balance 作为地址的数组值
*(balance + 0) : 1000.000000
*(balance + 1) : 2.000000
*(balance + 2) : 3.400000
*(balance + 3) : 17.000000
*(balance + 4) : 50.000000
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值