C语言 - 数组的基础和部分应用

在C语言中,数组是一个可以用来存储固定大小、同类型元素的序列的数据结构。数组中的每个元素都可以通过其索引(或下标)来访问。在C语言中,数组的索引是从0开始的。

1.一维数组

    int a[ ]    //表示定义了一个int类型数组,数组名为a

    ①

        a.在定义数组时,需要指定数组中元素的个数

        b.定义数组时给所有元素赋初值,叫做完全初始化

        c.定义数组时只给一部分元素赋值,叫做不完全初始化,后面没有被初始化的值自动为0,但是不能所有元素都不初始化

        d.定义数组时给所有元素赋初值,那么就可以不指定数组的长度

        e.只有在定义的时候 a[x] 表示的才是数组,除此之外任何其他地方看到 a[x] 都不是数组,而是数组的一个元素

    ②

        数组名a可以作为数组第一个元素的指针

        a代表这个地址数值,它相当于一个指针,指向第一个元素(&a[0]),即指向数组的首地址

        数组中的其他元素可以通过a的位移得到,即:a+i = &a[i]

    ③

        对于一个变量b,&b是指取得b的存放地址;

        a在内存中没有分配空间,只对数组a的每个元素分配了存储空间,此处数组名字a显然不是普通的变量,&a也不代表取a的存储地址。

        &a在数值上与&a[0]相等,也等于a;此时,&a数值上等于整个数组的起始位置地址,含义上代表整个数组所占内存的大小,它的进阶单位是整个数组的字节长度,(&a+1)等于的是数组结束之后的下一段的起始位置地址

        a[0]在内存中实际分了存储空间,而&a[0]就是取该存储空间的地址

        当用sizeof时,由于a是个关键字,而不是个函数,所以数组不自动转换为指针,最后得到的结果=(数组长度*数组元素所占字节数),sizeof(a) = sizeof(&a)

        数组的大小:sizeof(数组名)/sizeof(数据类型)

2.数组作为入参

    数组传参时会退化为指针,

    退化的意义:C语言只会以值copy的方式传递参数,参数传递时,如果copy整个数组,效率会大大降低;同时参数位于栈上,太大的数组copy会导致栈溢出

    因此做了退化,在copy数组时,将数组名作为常量指针,传递数组首元素的地址

    void test(int a[])

    void test(int b[5])

    void test(int *c)

3.数组作为返回值

        在C语言中,数组本身不能直接作为函数的返回值。这是因为数组名在大多数上下文中代表数组首元素的地址,即一个指向数组元素的指针,而不是数组本身。可以通过几种不同的方式间接地返回数组的内容。

        方法一:通过指针参数

        一种常见的方法是通过指针参数来返回数组的内容。你可以传递一个指向数组元素的指针到函数中,并在函数内部修改这个指针指向的内存区域。

        void fillArray(int *array, int size)

        {  
            for (int i = 0; i < size; i++) {  
                array[i] = i * 2;  
            }  
        }  

        方法二:返回指向静态数组的指针

        如果你需要返回一个数组,并且该数组的内容在函数返回后仍然有效,你可以使用静态数组。但是不建议使用!(有多次调用覆盖静态数组的内容或线程安全的问题)

        int* createArray()

        {  
            static int array[5] = {1, 2, 3, 4, 5};  
            return array;  
        }  

        方法三:使用动态内存分配

        可以使用动态内存分配(如 malloc 或 calloc)。调用者需要负责在适当的时候释放内存

        int* createDynamicArray(int size)

         {  
            int *array = (int*)malloc(size * sizeof(int));  
            if (array == NULL) {  
                return NULL; // 分配失败  
            }  
            for (int i = 0; i < size; i++) {  
                array[i] = i * 2;  
            }  
            return array;  
        }  

        int main()

        {  
            int *myArray = createDynamicArray(5);  
            if (myArray != NULL)

           {   
                free(myArray); // 释放动态分配的内存  
            } 
            return 0;  
        }

        注意,使用动态内存分配需要谨慎处理,以避免内存泄漏或野指针等问题。每次使用 malloc 或 calloc 分配的内存都应该用 free 释放。

4.二维数组

        在C语言中,二维数组是一个由多个一维数组组成的数组,通常用于表示表格或矩阵形式的数据。每个一维数组(即二维数组的行)具有相同的元素数量。二维数组可以通过两个索引来访问其元素,第一个索引表示行,第二个索引表示列。

        二维数组的定义和初始化

        定义一个二维数组时,需要指定行数、列数以及数组元素的类型。

        int matrix[3][4]; // 定义一个3行4列的二维数组

        如果没有提供完整的初始化值,数组的元素将被自动初始化为0(对于全局或静态数组)或未定义的值(对于局部变量)。

        二维数组作为函数参数

        当将二维数组作为函数参数传递时,通常需要指定数组的第二维的大小,因为C语言在函数参数传递时不会保留数组的大小信息。例如:

        void printMatrix(int matrix[][3], int rows)

        {  
            for (int i = 0; i < rows; i++) {  
                for (int j = 0; j < 3; j++) {  
                    printf("%d ", matrix[i][j]);  
                }  
                printf("\n");  
            }  
        }  

  • 当声明二维数组时,第一维的大小可以省略(在函数参数中常见),但第二维的大小必须指定,因为编译器需要知道每行有多少个元素以计算数组的偏移。
  • 在C语言中,二维数组在内存中是连续存储的,行优先(即先存储第一行的所有元素,然后存储第二行的所有元素,依此类推)。

        二维数组作为函数返回值实例:

        日常Codeing过程中基本上用不到二维数组,这里写个简单的例子,大家有兴趣可以了解下;

        int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes)
        {
            int **arr;
            arr = (int **)malloc(sizeof(int *)*100);
            int cnt = 0;

            int *brr = (int *)malloc(sizeof(int) * 3);
            brr[0] = nums[0];
            brr[1] = nums[1];
            brr[2] = nums[2];
            arr[cnt++] = brr;

            *returnSize = cnt;          //
            *returnColumnSizes = (int *)malloc(sizeof(int)*cnt);
            for(int m=0;m<cnt;m++)
            {
                (*returnColumnSizes)[m] = 3;
            }
            return arr;        
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bigger_One

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值