问题来源
是我本人在使用C语言完成顺序线性表时一个比较疑惑的问题,可能题目描述的不是很清楚,下面我将详细的描述我的问题
问题描述
首先我定义了一个.h文件来定义我的顺序表结构
// 假定该顺序表数据元素类型为Int,实际上可以是任何数据类型
typedef int Element;
// 定义顺序表结构体
typedef struct{
Element *head;
int length; // 顺序表当前已使用的长度
int size; // 顺序表的最大长度(maxsize)
}sequence_list;
在调用该.h文件后,我编写了一个函数用于初始化顺序表
void InitList(sequence_list *sequenceList,int size){
// init the sequence_list
sequenceList->size = size;
sequenceList->length = 0;
sequenceList->head = (Element*)malloc(sizeof(Element) *sequenceList->size);
}
这里我使用malloc申请了动态内存,所以基本上来说,就是我申请出了一块连续内存
内存首地址为head
,长度为size * 长度数据元素长度
,取到每一个对应的值完全依赖首地址内存+偏移量
这个时候问题来了,我使用数组下标就可以像int数组一样,直接偏移到想要的位置
void PrintList(sequence_list *sequenceList){
// print all element
for (int i = 0;i < sequenceList->length;i++){
printf("%d \t",sequenceList->head[i]);
}
printf("\n");
}
我很好奇这个数组下标是如何判断出应该偏移多少位的,正常int数组在声明时声明了类型,因此编译器知道需要偏移的大小是多少,那么这样malloc申请的连续地址,这个数组下标又是怎么知道单个数据元素需要的内存大小是多少?这是怎么确定偏移量的?
关键的就是这一步:
这里, 确定了申请的内存大小,也确定了后续使用内存的基本规则。
sizeof(Element) *sequenceList->size
这里确定了内存申请的量,首先,通过sizeof(Element)
获取了单个Element
的大小,再乘以需要的数量(由sequenceList->size
确定),就是总的大小。这样malloc
函数申请的就是合适的总大小啦。至于如何用内存,这里用了
(Element*)malloc(sizeof(Element) *sequenceList->size)
,就是说强制以(Element*)
即Element
结构的形式来访问申请到的内存。有了这一步后,后面访问就直接可以类似数组,每次偏移会自动的以Element
结构所占内存字节数的整数倍来移动指针啦,即后面sequenceList->head[i]
对应的就是(Element*)(sequenceList->head +sizeof(Element) *i)
,即数据结构按Element
解析。