数组
基本原则
1、声明一个数据类型为T,程度为N的数组A ,T A[N]。这句语句的意思为在存储器中分配N*sizeof(T)个字节的存储空间,其中A为指向该存储空间的首地址,在Ubantu下用 p A打印指令,可以看出A存储的是一个地址。
下面来看看几个数组的声明:
char A[12]
char *B[4]
int C[8]
int * D[8]
数组 | 元素大小 |
---|---|
A | 1字节 |
B | 4字节 |
C | 4字节 |
D | 4字节 |
*这里是32位机上的结果,对于指针数组的元素,其存的是地址,为32位,大小为4字节。对于64位机,则是8字节。
元素访问
返回a数组中的下标index的元素
// 访问数组内的元素
int get_elemen(a,int index){
return a[index];
}
IA32的汇编代码
%edx = a;
%eax = index;
movl (%edx,%eax,4),%eax //取a[index]放入eax
edx存储数组首地址,eax存储下标值,访问数据的地址为4%eax+%edx,然后利用内存寻址方式取值。
二维数组
T A[R][C] 数据类型T,R行,C列
数组大小:R* C * K 个字节。K为每个元素的大小
排列方式:以行优先
元素访问
A[i][j]的地址为:A+C * K * i + j *K
嵌套数组
跟二维数据类似,只不过访问二维数组只需要访问一次内存,而嵌套数组要先访问存储地址的数组,然后根据地址访问数据所在的内存,一共访问了两次内存,其优点是灵活性强。
结构体
C语言中的结构体
struct r{
int a[3];
int i;
struct r *n; //指向结构体的指针
}
1、分配的内存连续
2、可以通过结构体名字和成员名字访问相应的数据。例如.,->
3、可包含不同数据类型的数据
数据访问
rec ->a 或 rec.a
*一般->用于指针运算
IA32机器表示
C代码
void set(struct r *rec,int value){
rec->i = value;
}
汇编
%edx=value;
%eax = rec;
movl %edx,12(%eax)
- i是结构体中的第2个元素,前面的a数组占了3*4=12个字节,所以i的地址为rec+12。
结构与对齐
结构体内分配的内存的大小是最大数据类型大小的整数倍。并且,每个数据类型都有自己的对齐规则,即自身类型的大小的整数倍。如下:
char类型:没有限制
short类型:地址位的低两位是(00)2,即偶数地址对齐。
int、float、char*:4的倍数地址边界对齐
double:(Linux是4的倍数地址边界对齐,Windows和绝大多数为8的倍数的地址边界对齐)
long double:12的倍数的地址边界对齐
- 对齐提高了存储器系统的性能。
举个例子:对于下面的结构体
struct r{
char c;
int i[2];
double v;
} *p
没有对齐的内存分配:
对齐后:
- 这里的数据类型的最大长度为8字节,所以整个长度为8的整数倍。
- 为了节省空间,把长度大的数据类型放在前面,可减少因对齐额外分配内存。
联合体(Union)
内存分配
联合体的定义跟结构体语法一样,但其分配内存是根据最大长度元素的长度分配内存空间,而且每个成员共享这一块内存。
struct r{
char c;
int i[2];
double v;
} *p
union r{
char c;
int i[2];
double v;
} *p
字节顺序
联合体可用来判断机器的大端、小端表示法。
下面是在Ubantu下进行演示
#include<stdio.h>
#include<stdlib.h>
int
main(int argc, char **argv)
{
union {
short s;
char c[sizeof(short)];
} un;
un.s = 0x0102;
if (sizeof(short) == 2) {
if (un.c[0] == 1 && un.c[1] == 2)
printf("大端法\n");
else if (un.c[0] == 2 && un.c[1] == 1)
printf("小端法\n");
else
printf("不能判断\n");
} else
printf("sizeof(short) = %d\n", sizeof(short));
exit(0);
}
小端:低位存储在低位,高位存储在高位。0x0102,0x02是低位,存储在低地址,0x01存储在高地址。
大端:与小端相反
可以看出32位Linux系统下数据的存储方式是小端法。
- 本片博客是我拿来复习用的,因为也才刚刚入手,如有描述不对的地方,还请各位多加指正。