C语言数组(数据的批量处理)

 2024-01-27 00:03:32  阅读 0

1.谈谈你对数组的理解

数组是一种构造数据类型。 与指针不同,数组在堆栈上静态分配空间,并且空间是连续的。 因为空间是静态分配的,所以数组空间是在定义时分配的。 空间大小无法改变,造成空间利用率低的问题。 为了解决这个问题引入了变长数组和灵活数组。 数组按照维数可以分为一维数组、二维数组、三维数组以及其他数组。 使用数组时,要注意数组的定义、数组的初始化、数组名和数组地址的含义,以及当数组名作为实参、形参的类型时,要注意类型兼容性问题。 区分指针数组、数组指针的用法和应用场景,最后区分指针和数组在空间分配、访问效率、安全性、函数参数等方面的区别和联系。

2. 如何使用数组 1. 定义数组的大小

C89标准:定义必须确定数组长度

整数a[100];

静态分配不灵活,如何解决数组长度不灵活的问题——变长数组(C99标准中)&灵活数组

(1) 变长数组

实现原理:使用变量定义数组大小

它并没有真正解决数组长度的问题。 同时,如果变量没有初始化,则会被随机赋值。 当变量为负数时,就会出现错误。

(2) 灵活阵列

2、一维数组是由元素组成的,组成的单位是元素。

整数a[];

指针常数。 数组名称不能递增或递减。 它存储数组第一个元素的地址。 步长是单个元素的步长。

&A

取数组名的地址就代表数组的地址,步长就是整个数组元素的步长。

*(&a) == a

一维数组的地址等于数组第一个元素的地址。

3、一个二维数组可以看成是由多个一维数组组成,单位是一维数组。

int aa[][];

指针常量,保存一维数组的地址

&aa

二维数组的地址

*(&aa)=aa

二维数组的地址的值等于二维数组中第一个一维数组的地址。

*aa

二维数组中第一个一维数组的第一个元素的地址

4、一个三维数组可以看成是由多个二维数组组成的

int aaa[2][2][2];

1. 定义和初始化

2. 表达式说明:

啊啊

三维数组名,指针常量,保存三维数组中第一个二维数组的地址

*aaa

第一个二维数组中第一个一维数组的地址

**aaa

第一个二维数组中第一个一维数组的第一个元素的地址

***啊啊啊

第一个二维数组中第一个一维数组的第一个元素值

&aaa

三维数组地址

*(&aaa)=aaa

三维数组地址的值等于第一个二维数组的地址

5、示例:使用一维数组、二维数组、三维数组分别实现输入和输出。

#include
int main(int argc,char **argv)
{
    char a[100];
    printf("please input string\n");
    scanf("%s",a);
    printf("str1 = %s\n",a);
    int b[2][2];
    printf("please input number\n");
    for(int i = 0;i<2;i++)
    {
        for(int j = 0;j < 2;j++)
        {
            scanf("%d",&b[i][j]);
        }
    }
     printf("输出结果为\n");
      for(int i = 0;i<2;i++)
    {
        for(int j = 0;j < 2;j++)
        {
            printf("b[%d][%d] = %d\n",i,j,b[i][j]);
        }
    }
    int c[2][2][2];
     printf("please input number\n");
     for(int i= 0;i<2;i++)
    {
        for(int j = 0;j<2;j++)
        {
            for(int k = 0;k<2;k++)
            {
                scanf("%d",&c[i][j][k]);
            }
        }
    }
     printf("输出结果为\n");
    for(int i= 0;i<2;i++)
    {
        for(int j = 0;j<2;j++)
        {
            for(int k = 0;k<2;k++)
            {
                printf("c[%d][%d][%d] = %d\n",i,j,k,*(*(*(c+i)+j)+k));
            }
        }
    }
}

5. 指针数组

字符*pa[3]

数组中存储的元素是指针

1. 注意:

a\Array 未初始化的指针是野指针。 它们的使用方式与指针相同。 使用时必须分配空间。 使用后,必须及时释放空间,留空。

