从C到C++的第一步:了解C和C++在语法上的不同
icon2 Program Impossible | icon4 2007-07-07 14:03| icon317 Comments | 本文内容遵从CC版权协议 转载请注明出自matrix67.com

    C++语言是C语言的扩展。你把C源码的扩展名改成cpp通常都可以直接编译。从语法上看,C语言是C++语言的子集,个别地方除外。这篇日志专门收集C和C++语法上的不同,指出C和C++的极个别不兼容的地方,让大家在学习C语言后可以尽快写出正确的C++代码。这篇日志需要众牛过目并补充。

系统保留字
    C++多出了很多功能,因此系统保留字比C更多。如果你的C源码中的变量名或函数名正好是C++的系统保留字,此时将不能通过C++的编译。

void*类型赋值
    在C++中你不能把void*类型直接赋值给其它任何类型。下面这句代码在C中可以通过编译,但在C++中则不能通过编译。你需要使用类型转换后再赋值。
int *x = malloc(sizeof(int) * 10);
    
指针的初始化和释放
    在C语言中,对指针的初始化和释放通常这样写:
int *x = malloc( sizeof(int) );
int *x_array = malloc( sizeof(int) * 10 );
free( x );
free( x_array );

    但在C++中,这些操作通常使用new和delete运算符完成:
int *x = new int;
int *x_array = new int[10];
delete x;
delete[] x_array;


结构的声明
    C语言中声明结构变量需要在结构名前面加一个struct。在C++中那个struct可以省略。
    也就是说,在C语言中你需要这样写:
struct date
{
    int year;
    int month;
    int day;
};
struct date now;

    但在C++中,你可以写成这样:
struct date
{
    int year;
    int month;
    int day;
};
date now;



函数声明与调用
    C++中严格禁止先调用后声明。你可以把函数声明写在前面或使用向前引用。下面的程序代码在C中是合法的,但是在C++中无法通过编译。
#include <stdio.h>
int main()
{
    printfDomain();
    return 0;
}
int printfDomain()
{
    printf("matrix67.com");
}


bool类型
    C语言中使用bool类型需要包含stdbool.h文件。C++本身提供了bool类型。

主程序返回值
    C语言中,你需要在主函数结束前加一句return 0。C++中主函数自动返回0,因此你可以不写return 0。放心,不写return 0在编译时连个警告都没有。

C++的新特性
    这不属于本文的讨论范围。这是我们以后着重要讨论的东西。如果你不急着用C++的新特性,了解上面的东西后你就已经可以写出正确的C++程序了。

做人要厚道
转贴请注明出处

