为了更好地理解线性表的顺序结构实现,需要回顾C语言中的数组、结构体、参数传递、指针、内存管理等方面的知识,并且为了更好地写出简短的代码,在此也补充一些C++中的相关知识以写出更好的代码。
1.在“初识数据结构”一文中提到了关于抽象数据类型的定义,这些抽象的数据类型通常是根据已有的数据类型组合而成的,并且我们经常在很多地方看到类似于下面的代码:
typedef struct a{
ElemType data[];
int length;
}SqList;
很多初学者可能很疑惑这里的ElemType,这里可以直接把他理解为某种特定的数据类型,可以根据自己的需要声明。例如将其看做int型或char型:
typedef int ElemType
typedef char ElemType
如果需要一种复合类型,可再通过定义结构体数据类型加以说明,例如如果要定义一个多项式,其中某一项的系数以及指数都需要声明,可进行如下操作,p表示系数,e表示指数
typedef struct{
float p;
int e;
}Polynomial;
typedef struct{
Polynomial *elem;
int length;
}SqList;
2.数组的静态分配和动态分配
- 静态分配
typedef struct{
ElemType data[MaxSize];
int length;
}SqList;
- 动态分配
typedef struct{
ElemType *data;
int length;
}MyList;
3.C语言内存动态分配
SqList L;
L.data = (ElemType*)malloc(sizeof(ElemType)*MaxSize);
malloc(m):开辟m字节长度的地址空间,并返回这段空间的首地址
sizeof(x):计算变量或者数据类型的长度
free(p):释放指针p所指变量的存储空间,即彻底删除一个变量
以上函数许头文件<stdlib.h>
4.C++中的动态存储分配
new 类型名T
功能:申请用于存放T类型对象的内存空间
int *p = new int(10)
delete 指针p
功能:释放指针p所指向的内存
delete p;
5.参数传递
- C语言
①传值方式(形参改变不会导致实参改变)
此类型较简单,略过
②传地址——指针变量作为参数
#include<stdio.h>
void swap(int *p,int *q)
{
int t;
t = *p;
*p = *q;
*q = t;
}
int main()
{
int a=3,b=4;
swap(&a,&b);
printf("%d %d",a,b);
}
③传地址——数组名作为参数
这里对函数中任何对形参的改变都会反映到实参中!
- (补充C++中引用类型作为参数)
#include<stdio.h>
void swap(int &p,int &q)
{
int t;
t = p;
p = q;
q = t;
}
int main()
{
int a=3,b=4;
swap(a,b);
printf("%d %d",a,b);
}
(这里偷了点懒,直接在cpp中使用c的语法也是可行的嘞)
这里说明&符号的用法:
它给一个对象提供了一个替代的名字,两者都指向同一内存空间,所以对形参的改变都会反映到实参中。
引用类型作为形参,在内存中并没有产生实参的副本,他直接对实参进行操作,所以当参数传递的数据量较大时,引用参数的使用比一般的参数时间和空间复杂度都要小。如果用指针类型的话,在被调用函数中需要不断使用*p,这样很容易出错并且降低了程序的可读性。
在掌握了这些后,实现线性表的顺序结构就比较容易了)
(为什么感觉写一篇很平凡的文章花了这么长时间,)