c++冷知识

1. 表达式计算方向

printf和cin,cout是从右往左计算.
其他表达式从左往右计算,比如逗号表达式,但是逗号表达式返回值是最右边的值。逗号运算符优先级最低,所以要加括号。

int b[5] = { 1,2,3,4,5 };
int* p = b;
printf("%d, %d\n", *(p), *(++p));//输出2, 2

int i = 1;
int a = (2,i=3, i);
cout << a; //输出3

函数参数从右向左压栈,主要是处理变长参数

2. sizeof

sizeof是宏不是函数,是在编译期间执行的。
sizeof参数类型:类型(类)还是变量(对象)是等价的,可同意按照类型或变量来计算。
sizeof参数类型:函数,按照返回值类型计算。而且函数并不会在编译期间运行。

注意数组和指针区别:
sizeof只有参数为数组类型或者数组引用类型大小的时候计算整个数组大小,参数为指针类型的时候计算指针大小。

void func(int a[])
{
	cout << sizeof(a); 
	//因为计算sizeof是在编译器函数不运行,所以a是指针类型,所以输出8(64bit系统).
}
int main(void)
{
	int a[10];
	int* p = a;
	sizeof(a);//40数组类型
	sizeof(p);//8指针类型
	return 0;
}

typedef int(&Arr)[10];// sizeof(Arr) 40
typedef int(*Arr)[10];//sizeof(Arr) 8
typedef int Arr[10];//sizeof(Arr) 40

3. 负数补码

计算机中负数以补码表示。原码—(除符号位取反+1)–>补码—(-1除符号位取反)–>原码

-8:原码 1000 1000
	补码 1111 1000

4. 返回值优化

临时对象产生:值传递的形参;值传递的返回值。

A f()
{
	A(1) t;
	return t;
}
A a = f();

函数返回的过程:生成对象t–> 生成临时对象t1,并把t拷贝过去–>函数调用完t被析构->将t1赋值给a.。总共三次对象创建,两次拷贝。

优化过程:调用的时候虽然对象a还没调用构造但是已经分配内存,这时候直接将a地址传入函数体,直接对a初始化,整个过程之调用一次构造函数,不涉及拷贝。

5. 排序/集合中 比较函数的写法

例如std::sort、std::set、std::map中都可以传入自定义比较函数,那么比较函数如何定义呢?
effective c++中说到:永远让比较函数对相等的值返回false。

根据,排序/容器中对比较函数的使用,比较函数必须遵循"Strict Weak Ordering"的概念,它要求必须满足以下的条件:
1.自反性:即comp(x, x)必须是false
2.非对称性:即若comp(x, y)和comp(y, x),其结果必然相反
3.可传递性:即若comp(x, y)为true, comp(y, z)为true,那么comp(x, z)必然为true

例如要求按分数从小到大排序,分数相同的按加入时间顺序排序
使用stable_sort是稳定排序,不改变相同元素相对位置,能保证加入顺序。

struct Student {
  int id;
  int score;
};

vector<Student> stus;
stus.push_back({0, 50});
stus.push_back({1, 50});
stus.push_back({2, 50});
auto cmp = [](const Student& l, const Student& r) {
 return l.score <= r.score;
};

std::stable_sort(stus.begin(), stus.end(), cmp);
// 结果:
// {2, 50}, {1, 50}, {0, 50}

比较函数违背了自反性,应该定义成

auto cmp = [](const Student& l, const Student& r) {
 return l.score < r.score;
};

我们定义cmp的时候先想好比较规则,然后用自反省验证下就OK了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值