一、引用参数和指针的转换

标准C不支持引用参数,对此需进行转换。下面以bo1-1.cpp和bo1-1.c中DestroyTriplet()函数为例来说明这种转换。

bo1-1.cpp中含有引用参数的函数如下:

  1. Status DestroyTriplet(Triplet &T) {
  2. // 操作结果:三元组T被销毁
  3. free(T);
  4. T=NULL;
  5. return OK;
  6. }

转换后在bo1-1.c中的标准C程序如下:

  1. Status DestroyTriplet(Triplet *T) /* 将&T改为*T */
  2. { /* 操作结果:三元组T被销毁*/
  3. free(*T); /* 将T改为*T */
  4. *T=NULL; /* 将T改为*T */
  5. return OK;
  6. }

对照以上2个函数可见:将C++函数形参表中以&打头的参数改成以*打头的参数,再在函数中该参数前加*即可。

要注意的是,在这两个函数中,形参的类型是不同的。在bo1-1.cpp中,T的类型是Triplet;在bo1-1.c 中,T的类型是Triplet的指针。

但为方便起见,没有改写C程序中的注释。另外,在标准C程序中调用该函数,实参前应加&。

如main1-1.cpp中调用DestroyTriplet()的语句为

  1. DestroyTriplet(T);

相应的标准C程序main1-1.c 中调用DestroyTriplet()的语句为

  1. DestroyTriplet(&T);

其中,在调用DestroyTriplet()的两程序中,两实参T的类型是相同的。

另外,在转换过程中,遇到&*或*&可“抵消”,即将*&T转换为T。

二、标准C在指明所定义的结构体或枚举类型时,在类型前要加strutc或enum,而C++则不必加

如在C++的c2-1.h中定义结构体SqList如下:

  1. struct SqList {
  2. ElemType *elem; // 存储空间基址
  3. int length; // 当前长度
  4. int listsize; // 当前分配的存储容量(以sizeof(ElemType)为单位)
  5. };

C++在指明变量或形参的类型时,只需用SqList即可。如bo2-1.cpp中的一个函数如下:

  1. int ListLength(SqList L) {
  2. // 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数
  3. return L.length;
  4. }

如果在标准C程序中像C++的c2-1.h那样定义变量L的类型,则在bo2-1.c中该函数应如下:

  1. int ListLength(struct SqList L) {
  2. /* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数*/
  3. return L.length;
  4. }

说明变量L时要用struct SqList。当用到某个结构体就要在其类型前加struct,用到某个枚举类型就要在其类型前加enum是很麻烦的。

为了方便起见,可用typedef定义类型。在标准C程序的c2-1.h中定义SqList如下:

  1. typedef struct {
  2. ElemType *elem; /* 存储空间基址*/
  3. int length; /* 当前长度*/
  4. int listsize; /* 当前分配的存储容量(以sizeof(ElemType)为单位) */
  5. }SqList;

这样,在bo2-1.c中相应的函数为

  1. int ListLength(SqList L) {
  2. /* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数*/
  3. return L.length;
  4. }

这个函数与bo2-1.cpp 很相似。可见,只要在定义结构体时使用typedef,则在指明结构体的类型时就不必加struct。

标准C都采用这种方法定义结构体。定义枚举类型时使用typedef 的方法与此类似。

三、标准C的共用体必须有变量名,而C++可以省略

如在c5-6.h(C++)中定义GLNode1如下:

  1. // c5-6.h 广义表的扩展线性链表存储结构
  2. enum ElemTag{ATOM,LIST}; // ATOM==0:原子,LIST==1:子表
  3. typedef struct GLNode1 {
  4. ElemTag tag; // 公共部分,用于区分原子结点和表结点
  5. union // 原子结点和表结点的联合部分
  6. {
  7. AtomType atom; // 原子结点的值域
  8. GLNode1 *hp; // 表结点的表头指针
  9. };
  10. GLNode1 *tp; // 相当于线性链表的next,指向下一个元素结点
  11. }*GList1,GLNode1; // 广义表类型GList1是一种扩展的线性链表

注意:其中的共用体没有变量名。在bo5-6.cpp 中的函数GListEmpty()如下:

  1. Status GListEmpty(GList1 L) {
  2. // 初始条件:广义表L存在。操作结果:判定广义表L是否为空
  3. if(!L||L->tag==LIST&&!L->hp)
  4. return OK;
  5. else
  6. return ERROR;
  7. }