17 条回复

  • 楼层: 沙发 | | 逆铭 说:

    新的c++标准好像建议包含C++头文件时不加.h,如 #include <iostream>
    如果要包含C的库文件也不加.h,但是要在库名前加字母c。如C++的string头文件:#include <string>;C的string头文件:#include <cstring>
    再就是命名空间了,一般OI的程序里要加上using namespace std;
    命名空间搞得不是很清楚,不说了……

    暂时想到这些,也不知道对不对。

    回复:以io头文件为例
    iostream是C++的头文件,C++ style的IO操作
    cstdio也是C++的头文件,C-style的IO操作,和C的stdio.h没啥区别,只是放进了std命名空间里,因此要加using namespace std
    stdio.h是C的头文件,C++包含它不会出错,用法完全和C一样,不用加using namespace std。这能保证C代码可以在C++编译器下通过编译
    不知道说的对不对

    C++头文件和命名空间都属于新特性,不是语法的区别,因此留着以后说。不专门介绍命名空间的话很难解释清楚为什么要加一句using namespace std

  • 楼层: 板凳 | | ISO 说:

    厄,个人觉得,有的时候用用C++的标准流还是有好处的,C的经典流有些地方用起来确实有些麻烦,比如long long类型。。。
    感觉namespace是软件工程用的,OI米什么用。。。

    回复:C++的流是个好东西;namespace确实没啥用

  • 楼层: 地毯 | | INFINITE_Li 说:

    C99引入的_Bool其实就是布尔类型,stdbool.h只是做了这个手脚:#define bool _Bool.

  • 楼层: 地板 | | INFINITE_Li 说:

    记得以前看书的时候好像是说……当工程中变量名的数量大于某个非常大的数(比如10000)的时候,Namespace就有用了……对于OI……

  • 楼层: 地下室 | | Clear 说:

    struct date
    {
        int year;
        int month;
        int day;
    };
    struct date now;            //C
    date now;                      //C++
    因为C++中struct也是类,和class定义的方法一样,相当于
    class date
    {
    public:
        int year;
        int month;
        int day;
    };

    回复:没研究过这个,第一次听说,长见识了。

  • 楼层: 地基 | | Clear 说:

    记得以前看书的时候好像是说……当工程中变量名的数量大于某个非常大的数(比如10000)的时候,Namespace就有用了……对于OI……

    MS不是这样的的吧,应该是解决多个库(或工程)共用时出现的名字冲突问题。比如你要同时用2个数学库,一个叫Maths,还有一个叫Mars(当然是假如,不过个人觉得数学确实蛮火星的),然后两个库都定义了一个名叫solve的函数,Maths中是用来解方程的,Mars中是用来解递归式的。你要用解方程的那个solve时就Maths::solve,你要解递归式的时候就Mars::solve。
    不过对于OI,个人觉得实在是没什么用的还要多写一句using namespace std;

    回复:正解。

  • 楼层: 地壳 | | upsuper 说:

    貌似C++推荐采用流吧。。。
    不过好像流的速度很慢的说~读大数据可以慢1s+呢~
    Amber说C的读取结构和Pascal不一样~即使用标准scanf读入大的数据也会慢0.8s+(上次有道题就败在这里了。。。)怎么办呢。。。

  • 楼层: 地幔 | | ISO 说:

    貌似C++推荐采用流吧。。。
    不过好像流的速度很慢的说~读大数据可以慢1s+呢~
    ......
    即使用标准scanf读入大的数据也会慢0.8s
    ......

    需要澄清的是C/C++都是用流读入数据,这个概念要搞清楚。
    然后C++流(我比较习惯叫他标准流)是对C的流(我比较习惯叫他经典流)的封装。

  • 楼层: 地核 | | 逆铭 说:

    http://blog.sina.com.cn/u/4a443fd7010008wn
    这是我原来做的关于C和C++输入输出测试,比较诡异,win和linux的结果竟然不一样……

    回复:我一直在思考,是不是只有搞OI/ACM的才会做这种事

  • 楼层: 10楼 | | 逆铭 说:

    struct date
    {
        int year;
        int month;
        int day;
    };
    struct date now;            //C
    date now;                      //C++
    因为C++中struct也是类,和class定义的方法一样,相当于
    class date
    {
    public:
        int year;
        int month;
        int day;
    };

    回复:没研究过这个,第一次听说,长见识了。

    我觉得class和struct其实是一样的,struct也可以有成员函数,只是写成class显得比较牛X,说明你会OOP……struct就是成员默认是public的class,class就是成员默认是private的struct

  • 楼层: 11楼 | | Clear 说:

    ......
    因为C++中struct也是类,和class定义的方法一样
    ......
    回复:没研究过这个,第一次听说,长见识了。

    《C++ Primer》是这么说的,里面还说union也是类定义的一种。当初从Pascal转C++的时候就是听了火牛的建议去看这本书的。有些厚了,不过应该比CLRS薄些(MS印刷的纸张厚了些,这样翻不烂吧[confused])。看下来OOP算是根深蒂固了,不过对于OI来说显然是罗嗦了些。个人认为当本必备的手册有空翻翻还是有好处的,有些东西就不要怎么去深究,毕竟这样没什么意义。

    to 逆铭:完全同意你的说法

  • 楼层: 12楼 | | 地瓜 说:

    做题最好不用C++流测试数据大点绝对超时
    scanf用15MS的时候cin会到2s
    c++不是给做题的人用的是用来安全高效地避免重复劳动地做项目安全方便的代价就是时间开销 空间开销不大清楚

  • 楼层: 12a楼 | | iceboy 说:

    struct date
    {
        int year;
        int month;
        int day;
    } now;

    c++ 可以这样写, 不知道 c 可不可以...

    还有, struct 和 class 有微妙的区别, 比如东西存在哪个地方...

  • 楼层: 14楼 | | fearlessxjdx 说:

    请教大牛
    void shownumber()
    {cout<<number}
    number是在class下的私有函数
    这个函数是公有函数 但这个函数是什么意思啊

  • 楼层: 15楼 | | fearlessxjdx 说:

    不好意思我说错了number是私有成员

  • 楼层: 16楼 | | CPrimer 说:

    而且C语言没有引用类型,这个也挺有意思的,和C++的不太一样

  • 楼层: 17楼 | | DMKaplony 说:

    貌似我用c的读入输出比pascal慢了很多。。1M的文件。pascal 0.12s 左右。。c的stdio竟然1.12s。。我很是无语啊。。

您也随便说几句吧:

您可以在 Gravatar 设置您的头像。