关于cout的几点提醒
1.注意与cin的>>区分,cout是<<
2.endl用于换行
3.cout是从后向前执行,<<操作符的递归调用,先递归执行的是最后一个,参数压栈的顺序是从右向左,输出则是从左到右。
例:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int a = 1, b = a;
cout << a << "\t" << a++ << endl;
cout << b + ++b << endl;
char str[] = "Hello World ";
char* str2 = str;
cout << "*str2:" << *str2 << "\t" << "*str2++ :" << *str2++ << endl;
cout << "*str2 " << *str2 << endl;
cout << "str :" << str << endl;
return 0;
}
输出:
2 1
4
*str2:e *str2++ :H
*str2 e
str :Hello World
声明与定义 Declaration & Definition
1.声明:一条负责为程序引入一个新的名字的语句,并指定类型。
2.定义:描述语句的具体实现方法
3.在头文件中只做声明,不要定义,在cpp文件中进行定义
4.若在头文件中写出了int a;这样的语句,而在cpp文件中再次int a;则是错误的
应在头文件中int a;前加extern关键字,表示现在有一个int型变量叫做a
cpp中的int a;表示告诉编译器这个叫a的int型变量在这里
5.speaking of extern,extern const int a表示有个整型变量a,在此处为不可修改
6.C++支持在定义变量的同时使用,如
for( int i = 0 ; i < 10 ; i++ ){
//具体操作
}
其他
1.头文件:一般无需加.h后缀,调用C的库只需在前面加c,后面也不需要加.h后缀
例如:#include <cstdio>
万能头文件:#include <bits/stdc++.h>
该头文件包含了C++所有的库,但有些编译器会提示无该头文件(如Win端的Visual Studio和Mac端的XCdoe)
2.类型:定义一组可能的值,以及一组对象上的操作。
3.对象:存放某类型值的内存空间。
4.值:一组二进制位,具体的含义由其类型决定。
5.更加通用的初始化方法:{ }
🌰:int i {88} / int i = {88} //等号在此时可省
6.两个“不变”:
(1)const:主要用于说明函数接口。
(2)constexpr:主要用于说明常量,作用是允许将数据置于只读内存中以提升性能。
7.空指针表达方式:nullptr,而NULL在C++作为一个宏其值为0
8.范围for循环(预先定义数组 int v[] = {1,2,3,4,5} )
(1)for ( auto x: v) cout<<x;
输出:12345
(2)for ( auto & x : v ) cout<<x;
输出:12345
二者区别是:第二种用于不希望将v的值拷贝到变量x中,而只想令x指向一个元素时
9.在C++中,这两个函数仍然可以使用,但是C++又新增了两个关键字,new 和 delete:new 用来动态分配内存,delete 用来释放内存。
用 new 和 delete 分配内存更加简单:
int *p = new int; //分配1个int型的内存空间delete p; //释放内存
new 操作符会根据后面的数据类型来推断所需空间的大小。
如果希望分配一组连续的数据,可以使用 new[]:
int *p = new int[10]; //分配10个int型的内存空间delete[] p;
用 new[] 分配的内存需要用 delete[] 释放,它们是一一对应的。
和 malloc() 一样,new 也是在堆区分配内存,必须手动释放,否则只能等到程序运行结束由操作系统回收。为了避免内存泄露,通常 new 和 delete、new[] 和 delete[] 操作符应该成对出现,并且不要和C语言中 malloc()、free() 一起混用。
在C++中,建议使用 new 和 delete 来管理内存,它们可以使用C++的一些新特性,最明显的是可以自动调用构造函数和析构函数,后续我们将会讲解。
10.在C++中定义或声明一个函数时,有时会在形参中给它赋一个初始值作为不传参数时候的缺省值,
例如:
int FUN ( int a = 10 ) ;
代表没有传参调用的时候,自动给a赋一个10的初始值。
且赋初始值遵循从右至左的顺序。
例如:
int fun(int a ,int b = 10);
int fun(int a = 20,int b);
可以,但若反转这是错误的。
11. 传引用和传常量引用
函数传值传递的是拷贝,在传递占用空间小的值时简单,直接,高效,但若较大,则代价高昂,此时可采用传(常量)引用的方式。
例如,void print(vector<int>& v); //引用参数需要指向一个变量,而非常量
若不想让函数内部意外修改参数的值,则上述声明可写作:
void print(const vector<int>& v);
尽量少的使用传引用的方式,若使用,认为函数必定修改了这个值。
12.引用的语法机制
🌰:
int i=7,&r=i;
r=9;
i=10;
cout << r <<' '<< i << endl;
输出:10 10
也就是说,任何对r的使用实际都是对i的使用,反之亦然。
13.constexpr函数要求必须非常简单,只可包含一条return语句(C++11)或简单的循环语句(C++14)
14.变量的销毁顺序与创建顺序相反(后进先出原则)
15.为解决合作开发时的命名冲突的问题,引入命名空间的概念。
16.尽量避免在表示std以外的地方使用using语句
指针回顾
1.const常量与指针
(1)const修饰指针——常量指针
int a=10;
const int *p = &a;
特点:指针的指向可以修改,但是指针指向的值不可以修改
*p = 20; //错误,指针指向的值不可以修改
p=&b; //指针指向可以改
//可以理解为const离&a太远,不能限制指针的指向
(2)const修饰常量——指针常量
int a =10;
int * const p = &a;
特点:指针的指向不可以改,指针指向的值可以改
//可以理解为const在*后面,不能限制其解引用,也就不能限制其修改值
*p = 20; //正确,指向的值可以改
p=&b; //错误,指针指向不可改
(3)const既修饰指针,又修饰常量
int a = 10;
const int * const p =&a;
特点:指针的指向和指针指向的值都不可以改
*p = 20; //错误,指针指向的值不可修改
p = &b; //错误,指针的指向不可修改
2.数组与指针
(1)int *p[3];
指针数组:本质为存储3个指针的数组
(2)int *(p[3]);
指针数组
(3)int (*p)[3];
数组指针:本质为存储一个含有3个元素的数组的指针
3.访问结构体/类的方法
访问值用”.”运算符
访问指针用”->”运算符