基本语法
- “#include”预处理指令 引入某个文件的作用
“#include”引入自己创建的要加入双引号 并且加上 .h
2. 以下三种方式功能一样
using namespace std;
using std::cout;
std::cout <<"xxx";
cout代表输出到控制台一段信息
endl代表行的结束 也就是换行的意思
3. 语法区别
unsigned 无符号的 不能存在负号
long long 类型 更大的整数值 long double 类型 更大的浮点数数值
E表示法 3.4e9和3.4e+9一样 代表 3.4 x 1000000000
4. 特殊关键字
auto 可以自动判断类型 比如 auto a = 'a';
5. 类型
字符串 其实是用 char[]代替的
\0表示字符结束 或者 用 char a[] = “baidu.com” ;表示,这个时候字符串长度是9 字符数组长度是10,因为还有一个默认的\0
如果一段字符串太长,可以分开多个双引号间隔使用,c++自动拼接,比如:"baidu" ".com"
c++也有string类型可以使用,需要前面引入下string类型 就c#一样可以使用了
6. 方法
getline(cin,用户输入) 可以避免cin的空格错误,自动将接收到的数据换行并且忽略空格
strlen() 表示取得字符串长度
strcmp(数组1,数组2) 比较两个数组内容是否相等,0代表相等,1代表不等
islower(字符) 表示一个字母是否是小写,0代表false,其他的为true
tolower(字符) 将一个字母字符转换为小写,但是会自动转换为数字,需要使用 putchar()字符转换下
srand((int)time(0)); 定义下随机数,传递当前时间,rand() 随机生成一个数字
7. 指针类型和引用类型
指针可以完成对内存地址的操作
指针的定义
int* p = &5; 定义一个int类型的指针
或者 void* p; 可以接收任意类型的指针
解指针 *p 或者 *(&5)
空指针定义
1. int* p1 = 0;
2. int* p2 = NULL;
3. int* p3 = nullptr; 这种方式可以转换任意类型的指针类型,推荐
4. int* p4 = new int; *p4 = 100; delete *p4; 注意这种指针一定要记得释放内存,否则会永久占用内存地址
指针和数组关系
数组其实就是一个指针,所以说比较两个数组是否相等,即便里面的值是一样的,结果也是0,就是false的意思,因为比较的其实是指针。所以使用 strcmp(数组1,数组2) 去比较两个数组的内容是否相等,0代表相等,非0为不相等
引用类型的定义
int& r = 100;
引用类型的内存地址是不能修改的。对引用类型赋值的话,相当于修改原变量。引用类型声明后,永远指向初始化的那个地址。
使用途径
在方法中通过引用类型向外传递多个返回值,因为引用类型修改是修改原变量的
8. 数组
-
创建一维数组
直接创建数组 int score[4]{1,2,3}; 该方式数组之间不能相互赋值,第四个索引的值为0
指针创建数组 int* p = new int[]; p[0] = 50;
模板类array array<int,9> a1 = { 1,1,2,3,4,5,6,8}; 该方式数组之间可以相互赋值 -
创建二位数组
直接创建数组
int score[2][3] = {
{1,2,3},
{3,5,1}
};
cout << score[1][1] << endl; //结果为5
- 遍历二维数组 - 使用循环嵌套
9. 循环
for循环和c#一致
while循环和c#一致
do while循环和c#一致
快速遍历方式,直接得到每个索引代表的数值
int scores[] = {1,2,3,4,5}; for(int temp : scores) { cont << temp << endl; }
但是无法这样赋值,赋值的话要采用下面的方式
int scores[] = {1,2,3,4,5}; for(int& temp : scores) { temp = temp * 2; }
&表示引用,代表修改的是temp对应的引用
10.类型别名
-
使用宏定义实现,宏的名字放在前面,后面是类型
没有太多意义,就是使用END 代替后面的内容#define END return 0; #define UString string
- 使用 typedef 定义类型别名,类型放在前面,后面是类的别名
typedef string UString;
-
区别
“#define” 可以给任意类型定义别名
typedef 只能给类型定义别名
“#define” 定义类似string这种类型是不需要 分号结尾的
typedef 定义类似string这种类型是需要 分号结尾,否则报错
11.运算符
-
i++ 和 ++i 是有区别
如果单独使用是没有区别的,但是放在表达式就不一样了
i++在表达式中会先使用i,然后再进行i++计算
++i在表达式中会先计算++i,然后再使用i
12.结构体
结构体可以将不同类型组合在一起形成新的类型,这个类型是对数据的整合,让代码更简洁
struct 结构体名字
{
成员类型 成员名
成员类型 成员名
}
13.局部静态对象
static int count = 0
局部静态对象和局部对象的相同点
- 两个都是局部变量,在外部无法使用
局部静态对象和局部对象的区别
- 局部对象是自动对象,是每次运行到方法中初始化代码都会创建一次,方法结束会被销毁掉
- 局部静态对象不是自动对象,只会创建一次,程序销毁才会被释放掉。static关键字来修饰局部变量
自动对象
- 只存在于块执行期间的对象成为自动对象
- 普通的局部对象 形参 都是自动对象
14.const形参和实参
一般来讲,定了const的值是常量,不可以修改
- 顶层const:表示任意的对象是常量
- 底层const:与指针和引用等复合类型有关
- 对指针而言,顶层const表示指针本事是个常亮,而底层const表示指针所指的对象是一个常量
int i = 22;
const int ci = 20; //顶层const,不能修改ci的值
const int* p1 = &c1; //底层const,允许修改p1的值,但是不能通过*p1修改c1的值
int* const p2 = &i; //顶层const,不能修改p2的值,但是允许通过*p2修改i的值
用实参初始化形参时,会忽略掉顶层const,也就是说,当形参有顶层const时,传给它常亮对象或者非常量对象都是可以的
15.内联函数
- 内联函数 是 C++为提高程序运行速度所做的一项改进
- 内联函数的编译代码与其他程序代码"内联"起来了,也就是说,编译器将使用相应的函数代码替代函数调用
- 对于内涵代码,程序无需跳到另一个位置处执行代码,再跳回来。因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存
- 内联函数的使用方法:在函数声明或函数定义前加上关键字 inline
- 通常的做法是省略原型,将这个定义放在本应提供原型的地方
- 注意:内联函数不能递归
inline int sum(int a, int b){return a+b;}
int main()
{
int res = sum(1,2);
return 0;
}
16. constexpr函数
- constexpr函数 是指能用于常量表达式的函数,即可以在编译时计算其返回值的函数
- 常量表达式是指值不会改变并且在编译过程就能得到计算结果的表达式
constexpr函数定义 - 函数中只能有一个 return 语句
- 返回值必须是字面值类型(算术类型、引用、指针属于字面值类型)
- 参数必须是字面值类型(自定义类、IO库、string类型不属于字面值类型)
- constexpr 函数被隐式地指定为内联函数
- 允许递归
constexpr int fact(int n)
{
return n==1 ? 1 : n * fact( n - 1);
}
constexpr int num = 5;