C++入门

C 是面向过程的语言,而 C ++ 是面向对象的语言。

C ++ 在某种程度上,可以理解为 C 语言强化版。两种语言有不少相似之处,且大部分时候,C ++ 可以兼容 C 语言。C ++ 可以直接运行 C 语言函数,但 C 语言不能调用 C ++。

C ++ 中,const 常量的不可变性得到了支持,而在 C 中,函数定义的 const 常量,可以通过指针修改。

C ++ 支持函数重载(同名函数,不同参数),C 不支持(C 函数名称不可重复);C++ 的函数支持默认参数,C 和java 都不支持。

C ++ 有 string、bool 类型,而 C 中没有专门的string、bool;但二者都是非 0 即 true

命名空间

命名空间,作用类似于 java 中的包名,为了在引用时区分不同库中定义的同名函数或变量。

命名空间可以用双冒号(::)表示;也可以直接在文件中用using指示进行声明,使得特定命名空间的所有名字可见

#include <stdio.h>
#include <iostream>
int main() {
    // C ++ 中,可以调用 C 语言的输出方法
    printf("this is a C output in C++\n");
    // C ++ 自己的输出方法
    // << 运算符被重载,此处并不是左移,而是输出流拼接,可以理解为输出格式
    std::cout << "this is a C++ couput" << std::endl;
    return 0;
}

// 直接声明命名空间
//using namespace std;
//
//int main() {
//    //声明命名空间后,无需再用 std:: 方式指明函数的所在
//    cout << "this is the output with namespace" << endl;
//    return 0;
//}

自定义命名空间

命名空间的定义一般置于 .hpp 的头文件中,作为对外开放的接口声明。

// 自定义一个命名空间
namespace bynamespace {
// 命名空间可以有变量
char * property;
// 类
class ObjectManager {
private:
    char *className;
public:
    char * getClassName();
    void setClassName(char *className);
};
// 方法
void function(ObjectManager manager);
// 方法可能与其他命名空间的方法冲突
void cout();
// 命名空间内还可以嵌套命名空间
namespace subnamespace {
void sayHello();
}
}

// 添加命名空间引用
using namespace std;
using namespace bynamespace;


int main() {
    // 由于添加了引用,可以省略命名空间的名称
    ObjectManager manager = ObjectManager();
    bynamespace::function(manager);
    // 嵌套的命名空间,在没有添加命名空间引用时,应为:bynamespace::subnamespace::sayHello();
    subnamespace::sayHello();
    // 当两个命名空间内方法冲突时,不可以省略命名空间名称,即便已经添加了引用
    bynamespace::cout();
    std::cout << "print" << endl;
    return 0;
}

函数特性

C++ 中,函数支持重载和传参默认值,但是默认值不似 kotlin 中那般灵活。C++ 中函数的参数默认值,必须从右往左进行默认值设置;在调用时,必须从左到右,传入参数。

且在函数声明时,需注意,要避开默认值可能带来的函数重载。

using namespace std;

// 全赋值默认参数;此方法在调用时,无法跳过 a、b 直接给 c、d 赋值
int sum(string s, int a = 0, int b = 0, int c = 0, int d = 0) {
    // sum(); -> a: 0, b: 0, c: 0, d: 0
    // sum(1, 2); -> a: 1, b:2, c:0, d:0
    // sum(1, 2, 3, 4); -> a: 1, b:2, c:3, d:4
    cout << "a: " << a << ", b:" << b << ", c:" << c << ", d:" << d << endl;
    return a + b + c + d;
}

// 不能这样赋值默认值,必须从右到左填充,填充完 a,之后才可以填充 s
// int sum(string s = "abc", int a, int b = 0, int c = 0, int d = 0)

// 此方法无法再进行声明,因为在上面的sum中,已经包含了两个 int 参数的重载
// 但在声明方法时,并不会报错,而是在使用方法时报错
// int sum(string a, int b);

// 此方法可以重载,因为上面默认值的方法第一个参数是 string,重载的方法,需从左到右保留参数 
int sum(int a, int b);


int main() {
    int t1 = sum("test1");
    int t2 = sum("test2", 1, 2);
    int t3 = sum("test3", 1, 2, 3, 4);
    // 如果上面声明了 int sum(string a, int b) 方法,则会报错:Call to 'sum' is ambiguous
    // int t4 = sum("test4", 1);
    cout << "t1: " << t1 << ", t2:" << t2 << ", t3:" << t3 << endl;
    return 0;
}

此外,在 C 或者 C++ 中,函数的参数声明,可能只有类型,而没有参数名。

一般这种没有参数名的函数声明,只是用于 .h 的声明中,在后续的实现函数中还是需要填写名称的,否则没有参数名的形参无法在函数体内被使用。

// 在参数声明时,只有类型 int,没有参数名
void printInfo(const int &, int);
// 调用时需要传入一个 string 类型,但是并没有任何用处,不建议这么写
void printInfo(string) {
    cout << endl;
}
int main() {
    int a = 100;
    // 调用时,必须传递该 int 类型参数
    printInfo(a, 0);
    return 0;
}
void printInfo(const int &value, int level) {
    cout << "value: " << value << ", level: " << level << endl;
}

静态变量

静态变量可以直接在函数外部进行定义,全局可用。

static int DEBUG = 1;

在类中,需要先声明的静态变量,然后再初始化

class Test {
  public:
    // 先声明
    const int a;
}
// 再初始化
int Test::a = 10;

可变参数

C 和 C++ 中,都支持 ... 可变参数。
但与java 不同的是,无法自动识别参数个数。
因而一般在定义时,都会在参数前添加 int cout 参数声明接下来的 ...包含几个变量。
... 参数必须位于最后一个位置。
... 支持传入不同基本类型(不支持自定义类型),但需要在解析的时候按顺序解析。

在使用 ... 参数时,需要先创建 va_list 类型变量用于存储这一系列参数。
通过 va_start(args, count) 将变量的值转移到 va_list 中;其中 count 变量需要传值 ... 的前一个函数入参。
通过 va_arg(ags, int) 方法,将 args 中的参数取出,其中int 为对应参数的类型。
最后需要用 va_end(args) 结束 args 的读取。

int sum(int count, ...) {
    int result = 0;
    // 创建存储入参的变量
    va_list args;
    // va_start 将入参读取到 args 中,需要 ... 参数的前一个参数作为读取锚点
    va_start(args, count);
    for (int i = 0; i < count; i++) {
        // va_arg 读取 args 中的参数,需要传入对应的数据类型
        result += va_arg(args, int);
    }
    // 结束读取后,需要调用 var_end 方法
    va_end(args);
    return result;
}

int main() {
    cout << sum(2, 10, 20) << endl;
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,492评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,048评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,927评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,293评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,309评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,024评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,638评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,546评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,073评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,188评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,321评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,998评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,678评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,186评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,303评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,663评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,330评论 2 358

推荐阅读更多精彩内容