(整理自 中国大学幕课 浙江大学-C语言程序设计)
-可变数组
C语言的可变数组是由不可变数组封装起来的
首先构建一个结构体:
typedef struct {
int *array;
int size;
}Array;
Array即可变数组 实际上为一个结构体
array为一个地址 size为数组的大小
这个结构体加上几个函数 就构成了可变数组
函数包含:
Array array_create( int
init_size ) ;//创建数组结构体 初始化array和size
void array_free( Array
*a ) ;//释放数组内存
int array_size( const
Array *a ) ;//设置结构体中的size
int *array_at( Array
*a, int index );//先判断是否越界 若越界 则调用inflate函数,获取结构体中array[ index
]的元素
void array_inflate(
Array *a, int more_size );//给数组扩展空间
每次扩展一个块block
其中最后的函数 void array_inflate( Array *a, int
more_size ); 为数组扩展函数,用到了block,block为开辟空间大小块 避免一次开一个小空间而多次开辟
-链表
可变数组 不断创建内存
十分麻烦,而且在不断创建和释放的情况下 到后面会发生申请不到空间的情况,实际内存足够
但刚申请的数组内存的“后面”没有足够的内存
上面的方法生成数组
不适应所有情况,现在需要的是 不再copy原数组 而是在原数组的基础上
开辟一块内存,并将新开辟的内存链接到原数组后面,这样每次数组扩展时都不用自我复制并申请新的内存 可以避免申请不到空间的情况
将新的数组指向原来的数组:
“数据加指针”(即节点)该指针指向下一个“数据加指针”(即节点),最后一个单元用特殊符号表示结束(最后一个节点的指针为NULL)
用特殊指针指向第一个单元(head)
这一系列构成链表 每个单元叫节点
每一个节点是数据加指针
节点实际上是结构体 用typedef
声明,分别是int和指向下一个结构体的指针
typedef struct
_node{
int value ;
struct_node *next;
} Node ;
新添加的struct 是链表最后的节点
它的指针应该是NULL,然后将上一个节点的指针指向该新增的节点
特殊情况:第一个节点的判断
Node* n =
( Node*)malloc(sizeof (
Node ) ) ;
n ->value = i
;
n ->next = head
;
head = n ;
将以上过程封装成一个函数 即添加一定大小的链表
该函数需要传入参数head,而该参数是形参 在函数内部改变后外部仍然没有变化,最好不要将head全局化
因为可能需要多个链表,直接将head return传出去 则需要程序员调用该函数时用一个新的head接收它,未避免忘记接收的情况
我们在给函数传入head时就不要直接传形参 而是传head的指针,由于head本身就是一个指针
所以传入的参数是指针的指针(Node**),这样处理后 我们可以直接在函数内部对head进行需要的修改;第四个办法
函数中传入的是一个结构体(List)的指针,该结构体里面只有一个指针head,或者 上述函数添加链表都是从第一个head开始
我们可以在结构体list里面再添加一个指针(tail)该指针指向链表的最后一个节点
这样每次添加节点都可以直接用这个指针指向下一个新的节点
typedef struct{
Node* head ;
}List ;
void add_head ( List*
list , int i ) ;
利用for循环 建立链表
for ( p = head ; p ; p
= p ->next ){};
移除某节点
先将该节点的上节点的指针指向下节点,再移除该节点
for ( q = 0, p = head;
p; q = p, p = p->next ) {
if ( p->value == i )
{
q->next = p ->next;
}
}
-附:
静态本地变量即全局变量
静态本地变量具有全局的生存期,函数内的局部作用域
返回本地变量的地址是危险的
而返回全局变量或静态本地变量地址是安全的
头文件:把函数原型放到一个头文件(以.h结尾)中,在需要调用这个函数的源代码文件(.c文件)中
#include这个头文件,就能让编译器在编译的时候知道函数的原型,这样可以保证传入的参数类型与函数要求的一致,头文件形成一个桥梁
#include是一个预编译处理
指出要插入的文件,不是用来引入库的
而是把引号或括号中的文件里的内容插入到include这一行
在使用和定义这个函数的地方都应该#include这个头文件
在函数前面加上static就使得它成为只能在所在的编译单元中被使用的函数,在全局变量前面加上static就使得它成为只能在所在的编译单元中被使用的全局变量
% [flag] [width]
[.prec] [hlL] type
C语言中的MVC模式
view和control没有直接发生联系,control通过改变model 从而改变view