b\向函数传递参数时,传递一维数组指针名称,形参使用二维指针。 因为传递一维数组名时,使用一维数组元素类型的指针。 数组中的元素是指针,指针的指针是二维指针。 尺寸指针。

示例:指针数组的定义和参数传递

#include
void print4(char **pa)
//注意是二维指针,传递数组名,形参是数组类型的指针,数组元素类型是指针,指针的指针不就是二维指针了吗
{
    for(int i = 0;i<3;i++)
    {
        printf("pa[%d] = %s\n",i,pa[i]);
    }
}
int main()
{
    char *pa[3] ={"hello1","hello2","hello3"};
    print4(pa);
}

6. 数组指针

1. 概念

数组的地址存储在数组指针变量中,或者指针指向数组第一个元素的地址。

2. 如何定义

int (* pa) [3]; == int a[3];

pa == &a; *p == a;

注:*和&可以看作互为逆运算

3、数组指针使用场景——函数参数传递

#include
void print1(char *p)
{
    printf("str1 = %s\n",p);
    return;
}
void print2(char (*p)[100])
{
       for(int i = 0;i<2;i++)
    {       
        printf("str[%d] = %s\n",i,p[i]);//*(p + i)
    }
    return;
}
void print3(char (*p)[2][100])
{
     for(int i= 0;i<2;i++)
    {
        for(int j = 0;j<2;j++)
        {
           printf("%s\n",p[i][j]);//*(*(p+i)+j)
        }
    }
    return;
}
int main(int argc,char **argv)
{
    char a[100];
    printf("please input string\n");
    scanf("%s",a);
    print1(a);
    char b[2][100];
    printf("please input string\n");
    for(int i = 0;i<2;i++)
    {
       scanf("%s",b[i]);//*(b + i)
    }
     printf("输出结果为\n");
     print2(b);
    char c[2][2][100];
     printf("please input string\n");
     for(int i= 0;i<2;i++)
    {
        for(int j = 0;j<2;j++)
        {
           scanf("%s",c[i][j]);//*(*(c+i)+j)
        }
    }
     printf("输出结果为\n");
     print3(c);
    return 0;
}

(1) 将实参作为一维数组名传递,形参连接元素类型的指针。

a 是一维字符数组的名称,是调用函数的名称

实参: (a) 形参:void (char * str)

(2)实参以二维数组名的形式传递,形参连接一维数组指针(相当于二维指针)

(aa) 字符 (*a)[]

(3)实参以三维数组名的形式传递,实参连接二维数组指针(相当于三维指针)

(aaa) 字符 (*a)[][]

补充:当数组作为形参时,编译器会将数组退化为指针,这样可以提高效率。

1、一维数组退化为一维数组元素类型指针(一维指针); 2、二维数组退化为指向一维数组的指针(二维指针); 3、三维数组退化为指向二维数组的指针指向元素的指针(3D指针)

指针数组和数组指针详解博客 - CSDN Array

三、指针和数组的区别 1、空间大小

数组是静态分配的空间(栈),并且空间是连续的。 定义就是分配空间,访问效率快。 存在一个问题,空间长度是固定的,不能改变。 很容易造成空间利用率低,造成空间浪费。 指针是动态分配的,并使用链表实现。 空间长度可以根据需要改变,需要用户手动分配空间(在堆上)。 使用完后,必须及时释放空间,防止内存泄漏。

2. 访问效率

数组可以快速连续访问,而指针则很灵活,可以用来随机访问数据。

3. 安全性

阵列有系统管理的空间,安全性好。 指针空间由用户管理,需要自己分配和释放,很容易造成内存泄漏,安全性较差。

4.函数参数(类型兼容性问题)

当数组作为形参时,编译器会将数组退化为指针,这样可以提高效率。

1、一维数组退化为一维数组元素类型指针(一维指针); 2、二维数组退化为指向一维数组的指针(二维指针); 3、三维数组退化为指向二维数组的指针指向元素的指针(3D指针)

4. 指针和数组的复杂声明(待补充)

标签: 数组 指针 二维

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码