而标准C的c5-6.h如下:

  1. /* c5-6.h 广义表的扩展线性链表存储结构*/
  2. typedef enum{ATOM,LIST}ElemTag; /* ATOM==0:原子,LIST==1:子表*/
  3. typedef struct GLNode1 {
  4. ElemTag tag; /* 公共部分,用于区分原子结点和表结点*/
  5. union /* 原子结点和表结点的联合部分*/
  6. {
  7. AtomType atom; /* 原子结点的值域*/
  8. struct GLNode1 *hp; /* 表结点的表头指针*/
  9. }a;
  10. struct GLNode1 *tp; /* 相当于线性链表的next,指向下一个元素结点*/
  11. }*GList1,GLNode1; /* 广义表类型GList1是一种扩展的线性链表*/

它内部的共用体必须有变量名。在bo5-6.c 的函数GListEmpty()中也变动如下:

  1. Status GListEmpty(GList1 L) {
  2. /* 初始条件:广义表L存在。操作结果:判定广义表L是否为空*/
  3. if(!L||L->tag==LIST&&!L->a.hp)
  4. return OK;
  5. else
  6. return ERROR;
  7. }

四、C++可重载

即在一个程序中,可有几个同名的函数同时存在。只要它们的形参个数或类型有所不同即可。

标准C不可重载。在C++转换成标准C时,必须将同名函数改为不同名。

如在bo9-2.cpp中有1个SearchBST()函数(算法9.5(b)),在bo9-2.cpp所包含的文件func9-1.cpp中也有1个SearchBST()函数(算法9.5(a)),但这两个同名函数的形参个数不同。

C++根据函数的形参个数可分辨所调用的是哪个函数。而标准C没有这个能力,所以把bo9-2.c中的SearchBST()函数改为SearchBST1()函数。

五、C++允许在执行语句中变量使用之前定义变量

如algo8-1.cpp 中的PrintUser()函数:

  1. void PrintUser(Space p[]) {
  2. // 输出p数组所指的已分配空间
  3. for(int i=;i<MAX/e;i++)
  4. if(p[i]) // 指针不为0(指向一个占用块) {
  5. printf("块%d的首地址=%u ",i,p[i]); // 输出结点信息
  6. printf("块的大小=%d 块头标志=%d(0:空闲1:占用)",p[i]->size,p[i]->tag);
  7. printf(" 块尾标志=%d\n",(FootLoc(p[i]))->tag);
  8. }
  9. }

这种形式在标准C 语言中是不允许的。相应的algo8-1.c 中的PrintUser()函数为:

  1. void PrintUser(Space p[]) {
  2. /* 输出p数组所指的已分配空间*/
  3. int i;
  4. for(i=;i<MAX/e;i++)
  5. if(p[i]) /* 指针不为0(指向一个占用块) */ {
  6. printf("块%d的首地址=%u ",i,p[i]); /* 输出结点信息*/
  7. printf("块的大小=%d 块头标志=%d(0:空闲1:占用)",p[i]->size,p[i]->tag);
  8. printf(" 块尾标志=%d\n",(FootLoc(p[i]))->tag);
  9. }
  10. }

六、C++允许在转换类型时采用函数的形式

如algo8-2.cpp中AllocBuddy()函数的,一条语句如下:

  1. pi=pa+int(pow(,k-i));

而在标准C程序algo8-2.c中必须改为以下形式(注意带下划线部分):

  1. pi=pa+(int)pow(,k-i);

七、在C++中可用new申请空间

如bo8-1.cpp 中主函数main()的一条语句如下:

  1. p=new WORD[MAX+]; // 申请大小为MAX*sizeof(WORD)个字节的空间

在标准C的bo8-1.c中要改为

  1. p=(WORD*)malloc((MAX+)*sizeof(WORD)); /* 申请大小为MAX*sizeof(WORD)个字节的空间*/

八、在C++中可用cout和cin做输入输出语句

它们的好处是不必给出格式符。这样,当变量的类型发生变化时,不必修改语句。但在main1-1.c 中必须改为

  1. printf("%d %d %d\n",T[],T[],T[]);/*当ElemType的类型变化时,要相应改变printf()的格式符*/

九、在C++中“//”后到本行末的内容为注释,而标准C的注释必须放在“/*”、“*/”之间

十、标准C 程序的扩展名为.c,C++程序的扩展名为.cpp

定义数据存储结构的文件,其扩展名是.h,在两种语言中不能混用。

