C++ 之 知识补充
函数指针
函数在内存中也是占用一段内存的所以我们也可以使用指针指向函数,之后只用指针调用函数,这一点在Python中有较好的体现,在个体类中直接调用适应度函数指针即可实现适应度的计算,因为Python中遵循一切皆指针的原则,所以直接以函数名传递即可实现。当然在cpp函数名也是函数指针类型的可以直接按函数指针进行传递,在北大视频中以数组排序函数为例进行讲解,其中比较函数则使用的函数指针进行传递。
函数对象
头文件:<functional>
若一个类重载了运算符"()",则该类的对象就成为函数对象。
STL中的函数对象类模板以下模板可以用来生成函数对象。
- equal_to
- greater
- less
- ... ...
函数对象应用
list有两个sort成员函数
-
void sort();
将list中的元素按"<"规定的比较方法升序排列 -
template
void sort(Compare op);
将list中的元素按op规定的比较方法升序排列。即要比较x,y大小时,看op(x,y)的返回值,为true则认为x小于y
//使用函数对象实现指数幂
template <typename T,int size=3>
class Power {
public:
T operator()(T value) {
T count = T(1);
for (int i = 0; i < size; i++)
{
count *= value;
}
return count;
}
};
//使用函数实现指数幂
template <typename T, int size = 3>
T power_fun(T value) {
T count = T(1);
for (int i = 0; i < size; i++)
{
count *= value;
}
return count;
}
int main(){
int num = 10;
int n = 3;
//使用函数实现10的三次幂
power_fun<int,n>(num);
Power<int,n> power_obj;
//使用函数对象实现10的三次幂
power_obj(num);
}
变参函数
cpp允许定义形参个数和类型不确定的函数。例如,C语言中的标准函数printf便使用这种机制。在声明不确定形参的函数时,形参部分可以使用省略号“…”代替。“…”告诉编译器,在函数调用时不检查形参类型是否与实参类型相同,也不检查参数个数。
头文件
类型
va_list : Type to hold information about variable arguments (type )
宏函数
函数 | 功能 |
---|---|
va_start | Initialize a variable argument list (macro) |
va_arg | Retrieve next argument (macro) |
va_end | End using variable argument list (macro) |
va_copy | Copy variable argument list (macro) |
示例 :
#include <stdio.h>
#include <stdarg.h>
void simple_printf(const char* fmt, ...){
va_list args;
va_start(args, fmt);
while (*fmt != '\0') {
if (*fmt == 'd') {
int i = va_arg(args, int);
printf("%d\n", i);
} else if (*fmt == 'c') {
// 将提升 'char' 类型值为 'int'
// C 中字符常量自身为 'int' 类型
int c = va_arg(args, int);
printf("%c\n", c);
} else if (*fmt == 'f') {
double d = va_arg(args, double);
printf("%f\n", d);
}
++fmt;
}
va_end(args);}
命令行参数
int main(int argc,char * argv[])
{
for(int i=0;i<argc;i++)
printf("%s\n",argv[i]);
return 0;
}
其中argc
为命令行参数的个数,argv
为参数的字符串,每个参数以空格为分割符,如果参数中间有空格通过引号括起来就好了,并且argc 和 argv 是包含程序名本身的。
函数重载
同函数的参数个数和类型进行函数调用。在Python中我们也可以通过对参数的类型和个数进行不同功能的实现。
位运算 可以提高运算效率
& //按位与(双目) 使得某些位变为0
| //按位或(双目) 使得某些位变为1
^ //按位异或(双目) 使得某些位取反
~ //按位取反(单目)
<< //左移(双目)
>> //右移(双目)
其中按位异或^
有特性a^b=c
, c^b=a
,c^a=b
可用于简单的加密和解密,例如以a为原文,b为秘钥,c则为密文。当我持有密文和秘钥的时候,便可以通过按位异或获取原文a。同时异或可用于两个整型变量进行交换。例如:
int a = 5,b = 7;
a = a ^ b;
b = b ^ a;
a = a ^ b;
类似于,因为可以通过运算将两个不想关的变量联系起来,类似于耦合解耦的过程:
int a = 5, b = 7;
a = a + b;
b = a - b;
a = a - b;
引用
引用就是别名,同时引用只能引用变量,且从一而终。const T &
和T &
不是同一种类型,可以理解为const &
为一种实现方式的权限设定,通过该引用无法修改引用的内容。则如果原变量为非const
类型则可以修改权限使得引用为只读引用,如果原变量为const
,则如果使用可修改引用,则会使得该方式的权限无法实现,出现编译错误。
const 用法
-
定义常量
-
定义常量指针:通过该指针无法修改指向的内容
const int * p1, int * p2;
p1 = p2; // ok
p2 = p1; // error 等于是提高权限,有不安全因素
p2 = (int *) p1; // 当然权限的修改也不是不可以,前提是常指针指向的
- 定义常引用:通过该引用无法修改引用的内容
动态分配内存 new
- 分配
new T
,new T[]
。 - 释放
delete T
,delete [] T
。