C 与 C++ 的差异

C++ 是 C 的超集和增强,校验更加严格 C 主要是面向过程,C++ 是面向对象,面向过程是函数驱动,面向对象是对象驱动 1 新增命名空间 给{}作用域起了个名称,后面不用加分号; 命名空间可以嵌套 namespace X { namespace Y { } } 2 新增引用类型 引用在一定程度上可以替代指针,作用与常指针类似 int * const a 引用没有定义,是一种关系声明,声明它和原有某一变量(实体)的关系, 故而类型与原类型保持一致,且不分配内存,与被引用的变量有相同的地址 声明时必须初始化,一经声明,不可变更 可对引用再次引用,多次引用的结果是某一变量具有多个别名 & 符号在 = 号左边是引用,在 = 号右边为取地址 3 枚举检测增强 不能将整型隐式转化为枚举 4 变量定义增强 C++ 变量不必都声明在函数顶部,可以随使用随定义 5 全局变量定义检测严格 C 全局变量重复定义,C++ 不可以,全局变量检测增强 // C 语言 int g_val; // bss段 int g_val = 10; // data段 6 函数形参个数和函数返回值检测增强 // C 语言 f() // 默认返回值 int { return 10; } int g(int a) { return 10; } // 调用 g(10, 20, 30, 40); // 可编译通过,但是有警告 7 struct 结构体增强 功能与类基本等同,只不过 class 默认是 private 权限,struct 默认是 public 权限 // C 语言声明结构体变量 struct Student s; // C++ 语言声明结构体变量 Student s; 8 新增 bool 关键字,1 个字节 C 用 0 表示 false,非 0 表示 true C++ 中 bool 为 1 个字节,但是只有 true 和 false 两个值 9 三目运算符增强(语法糖) C 中三目运算符不可以当左值 // C 语言 int a = 10, b = 20; ((a < b) ?...

December 22, 2021 · 2 min · Rick Cui

函数形参从右到左入栈

int add(int count, ...) { // 指针大小与程序位数有关(32位指针是4个字节,64位指针是8个字节) int intSize = sizeof(int*) / sizeof(int); int sum = 0; // cout << &count << endl; int *p = &count + intSize; // cout << p << endl; for (int i = 0; i < count; ++i) { sum += *p; cout << *p << endl; p += intSize; } return sum; } int main() { cout << add(3, 1, 2, 3) << endl; return 0; } 输出:...

December 22, 2021 · 1 min · Rick Cui

指针 + 1

1. 32 位和 64 位程序指针是多少位 32位指针大小为4个字节,64位指针大小位8个字节 2. 指针加 1,是对该指针增加 1 个储存单位 “存储单位”,指的是指针指向的数据类型所占的内存的字节数。不同类型的指针加1后,增加的大小不同。 int main() { int a[] = {1, 2, 3, 4, 5}; // &a是数组指针,其类型为 int (*)[5],a是长度为5的int数组指针,所以要加 5*sizeof(int),所以ptr实际是a[5]; // &a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int) // 但是prt与(&a+1)类型是不一样的(这点很重要,ptr指向的是整形),所以prt-1只会减去sizeof(int) int *ptr = (int*)(&a + 1); cout << *(a + 1) << endl; cout << *(ptr - 1) << endl; return 0; } 输出: 2 5 注: a,&a的地址是一样的,但意思不一样: a是数组首地址,也就是a[0]的地址,a+1是数组下一元素的地址,即a[1] &a是对象(整个数组作为一个对象)首地址,而&a+1是下一个对象的地址,即a[5].

December 22, 2021 · 1 min · Rick Cui

模板类

结论 不建议将模板类的声明和定义分开,一般把这个文件叫做 .hpp,以便与 .cpp 文件进行区分,表示这个文件中使用了模板 模板类进行了两次编译,在第二次编译(模板类使用的时候)时才会生成真正的调用函数 声明和定义分开方式一:可将定义放在同名的 .inl 或 .tpp 文件中,同时在头文件的末尾使用 #include 包含进来,不可放到 .cpp 文件,否则会造成嵌套包含 声明和定义分开方式二:在头文件中声明实例化,并在一个源文件中定义它,这样它只会被实例化一次,而不是每个翻译单元,这可能会加快编译速度,但是只能使用已经显式声明的模板类实例 不建议在模板类中使用友元函数 声明和定义在同一文件 // Test.h // 写法二:前置声明 template<typename T> class Test; template<typename T> void printTest(Test<T>& t); template<class T> class Test { public: Test(T t){ m_t = t;}; // explicit Test(T t){ m_t = t;}; // 1. 直接在类内定义 // T getValue(){ // return m_t; // }; // 2. 类外定义 T getValue(); // 3....

December 22, 2021 · 2 min · Rick Cui

模板函数

template <typename T> inline const T& Max (const T& a, const T& b) { return a < b ? b:a; }; int main() { int i = 39; int j = 20; cout << "Max(i, j): " << Max(i, j) << endl; double f1 = 13.5; double f2 = 20.7; cout << "Max(f1, f2): " << Max(f1, f2) << endl; string s1 = "Hello"; string s2 = "World"; cout << "Max(s1, s2): " << Max(s1, s2) << endl; return 0; } 输出:...

December 22, 2021 · 1 min · Rick Cui