这两天终于抑制不住想要敲代码的心了,于是乎在9号下午,教练说我不让我去练车时,我就开心地回家学《数据结构》(清华严敏蔚老师的书)了,但感觉自己学顺序表时顺带学的有点乱,故决定写此小文总结下近两日的收获。
感觉这次学习顺序表将之复杂化的主要原因在于图1.顺序表基本操作和图2.例题2-1
图1.《数据结构(c语言版)》中写的顺序表的基本操作
图2.《数据结构(c语言版)》中的例题2-1
原本以为这些函数的使用我只需要引用其头文件就ok了,但百度并无结果,老师也告诉我要自己写。于是我就决定自己将这些函数声明写头文件里,现在想来就因为非要写到头文件里就有了后续很多麻烦,也花费了很多时间。决定了就开始写呗!写到此处,我忽然不打算按照流水账似的写下去了,附张我这两天的网页浏览图整理,基本就是学习的曲折路线了。
图3.网页搜索部分问题
好了,回归正题,近两日学习小结。
一、C语言从编码编译到执行经历的过程
1.编写c语言源代码
2.预处理阶段-->读取c源代码,对其中的伪指令(以#开头的指令)和特殊符号进行处理
3.语法、词法分析阶段
4.编译-->生成目标代码(在目标机器上运行的代码)
5.连接-->生成最终可执行的二进制机器代码
6.执行-->在特定的环境下运行c程序
插张从网上找的c/c++编译过程图片(http://www.cnblogs.com/dongdongweiwu/p/4743709.html)
#include "mytest.h"
void main()
{
test = 25;
printf("test=%d\n",test);
}
mytest.h头文件内容如下:
#ifndef _MYTEST_H_
#define _MYTEST_H_
int test;
#endif
现在用上面的例子来说下解VC编译器的工作:
1.预处理阶段:编译器以.cpp文件作为一个单元,首先读这个文件,发现前两句是#include,一般带“<>”(如:<stdio.h>)会先去默认路径安装vc目录下\VC98\Include下查找,查找不到再去其工程路径下,一般带“”(如例子中的"test.h"则先在源代码路径下查找(和<>查找顺序相反)。找到之后,就会将相应头文件中再去处理宏,变量,函数声明,嵌套的头文件包含等,进行宏替换,看是否有重复定义与声明的情况发生,最后将那些文件中所有的东东全部扫描进这个当前的.cpp文件中,形成一个“中间文件”。
2.编译阶段,在上一步中相当于将那个头文件中的test变量扫描进了一个中间文件,那么test变量就变成了这个文件中的一个全局变量,此时就将所有这个中间文件的所有变量,函数分配空间,将各个函数编译成二进制码,按照特定目标文件格式生成目标文件,在这种格式的目标文件中进行各个全局变量,函数的符号描述,将这些二进制码按照一定的标准组织成一个目标文件。
3.连接阶段,将上一步成生的各个目标文件,根据一些参数,连接生成最终的可执行文件,主要的工作就是重定位各个目标文件的函数,变量等,相当于将个目标文件中的二进制码按一定的规范合到一个文件中。
再回到.cpp/.c文件与头文件各写什么内容的话题上:理论上来说.cpp/.c文件与头文件里的内容,只要是c/c++语言所支持的,无论写什么都可以的。我目前认为将函数、变量、结构体、宏声明写进.h文件,而只是一种规范而已,你不遵守程序一样可以执行。但在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。
唉,怎么说呢,感觉这两天学的依旧还是不太深入,而且发现很多东西我都慢慢忘记的差不多了(比如指针,动态内存分配),杂七杂八地算是复习了点东西吧!我目前对编程的学习态度是:有机会就敲敲代码,但一定要多思考,然后总结总结,接着进入下次循环。学习过程中遇到不会的就学去点,忘记的就复习下。发现问题,解决问题,总结经验。最后附写好的源码(可能比较渣,但终究是原创不是)
list.h头文件内容:
/**
*FileNmae:list.h
*Author:WYZ
*Version:1.0
*Date:2017/08/10
*Function List:
void ListInsert(List &L,int i,ElemType e);在第i个位置插入元素e
void ListDelete(List &L,int i,ElemType &e); 删除第i个元素,并用e返回其值
void GetElem(List &L,int i,ElemType &e);用e返回第i个元素的值
*/
#ifndef _LIST_H_
#define _LIST_H_
#include<stdlib.h>
#define LIST_INIT_SIZE 10
#define LISTINCREMENT 10
typedef int ElemType;
typedef struct{
ElemType *elem;/*存储基址 */
int length;/*当前长度 */
int size;/*当前存储容量 */
}List;
int InitList(List &L);/*初始化线性表*/
void ListInsert(List &L,int i,ElemType e);/*在第i个位置插入元素e*/
void ListDelete(List &L,int i,ElemType &e); /*删除第i个元素,并用e返回其值*/
void GetElem(List &L,int i,ElemType &e);/*用e返回第i个元素的值*/
void DestoryList(List &L);/*销毁线性表*/
void ClearList(List &L); /*清空线性表*/
int LocateElem(List &L,ElemType e,int compare);/*返回L中第一个与满足关系的元素位置,不存在则返回0*/
int ListTempty(List L);/*线性表是否为空*/
#endif
#include <memory.h>
#include"list.h"
/*初始化线性表*/
int InitList(List &L)
{
L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(L.elem==NULL)
exit(0);
L.length=0;
L.size=LIST_INIT_SIZE;
return 1;
}
/*在第i个位置插入元素e*/
void ListInsert(List &L,int i,ElemType e)
{
ElemType *p=NULL,*q=NULL,*newElem=NULL;
/*若插入的位置i不在1~Length+1,则退出*/
if(i<1||i>L.length+1)
exit(0);
/*若当前元素个数等于其已分配的空间,则需要增加其存储空间*/
if(L.length>=L.size)
{
newElem=(ElemType*)realloc(L.elem,(L.size+ LISTINCREMENT)*sizeof(ElemType));
if(newElem==NULL)
exit(0);
L.elem=newElem;
L.size+=LISTINCREMENT;
}
p=&L.elem[i-1];
q=&L.elem[L.length-1];
while(q>=p)
{
*(q+1)=*q;
q--;
}
*p=e;
++L.length;
}
/*删除第i个元素,并用e返回其值*/
void ListDelete(List &L,int i,ElemType &e)
{
ElemType *p=NULL,*q=NULL;
/*若删除的位置i不在1~Length,则退出*/
if(i<1||i>L.length)
exit(0);
p=&L.elem[i-1];
e=*p;
q=&L.elem[L.length-1];
while(p<q)
{
*p=*(p+1);
p++;
}
--L.length;
}
/*用e返回第i个元素的值*/
void GetElem(List &L,int i,ElemType &e)
{
ElemType *p=NULL;
if(i<1||i>L.length)
exit(0);
p=&L.elem[i-1];
e=*p;
}
/*清空线性表*/
void ClearList(List &L)
{
memset(L.elem,0,sizeof(List)*L.length);
L.length=0;
}
/*线性表是否为空*/
int ListTempty(List L)
{
if(L.length==0)
return 1;
return 0;
}
/*销毁线性表*/
void DestoryList(List &L)
{
free(L.elem);
L.length=0;
L.size=0;
}
/*返回L中第一个与e满足关系的元素位置,不存在则返回0*/
int LocateElem(List &L,ElemType e,int compare){
ElemType *p=NULL;
int a=0,b=0;
b=e;
for(int i=0;i<L.length;i++)
{
p=&L.elem[i];
a=*p;
//查找关系为相等
if(compare==0&&a==b)
{
return i+1;
}
//小于e
if(compare<0&&*p<=e)
{
return i+1;
}
//大于e
if(compare>0&&*p>=e)
{
return i+1;
}
}
return 0;
}
test.cpp内容:
#include<stdio.h>
#include"list.h"
int main(){
/*例题2—1:求A=AUB*/
int i=1;
ElemType m=0;
/*创建并初始化La、Lb*/
List La,Lb;
InitList(La);
InitList(Lb);
/*对La、Lb赋值*/
for(i=1;i<6;i++)
{
ListInsert(La,i,i);
ListInsert(Lb,i,2*i);
}
/*从Lb中取出元素并进行相关操作*/
for(i=0;i<Lb.length;i++)
{
GetElem(Lb,i+1,m);、
/*若La中不存在Lb中的元素,则插入到La中*/
if(LocateElem(La,m,0)==0)
ListInsert(La,La.length+1,m);
}
/*输出合并后的最终结果*/
for(i=0;i<La.length;i++)
{
GetElem(La,i+1,m);
printf("%d\t",m);
}
return 0;
}
附运行结果图示:
这次就说到这啦,要练车去啦,暑假不止,练车不息!!!