day 1.c++语法

字符数组初始化字符串会默认添加\0,要注意数组下标大小
例如 char a[]="123",要开到4;
C数组 int a[]不能拷贝和赋值;如a2=a,int a2[]=a //错误
int *a[10] //a是指向10个int *
int (*a)[10] //指向10个int型的数组指针
int a[10]={1,2,3...};
a[2]=*(a+2)=3;
int *p=&a[2];
p[2]=*(p+2)=5;//a[4];
数组int a[]内置下标可以有负值,标准库类型sting,vector都是unsigned
内置数组初始化vector
int a[10]={0};
vector<int>ans(begin(a),end(a));
花括号初始化数组
int a[5]={0,1..};
int a[2][3]={{0,0,0},{0,0,0,}};也可以写成int a[2][3]={0,0,0,0...};
缓冲区溢出:越界索引访问容器内容
常量可以引用非常量,非常量不能转常量;
int i;
const int &j=i;
const int *p=&i
int &r=j//非法,不能从常转非常
只要不包括底层const都能用static_cast
int j;
double d=static_cast<double> (j);
const int*p1 = &a; //p1是底层const,通过p1不能改变p1指向的数据a。p1本身可变。
int const*p2 = &a; //同上,p2是底层const,通过p2不能改变p2指向的数据a。p2本身可变。
顶层const表示指针本身是一个常量
底层const表示指针指向的对象是一个常量

常量转非常量用const_cast 只能在同类型去const 不能转换类型
const int *a;
int *p=const_cast<int*>(a);
goto跳转到同一函数内的其他地方;

异常部分知识点
try
{
...
if(失败)
{
抛出异常让catch捕获;
}
}
catch(A)
{
捕获异常...
}
catch(B)
{
捕获异常...
}

函数
定义
int fac(int n)
{
return 0;
}
调用可以fac(3.14)会自动进行类型转换;

分离式编译 把函数声明放一个文件;定义放另一个文件


重载函数
函数名相同,形参列表不同的成为函数重载;
int fac(int p);
int fac(string p);
int fac(int a,int b);
注意main不能重载
应用于数据库
record lookup(const name&);
record lookup(const phone&);

int fac(int);
int fac(const int)是等价的,顶层const会被忽略;所以是声明两次;

int fac(int *);
int fac(int *const);顶层const 可以忽略;
但是
int fac(int *)
int fac(const int*)确是重载,两个新函数,因为后面是底层const

重载和作用域

在外面重载的函数,在里面作用域会被屏蔽;即调用时是调用内部的

int fac(double);

void test()
{

int fac(int);
fac(3.14);//会被调用成fac(3),屏蔽外面的
简单总结就是,都有同名函数,会屏蔽外部的重载,没有才会调用外部重载;
}

内联函数 可以避免函数调用的开销;
如coutt<<strcmp(s1,s2)<<endl;
等价cout<<s1<s2?s1:s2<<endl;

constexpr函数的返回值和形参都得是字面常量

内联函数和constexpr函数可以多次定义,但是定义必须一致

调用重载函数时,如果有默认形参,那么实参可以不用考虑默认形参,可能会少于定义的形参数

重载函数匹配优先精确匹配,实在不行系统会强制转换,如果可以的话

返回指向函数的指针
using F=int(int *,int)//F是函数
using pf=int (*)(int*,int)//pf是指向函数的指针,形参要和函数一致

函数的返回值不能是函数

decltype
①当使用decltype(var)的形式时,decltype会直接返回变量的类型(包括顶层const和引用),不会返回变量作为表达式的类型。

const int ci=0;
decltype(ci) x=0;

decltype(expr)的结果根据expr的结果不同而不同:expr返回左值,得到该类型的左值引用;expr返回右值,得到该类型。

int i = 42, *p = &i, &r = i;

// r + 0是一个表达式
// 算术表达式返回右值
// b是一个int类型
decltype(r + 0) b;

// c是一个int &
decltype(*p) c = i;
因此,decltype(expr)的结果根据expr的结果不同而不同:expr返回左值,得到该类型的左值引用;expr返回右值,得到该类型。

我们可以使用decltype获得函数add_to的类型:
decltype(add_to) *pf=add_to//add_to类型的函数指针;

首先,我要告诉你static与extern是一对“水火不容”的家伙,也就是说extern和static不能同时修饰一个变量;其次,static修饰的全局变量声明与定义同时进行,也就是说当你在头文件中使用static声明了全局变量后,它也同时被定义了;最后,static修饰全局变量的作用域只能是本身的编译单元,也就是说它的“全局”只对本编译单元有效,其他编译单元则看不到它,如:


extern 是声明全局的变量的意思。

例如在一个工程中有两个cpp,一个是test.cpp一个是main.cpp 。

我们在test.cpp中定义了一个int num;但是我们在main.cpp中想要调用。这时候我们就需要使用到extern

在main.cpp中进行声明extern int num;这样我们就可以调用到test.cpp中的num。

注意:

在main.cpp中,我们只是进行了声明,而真正定义是在test.cpp中。那就意味着我们不能这样写:extern int num = 1;这样就变成了定义

 

上一篇:如何使用C语言来计算n的阶乘?(递归?)


下一篇:组合计数 ---- 2020 icpc 上海 The Journey of Geor Autumn(思维划分问题计数+预处理优化)