在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;
}