语法

作者: 夜雨聲煩_ | 来源:发表于2021-05-10 17:50 被阅读0次

    基础

    后缀.cpp。(C Plus Plus)
    编译 C++程序时,gcc命令也可以使用,不过要增加-lstdc++选项,否则会发生链接错误。

    对象

    Student stu;
    栈上创建一个Student类的实例对象stu
    Student *pStu = new Student;
    堆上创建一个Student类的实例对象pStu
    使用stu.name访问对象变量。
    使用pStu -> name访问对象指针的对象变量。

    class Student{
    public:
        //成员变量
        char *name;
        int age;
        float score;
        //成员函数
        void say();  //函数声明
    };
    //函数定义
    void Student::say(){
        cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl;
    }
    

    函数

    //函数定义
    void Student::say(){
        cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl;
    }
    

    但当成员函数定义在类外时,所有文件均可以实现,因此就必须在函数名前面加上类名予以限定,同时这个定义此函数的文件不能引用实现文件,否则会报重复引用的错误。::被称为域解析符(也称作用域运算符或作用域限定符),用来连接类名和函数名,指明当前函数属于哪个类。

    在类体内定义函数称为内联函数(inline),仅适合短小简单的函数。

    如果类外函数想定义成内敛函数使用inline关键字。

    命名空间

    为避免多人协同开发全局变量命名冲突,C++提供命名空间。

    namespace Li {
        FILE fp = NULL;
    }
    
    namespace Han {
        FILE fp = NULL;
    }
    

    使用变量、函数时要指明它们所在的命名空间。以上面的 fp 变量为例,可以这样来使用:

    Li::fp = fopen("one.txt", "r"); //使用小李定义的变量 fp
    Han::fp = fopen("two.txt", "rb+");//使用小韩定义的变量 fp
    

    ::是一个新符号,称为域解析操作符,在 C++中用来指明要使用的命名空间
    除了直接使用域解析操作符,还可以采用 using 关键字声明,例如:

    using Li::fp;
     //using namespace Li; 也可
    fp = fopen("one.txt", "r"); //使用小李定义的变量 fp
    Han :: fp = fopen("two.txt", "rb+"); //使用小韩定义的变量 fp
    

    对于不带.h 的头文件,所有的符号都位于命名空间 std 中,使用时需要声明命名空间 std;带.h 的头文件,没有使用任何命名空间,所有符号都位于全局作用域。
    而为了使用cout等函数,都需要统一using namespace std

    iostream

    iostream 是 Input Output Stream 的缩写,意思是“输入输出流”。
    cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl;
    cout打印函数,<<name<<双尖括号包含变量,"的年龄是"双引号包含文本,endl结尾。endl表示end of line\n含义一样。
    cin输入函数,接>>

    cincoutiostream的内置对象,而不是关键字。在C++中推荐使用他们,替代printfscanf

    数组

    Student allStu[100];
    创建一个 allStu 数组,它拥有100个元素,每个元素都是 Student 类型的对象。

    变量的定义

    C89和C99是两套不同的C语言标准,在C89中要求变量必须定义在函数开头,而作为C89的升级C99,则没有此要求。而在我们常用的XCode中,就没有此要求,只要变量实在使用前定义就可以,不用定义在开头。另外,此要求不针对C++。

    bool类型

    C语言没有彻底从语法上支持真假,只是0为假,非0为真。而在C++中则引入bool类型,占1字节,true表示真,flase表示假。只是用cout输出时,还是01,在java中可以输出turefalse

    const 在C和C++中有趣的不同处理

    const int m = 10;
    int n = m;
    

    这一段代码在C和C++中含义并不相同。如果使用C语言的环境来编译,则相当于先取出m所在内存取出数据10,再将10赋值给n。而对于C++编译来说,const更像#define,将10等价替换m
    因为常量通常不可修改,所以这两种方式最后的结果相同。
    但对于特殊情况,例如修改常量。当使用指针的方式,修改常量的内容后:

    const int n = 10;
    int *p = (int*)&n;
    *p = 99;
    int m = n;
    

    在C中,m等于99,而在C++中,m等于10。

    实际开发中并不会出现这种强行修改常量的情况,只是说明const在C++中类似于#define的处理。

    C和C++中const的作用域相同,都是当前文件,不同的是可见范围。在C语言中整个程序可见,在其他文件中使用extern声明后就可以使用。而C++中仅限于当前文件,其他文件不可见,因此可以定义在头文件中,多次引用也不会出错。

    内存

    C语言中使用malloc()分配内存,使用free()释放内存。

    int *p = (int*)malloc(sizeof(int) * 10);
    free(p);
    

    在C++中使用newdelete来构造和析构。

    int *p2 = new int[10];
    delete [] p2;
    

    内联函数

    使用inline关键字来定义内联函数。内联函数适用于函数体比较小的函数,在某些情况下适用于替换宏定义。例如:

    #define SQ(y) y*y
    

    如果传入SQ(n+1)那么结果就是2n+1而不是n+1的平方。而使用内联函数可以很好的解决这个问题,如下:

    inline int SQ(int y){ return y*y };
    

    当然,也可以多食用括号来解决宏定义的问题,如下:

    #define SQ(y) (y)*(y)
    

    推荐使用内联函数。能替代宏定义才更能提现内联函数的作用。
    声明的时候不需要使用inline关键字来指明是否是内联函数,而在实现的时候使用inline来指明。

    函数默认参数

    函数可以有默认参数,这点类似于Swift,不同于OC。

    void func(int a, b=10, c=@"msg"){ }
    func(5,2); //可以只传一个或者两个参数
    

    注意有多个形参时有默认的参数都放在后边,没有的放在前面。
    此写法为错:void func(int a, b=10, c=@"msg", int d){ }
    同时注意,如果在一个文件中,在声明中指定默认参数,在实现时同样指定默认参数,即时指定的一样,编译器也会报默认参数赋值两遍的错。但如果声明和实现不在一个文件,则不会报错。而且,如果同文件中声明中默认B参数,实现默认C参数,也不会报错。

    函数重载

    函数名相同,参数不同,返回值无所谓的函数。
    void Swap(int a,int b)会被重命名为_Swap_int_int;void Swap(float a,float b)会被重命名为_Swap_float_float

    函数重载只是语法上的,实际上他们是不同的函数,占用不同的内存,不一样的入口地址。

    C与C++混编

    因为C++中void Swap(int a,int b)会被重命名为_Swap_int_int,而C中会被重命名为_Swap,所以C++中直接调用自定义的C方法会报错。

    #ifdef __cplusplus
    extern "C" void display();
    #else
    void display();
    #endif
    

    相关文章

      网友评论

          本文标题:语法

          本文链接:https://www.haomeiwen.com/subject/tjbidltx.html