嵌入式Linux C(七)——数组(详)
一、数组
1.1 数组认知:
- 静态分配空间(int a[100] 400个字节)----->空间利用率太差(1.不够用 2. 浪费空间)
- 所占内存空间特点:连续的(物理连续) -->malloc分配空间不一定是物理连续(malloc实现原理:链表链接所有空闲的空间,组成最终分配的空间)
1.2 如何使用数组
- 定义数组:该定义多大?char src[1024]; -->柔性数组!!!
注意事项:可变长数组c99
c89:定义数组时。必须定义其长度;
注意事项:不能在使用过程中通过修改变量,来扩充数组的内存空间
(选择方式):通常用宏来表达数组的代销,提高代码移植性
定义数组时,要清零
int a[3] = {0}
memset(a,0,sizeof(a));
[] = *();
数组++;不行
//柔性数组
struct node
{
int len;
int array[0];
}
struct node n;
n.len = 10;
n.array = (int *)malloc(sizeof(int) * n.len);
- 数组的使用
数组名的作用:
一维数组名:指针常量(元素类型的指针,无法改变),保存的数组首元素的地址
void func(char src[100])//用数组接的话,会退化成指针:char *src,所以要用指针接
{
printf("%ld",sizeof(src));//输出是8
src++;
}
char buffer[1024] = "hello world";
func(buffer);
- 数组的地址
int a[3]
printf("&a + 1 = %p",&a)
//a:数组名,指针常量,保存数组首元素的地址
&a:对数组名取地址,等于数组的地址:
*(&a) = a;对一位数组的地址取值等于数组首元素的地址
整型变量的地址用整型指针变量保存,
字符变量的地址用字符指针变量保存,
数组变量的地址用数组指针变量保存,
数组指针变量:变量,保存的是地址,地址数组的地址是数组的地址
int (*pa)[3] //整型数组指针变量:pa是一个变量,保存的地址,该地址是数组的地址,该数组是一个整型数组
pa = &a //*pa = a
- 二维数组
#include <stdio.h>
int main()
{
int aa[2][2];
//int aa[2][] = {1,2,3,4} //二维数组只能省略列,不能省略行
// 二维数组名
//作用:
for(int i = 0;i < 2; i++)
{
for(int j = 0;j < 2; j++)
{
scanf("%d",&aa[i][j]);
scanf("%d",(*(aa + i) + j))
}
}
for(int i = 0;i < 2; i++)
{
for(int j = 0;j < 2; j++)
{
printf("aa[%d][%d] = %d\n",i ,j ,aa[i][j]);
printf("aa[%d][%d] = %d\n",i ,j ,*(*(aa + i) + j));
}
}
}
二维数组:
aa指针常量,保存的是首个一维数组的地址;
&aa:二维数组的地址
*(&aa) = aa;对二维数组的地址取值等于首个一维数组的地址
*aa:首个一位数组的首个元素的地址
二维数组名:指针常量(一维数组指针,保存首个一维数组的地址)
- 三维数组
int aaa[2][2][2] = {{1,2,3,4},{5,6,7,8}};
//第一个下标:第几个个二维数组
//第二个下标:第几个个二维数组第几行
//第三个下标:第几个个二维数组第几列
//aaa[1][1][0]是7
//*aaa:首个二维数组的首个一位数组的地址
//**aaa:首个二维数组的首个一维数组的首元素的地址
//***aaa:首个二维数组的首个一维数组的首元素的值
//&aaa:三维数组的地址
//*(&aaa):对三维数组的地址取值等于首个二维数组的地址
1.3 数组名
#include <stdio.h>
int main()
{
char str[100];//"hello"
char ktr[2][100];//"hello1""hello2"
char ptr[3][2][100];//"hello3""hello4""hello5""hello6"
printf("input str:\n");
scanf("%s",str);
printf("str = %s\n",str);
printf("input ktr:\n");
for(int i = 0; i < 2; i++)
{
//scanf("%s",*(ktr + i));
scanf("%s",ktr[i]);
}
for(int i = 0; i < 2; i++)
{
printf("ktr[%d] = %s\n",i,*(ktr + i));
//scanf("%s",ktr[i]);
}
printf("input ptr:\n");
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 2; j++)
{
scanf("%s",*(*(ptr + i) + j));//ptr[i][j]
}
}
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 2; j++)
{
printf("ptr = %s\n",*(*(ptr + i) + j));//ptr[i][j]
}
}
return 0;
}
1.4 数组指针
数组指针变量
//数组指针
int (*paa)[2][2] = &aa;//数组指针变量:指向一个二维数组(保存二维数组地址)
int (*paaa)[2][2][3] = &aaa
如何定义数字组指针变量?右左法则 int (*p)
一维数组名,用指针接
void print2( char *str)
二维数组名,用一维数组指针接
void print2( char (*ktr)[100])
三维数组名,用二维数组数组指针接
void print2( char (*ptr)[2][100])
1.5 指针数组
指针数组:数组里保存的都是指针
#include <stdio.h>
int main()
{
int *pi[3];//指针数组,存放
//int (*pa)[3];//数组指针,是指针,指向数组,sizeof(pa) = 8
char *pc[3] =
}
一维数组名,用元素指针接,而元素就是指针,则就是元素指针的指针来接,即二级指针
void print4(char **pc)
1.6 指针与数组的区别
空间分配:指针:动态,数组:静态(优缺点)
访问效率:数组 > 指针 指针更灵活
安全性:数组高
函数形参:数组全都退化成指针
1.7 指针与数组的复杂说明
右左法则:右左法则