一些偏门的点
-
endl可以用\n代替
cout<<"Hello world"<<"\n"
-
int main()括号里加void才能表示不可传参
// 这样是正确的
int main()
{
if (0) main(42);
}
// 这样会出错
int main(void)
{
if (0) main(42);
}
默认编译产生的文件名就是cpp的名且不带后面的参数。如果是在命令行窗口编译的,可以显示出arg 1--3
g++ test_main.cpp -o a
a.exe abcd bcde cdef
- 命名空间可自定义,不一定非要用std
#include <iostream>
namespace MyNamespace {
int value = 5;
void printValue() {
std::cout << "Value: " << value << std::endl;
}
}
int main() {
MyNamespace::printValue();
MyNamespace::value = 10;
MyNamespace::printValue();
return 0;
}
- 用宏控实现注释
#if condition
code1
#else
code2
#endif
-
枚举类型默认第一个是0
enum color { red, green = 5, blue };
依次是0 5 6 -
#define没有作用域限制,typedef有
-
const修饰谁的问题
是从右往左结合的,如下:
#define PINT int*
typedef int* pint
int i1 = 1, i2 = 2;
//pint自带括号,所以第一句实际上是 const (int*) p1 ,这里const修饰p1
// 第二句是宏定义展开,所以实际上是,const int (*p2) ,这里修饰*p2
const pint p1 = &i1; //p1不可更改,p1指向的内容可以更改,相当于 int * const p;
const PINT p2 = &i2; //p2可以更改,p2指向的内容不能更改,相当于 const int *p;或 int const *p;
** //也就是说,int *p事实上,是p先和*表示是指针类型,然后再和int结合,而不是把int*作为一个类型**
pint s1, s2; //s1和s2都是int型指针
PINT s3, s4; //相当于int * s3,s4;只有一个是指针。
-
int long longlong字节问题
-
自动转换的规则
- 先转换成同一类型再运算
- 转换方向是精度增高、字节变长、有符号转为无符号
- float实际运算时也是double运算的
- char和short实际运算时是int运算的
- 赋值运算,可能会让右值精度丢失
- 一般情况是作用域小的优先覆盖,有例外
int g = 99;
int func();
int main()
{
int g = 10;
//cout << g;
int kk = func();
cout << kk; //kk = 99
return 0;
}
int func()
{
return g;
}
改变全局变量的值
// 全局变量声明
int g = 20;
int fun1(int a,int b){
g=a+b;
cout<<"被改变的全局变量为:"<<g<<endl;
return 0;
}
int fun2(){
cout<<"此时的全局变量为:"<<g<<endl;
return 0;
}
int main(){
fun2();
fun1(10,20);
fun2();
return 0;
}
全局变量a和局部变量a,要想在局部的作用域调用全局的a,可以用 ::a
静态局部变量作用域是整个程序运行期间,准确的说只要加静态都是整个程序运行期间,静态局部还可以保证每次调用的都是上次的值,只会初始化第一次
-
整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。
-
字符常量是括在单引号中。如果常量以 L(仅当大写时)开头,则表示它是一个宽字符常量(例如 L'x'),此时它必须存储在 wchar_t 类型的变量中。否则,它就是一个窄字符常量(例如 'x'),此时它可以存储在 char 类型的简单变量中。
-
/不会输出任何,仅用于隔行写太长的字符串
-
#undef可以取消宏定义,但是const取消不了
-
无符号化为有符号的位数运算,采取 N-2^n 的计算方法,例如 N=50000,short 为 16 位,计算方法为 50000-2^16 得到 -15536。
基础知识
面向对象
- 封装
对外隐藏实现细节,只公开接口。提高安全性、可靠性和灵活性。 - 继承
从已有类中派生出新类,新类具有已有类的属性和方法,并且可以扩展或修改这些属性和方法。提高代码的复用性和可扩展性。 - 多态
多态是指同一种操作作用于不同的对象,可以有不同的解释和实现。它通过接口或继承实现,提高代码的灵活性和可读性 - 抽象
从实例中提取共同的特征,形成抽象类或接口,以封装为基础!!而不必关注底层的实现细节。
ANSI标准
为了保证c++可以运行在windows\linux\macos上,现在的编译器都符合这个标准
三字符组
之前的时候键盘有的字符打不出来或者冲突,就用??=代替# ??)代替]等,现在直接可以在键盘上找到或者转义字符
编程风格
有c fortran smalltalk等,分别代表底层,内存硬件的、科学计算的、面向对象的
数据类型
基本的就int float double char void bool wchar_t(宽字符型)
wchar_t ch2 = L'你';
修饰符有 long short signed unsigned
枚举类型
enum 枚举名{
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数]
} 枚举变量;
类型转换
预留...暂时没看懂
extern关键字
用于声明一个变量或函数,让编译器在其他文件中找定义,只能定义一次但可以声明无数次
定义包含了声明,但是声明可以不定义
作用域
包含局部、全局、块、类作用域
- 分别是函数调用创建,执行完销毁、程序开始创建,结束销毁、执行到{}创建,出括号销毁、与类相同生命周期
局部作用域是块作用域的一种特例,即函数内部的局部作用域是函数的块作用域。
块作用域可以包含更广泛的范围,例如在if语句、循环语句、switch语句等中声明的变量都属于块作用域
几个常用类型修饰符
- const 常量,初始化必须在定义时,后面无法更改
- volatile 该变量的值可能会被程序以外的因素改变,如硬件或其他线程。
- restrict 被restrict修饰的指针是唯一一种访问它所指向的对象的方式。C99标准加入。
说人话就是,即使定义了其他指针等于被restrict修饰的指针,它也无法访问到restrict修饰的指针指向的对象。 - mutable 表示类中的成员变量可以在 const 成员函数中被修改。
class MyClass {
public:
int getNumber() const {
// 可以修改被mutable修饰的变量
m_number = 10;
return m_number;
}
private:
mutable int m_number;
};
- register 用于定义寄存器变量,表示该变量被频繁使用,可以存储在CPU的寄存器中,以提高程序的运行效率