Skip to content

Instantly share code, notes, and snippets.

@liweinan
Last active April 6, 2018 09:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save liweinan/36e55fdd086e6a21f01429fe5871656f to your computer and use it in GitHub Desktop.
Save liweinan/36e55fdd086e6a21f01429fe5871656f to your computer and use it in GitHub Desktop.
#include <stdlib.h> // malloc和free函数定义在这个library里。
#include <stdio.h> // printf函数定义在这个地址里。
struct _listADT {
int size; // list的大小
int *data; // list数据的实际内存位置,是一块连续的内存空间。
int *head; // list的数据的起始位置
// 函数的指针,指向add()方法的实际实现。
// 因为C语言没有class的概念,没法把对list的方法和数据都封装到一个class里面,
// 所以就通过在struct里面定义函数指针的方式来实现一个类似class的形式。
void (*add)(struct _listADT*, int); // 我们约定这个list保存的是int类型的数据。这样数据类型一致,
// 才能保证访问第N个数据的时候,内存位置是可以被计算的,否则就会出错。
// 而编译器也不会允许你保存不同类型的数据的。
// 如果你一定要保存不同类型的数据,就像Python里面实现的Bag那样,
// 那你可以拿list保存每一个item的地址,也就是int *
// 这样,你的list里面的每一个item,其实都是这个item的地址,而不是数据本身
// 而地址的数据类型和大小是一致的,就是long,这样也没有问题
// 但是我们这个例子不用考虑这么复杂,就考虑只保存全部是int数据的情况
// 就可以了。
void (*delete)(struct _listADT*, int); // 删掉第index个item,index是int类型数据
};
// 简化一下代码,接下来写`List`,就可以代替`struct _listADT`了,少写点字
typedef struct _listADT List;
// 下面这两个函数是具体实现,下面要连接到_listADT的对应的函数指针上去。
void listAdd(List* self, int value) {
printf("ADD AN ITEM\n");
}
void listDelete(List* self, int idx) {
printf("DELETE AN ITEM\n");
}
List* CreateList() {
int default_size = 100; // 创建一个大小默认为100的list(list和linkedList不同,需要一个初始的大小)。
// 这个list默认可以保存100个数据,然后后续如果不够,再在add方法里面扩展内存。
List* newList = malloc(sizeof(List)); // 申请了heap内存,保存这个动态创建的List数据的实例。
newList->size = default_size; // list里面items的初始个数。(linked list不需要初始个数,动态增减就可以)
int* listData = malloc(sizeof(default_size * sizeof(int))); // 申请了heap内存,用来保存items数据。约定items都是int类型的数据。
newList->data = listData; // 把申请到的内存的地址的起始位置连接到struct的data这个指针上面。
newList->add = &listAdd; // 把add这个函数指针对应的具体实现,连接到listAdd函数上。(都是通过内存指针完成的,让add指向listAdd的函数地址。)
// 在C的世界里,所有数据,代码的地址,都是可以被引用的。
// 但代码的地址只能被引用,数据只读,不可写,防止process在执行的过程中可以动态地修改自身的代码。
// 这是出去安全角度,操作系统做的内存防护工作。
newList->delete = &listDelete; // 同理,把delete方法指向listDelete函数的具体实现地址。
return newList; // 返回这个新创建的list instance。
}
int main() {
List* list = CreateList();
list->add(list, 'x');
list->delete(list, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment