本文共 1496 字,大约阅读时间需要 4 分钟。
C语言与C++语言学习笔记
1. 全局变量与多个组成部分共享
全局变量可以在可被多个组成部分包含的头文件中定义,这一特性在编程时非常有用。它能够保证变量在各个模块之间保持一致。
2. 多线程应用中的输出问题
以下程序输出会经历多次fork()操作,导致缓冲区内容被复制多次:
int i;for (i = 0; i < 2; i++) { fork(); printf("-");} 这个程序会执行6次printf调用,但只有2次实际输出。因为父进程的输出缓冲区会被子进程复制,导致多个进程同时writing到缓冲区,结果呈现以下情形:
- fork() // i=0
- printf("-") // buffer="-"
- fork() // i=1
- printf("-") // +1
- printf("-")
- printf("-") // fork() // i=1
- printf("-") // +1
- printf("-")
最终的结果共出现了8个“-”符号。
3. C++中类成员的特性
C++中,静态成员属于整个类而非单个对象,具有如下特点:
- 静态成员函数:在对象创建前即被分配内存,且只能访问静态成员。
- 静态成员的可修改性:所有对象均可修改其值,可以被共享。
静态成员的声明方式为static,而常量通常由final关键字声明,不可修改。
静态成员不具备多态性,无法通过多态实现。
4. 内存管理函数
以下内存分配函数是常用的:
- malloc():在堆中分配内存,需使用
free()释放。 - calloc():与malloc类似,但初始化值为0。
- realloc():扩容时使用,需确保新大小大于现有块大小。
内存分配类型:
- 栈alloc():用于栈中的内存分配,无需释放。
- 堆malloc():默认使用堆分配。
5. C++中不可被继承的成员函数
在C++类体系中,不可被派生类继承的成员函数包括:
- 构造函数(Constructor)
- 静态成员函数(Static member function)
- 非静态成员函数(Non-static member function)
- 赋值操作函数(Assignment operator)
构造函数与派生类继承规则:
- 派生类无需显式调用基类构造函数,但编译器会依据构造函数的参数进行调用。
- 默认构造函数仅在没有显式定义的情况下提供。
6. 静态变量特性
静态变量在程序执行周期内始终存在,使其在多个函数中使用成为可能。
7. 抽象类特点
抽象类由于无可实例化对象而成为基类,主要用途有:
特征:
- 含有纯虚函数的类为抽象类。
- 抽象类不能实例化,需通过继承实现。
8. 转换类型
在C++中,不同转换类型的地位有所不同:
- reinterpret_cast:对任何类型的指针转换均可使用。
- static_cast:需程序员判断转换安全性。
- const_cast:用于常量与非常量的转换。
- dynamic_cast:对指针或引用进行安全性转换。
9. 二进制在C语言中的表示
C语言中的整数默认为二进制格式,例如:
int i = 1; // 二进制:1static int mask = (~0) << 1; // 十进制:2
十六进制表示需使用0x前缀。
10. 多线程i++安全性
多线程环境中的i++操作并不绝对原子性,因为内存操作分解为多个步骤:
因此在并发执行下,正确读取和写入顺序至关重要。如上文所述,最终i值可达最大值200和最小值2。
转载地址:http://hjcgz.baihongyu.com/