C和C++格式转换的更多相关文章

  1. FFmpeg学习4:音频格式转换

    前段时间,在学习试用FFmpeg播放音频的时候总是有杂音,网上的很多教程是基于之前版本的FFmpeg的,而新的FFmepg3中audio增加了平面(planar)格式,而SDL播放音频是不支持平面格式 ...

  2. 【视频处理】YUV与RGB格式转换

    YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与YUV的变换公式如下: YUV(25 ...

  3. 日期格式转换 java 2016-09-03T00:00:00.000+08:00

    /**  * 日期格式转换yyyy-MM-dd'T'HH:mm:ss.SSSXXX  (yyyy-MM-dd'T'HH:mm:ss.SSSZ) TO  yyyy-MM-dd HH:mm:ss  * @ ...

  4. RSA密钥之C#格式与Java格式转换

    前言 最近由于项目需求,服务端由c#编写,客户端由java编写.通信数据使用RSA非对称加密.但是java和c#生成的密钥格式是不一样的,所以需要转换格式才可以正常使用.网上搜到使用java进行格式转 ...

  5. 【VC++技术杂谈007】使用GDI+进行图片格式转换

    本文主要介绍如何使用GDI+对图片进行格式转换,可以转换的图片格式为bmp.jpg.png. 1.加载GDI+库 GDI+是GDI图形库的一个增强版本,提供了一系列Visual C++ API.为了使 ...

  6. Oracle日期格式转换,tochar(),todate()

    Oracle日期格式转换 本文主要介绍Oracle中的日期转换. 1. 日期转化为字符串 (以2016年10月20日为例) select to_char(sysdate,'yyyy-mm-dd hh2 ...

  7. C#返回时间格式转换成 js 字符串

    在.net 中,调用 post 或者 get和后台通信时,如果有时间返回信息,后台返回的时间信息一般是这样格式:Thu Jul 9 23:14:53 UTC+0800 2015,那么要在前台显示就会有 ...

  8. SpringMVC与MyBatis整合之日期格式转换

    在上一篇博客<SpringMVC与MyBatis整合(一)——查询人员列表>中遗留了日期格式转换的问题,在这篇记录解决过程. 对于controller形参中pojo对象,如果属性中有日期类 ...

  9. JAVA,NET RSA密钥格式转换

    JAVA和NET RSA密钥格式相互转换(公钥,私钥) 做了一个小项目遇到java和.net非对称加密问题,java的公钥和私钥就直接是一个字符串的形式展示的,但是.net是以xml简单包裹形式展示的 ...

  10. JS时间格式 GMT格式转换

    JavaScript时间格式转换总结 1.当前系统区域设置格式(toLocaleDateString和toLocaleTimeString) 例子:(new Date()).toLocaleDateS ...

随机推荐

  1. C++ 二位数组做参数传递

    指针的强大功能,,,,简直牛逼!!! #include<iostream> #include<cstdio> #include<map> using namespa ...

  2. 最小生成树【p2121】 拆地毯

    题目描述--->p2121 拆地毯 分析 这题为什么是最大生成树. 先来bb两句 题目为拆地毯,让我们剩下k个地毯. 题目想要我们求得最大的美丽度. 且要求我们 保留的地毯构成的图中,任意可互相 ...

  3. 九. 常用类库、向量与哈希1.Java基础类库

    Java 的类库是 Java 语言提供的已经实现的标准类的集合,是 Java 编程的 API(Application Program Interface),它可以帮助开发者方便.快捷地开发 Java ...

  4. 自己写Tiny6410的Bootloader总结!

    1.由于Tiny6410 2G版的Nand flash(K9GAG08U0E)的页大小是8K的,但是s3c6410芯片设置为nand flash启动时先从nand flash复制8K代码到片内内存中去 ...

  5. linux之ls指令的关键字过滤显示

    假设~/admin的文件夹下面有几个文件: a.pm b.pm c.pl d.pl e.pml 想只显示.pm结尾的可以用: ls *.pm 或者 ls | grep .pm,两者等价. 想显示b.开 ...

  6. apache的动态和静态

    apache的动态和静态  http://www.cnblogs.com/eoiioe/archive/2008/12/23/1360476.html(2.0和2.2一样) 关于apache的动态与静 ...

  7. tensorflow TensorArray 代码例子

    import tensorflow as tf import numpy as np B=3 D=4 T=5 tf.reset_default_graph() xs=tf.placeholder(sh ...

  8. 【Hadoop】Hadoop HA机制要点

    Hadoop HA 机制架构.要点.原理: 需要的机器(规划): 至少三台机器 HOSTNAME IP 安装软件ZK HADOOP进程 HADOOP-NODE1 10.20.0.11 JDK,HADO ...

  9. Linux Shell常用技巧

    转载自http://www.cnblogs.com/stephen-liu74/ 一.    特殊文件: /dev/null和/dev/tty Linux系统提供了两个对Shell编程非常有用的特殊文 ...

  10. SharePoint 2013 表单认证使用ASP.Net配置工具加入用户

    前 言 上面一篇博客,我们了解到怎样为SharePoint 2013配置表单身份认证.可是加入用户是一个麻烦事儿:事实上,我们还能够用Asp.Net的配置工具,为SharePoint 2013加入表单 ...