C/C++学习笔记


C语言学习笔记

#define

  • C语言中,可以用 #define 定义标识符。其特点是:定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了。预编译又叫预处理。预编译不是编译,而是编译前的处理。这个操作是在正式编译之前由系统自动完成的。#define#include 类似,凡是以“#”开头的均为预处理指令。(出处:C语言中文网

  • #define的几种类型:

    /* 定义常量 */
    #define A 10
    /* 定义表达式 */
    #define MAX(A, B) ((A) > (B) ? (A) : (B))
    /* 特殊符号 */
    #define A(x) T_##x
    #define B(x) #@x
    #define C(x) #x
    /*
    * 输入: A(a); 输出: T_a.
    * 输入: B(a); 输出: 'a'.
    * 输入: C(a); 输出: "a".
    */
    /* 分行 */
    #define FUN(A,B,C) \
    void A##B(){\
        std::cout<<#C<<std::endl;\
    }

extern "C"

  • extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上 extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;但C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。这是二者在编译时的主要区别。

  • 例子:

    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    ......
    
    #ifdef __cplusplus
    }
    #endif

函数调用约定

__stdcall

被这个关键字修饰的函数,其参数都是从右向左通过堆栈传递的(__fastcall 的前面部分由ecx,edx传), 函数调用在返回前要由被调用者清理堆栈。

  • 例子:
    int __stdcall fun();

博客

const int a; int const a; const int *a; int * const a; int const * a const; 之间的区别

C++学习笔记

explicit

explicit关键字只需用于类内的单参数构造函数前。由于无参数的构造函数和多参数的构造函数总是显式调用,这种情况在构造函数前加 explicit无意义。

google的c++规范中提到:explicit的优点是可以避免不合时宜的类型变换,缺点无。所以google约定所有单参数的构造函数都必须是显式的,只有极少数情况下拷贝构造函数可以不声明成 explicit,例如作为其他类的透明包装器的类。
effective c++中说:被声明为explicit的构造函数通常比其non-explicit兄弟更受欢迎。因为它们禁止编译器执行非预期(往往也不被期望)的类型转换。除非我有一个好理由允许构造函数被用于隐式类型转换,否则我会把它声明为explicit,鼓励大家遵循相同的政策。

枚举类型

enum

常量字符串

在C语言中,常量的 char*-based 字符串为:const char* const tmp = "blogg9ggg";

在C++中,定义成 string 往往更好:const std::string tmp("blogg9ggg");

char s[] = "test";
char *p = s;			// 普通指针
const char* p = s;		// non-const pointer, const data
char* const p = s;		// const pointer, non-const data
const char* const p = s;	// const pointer, const data
// 如果 const 出现在 * 左边,代表被指物是常量;
// 如果 const 出现在 * 右边,代表指针是常量;
// 如果出现在 * 两边,代表都是常量。

构造函数

copy构造函数被用来“以同类型对象初始化自我对象”,copy assignment操作符被用来“从另一个同类型对象中拷贝其值到

class Widget {
public:
	Widget();				//default构造函数
	Widget(const Widget& rhs);		//copy构造函数
	Widget& operator=(const Widget& rhs);	//copy assignment操作符
	...
};
Widget w1;	//调用default构造函数
Widget w2(w1);	//调用copy构造函数
w1 = w2;	//调用copy assignment操作符
Widget w3 = w2;	//调用copy构造函数!

博客

namespace

四种类型转换运算符:static_cast、dynamic_cast、const_cast和reinterpret_cast

C++ 虚函数和纯虚函数的区别


文章作者: 李立基
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 李立基 !
  目录