数据结构----头文件实现顺序表的创建、(c语言)小结

  这两天终于抑制不住想要敲代码的心了,于是乎在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)

    

 

  以上过程仅仅是个大概,详细的过程真可谓是相当复杂,下面的这篇文章写得很详细,我从中受益颇多:
原文来自http://www.vcgood.com/bbs/forum_posts.asp?tid=1400 ,这里我就不打算具体说了,因为我认为我目前水平确实还没有真真正正完全搞懂所有过程(底层的真的不是很明白),不过上面的连接我看了好几遍,只能算是了解个大概吧!但总觉得还是没有很通透,慢慢来吧!
  我在这次敲代码的过程中,碰到了为数不多次的编译可以通过,但连接有错的情况。当初学c觉得一编译出现好多bug好气哦,但昨天编译通过,链接有误更让我感到绝望,改都不知道去哪改,我都怀疑真的是因为我用的是vc简版的原因了(我确实又重装了vc,还用vs2015,Dev试了)。但后来发现是因为我在同一个工程中同时使用了.c和.cpp后缀名,而VC++的编译器中.c为C程序,.cpp为C++程序,C程序与C++程序中同样的函数在编译后的.obj文件中的symbol是不同的,所以以C方式编译的obj文件与以C++方式编译的obj文件无法成功链接(后来查了下.c和.cpp在同一个工程文件的共存问题,好像可以添加点东西使其共存,但我觉得我目前还不必搞那么复杂,就跳过了,直接都使用了.cpp(有兴趣可以自行查看关于.c 文件和.cpp 文件在工程中共存问题  http://blog.csdn.net/peng654321/article/details/6303416 )。同时我还遇到了调用函数时传入的参数类型不符等问题,但都陆续解决明白了,在此就不说了。
  二、.h头文件的用法
  有了上面的基础知识,现在言归正传,举个例子:
  test.cpp文件内容如下:
  #include <stdio.h>

  #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

 
 
list.cpp内容: 

#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;
}

 

 

附运行结果图示:

 

这次就说到这啦,要练车去啦,暑假不止,练车不息!!!

转载于:https://www.cnblogs.com/dowhatilove/articles/7345878.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值