学习C++的第二天
错误分类
一般错误分为以下几种:
- Syntax Error(语法错误)
违反了编程语言的语句形式或使用规则,一般由编译器检查指出
例如:遗漏标点符号、错用关键字、分支/循环语句结构缺失
亦称为:编译错误
- Runtime Error(运行时错误)
程序运行时,遇到一个无法执行的操作,一般编译器无法检查出来
例如:执行整数除以0的操作、打开不存在的文件、内存不足、磁盘满
- Logic Error(逻辑错误)
程序的运行结果与预期的正确结果不一致,编译器无法检查指出。
关于namespace的一个小问题
#include<iostream>
//using namespace std;
using std::cout;
using std::endl;
int main(){ //入口
return 0;
}
Namespace mynamespace{ //自定义的命名空间
int main(){//namespace隔离作用标识符的范围
cout<<"Hello World!"<<endl;
std::cin.get();
return 0;
}
}
//注意区分两个main()函数
输入输出
分类(根据源目分类) |
---|
Standard I/O(标准IO) |
File I/O(文件IO) |
String I/O(字符串IO) |
Network I/O(网络IO) |
C++输入输出:
- C++使用一种叫做“流”的概念对屏幕、键盘或者文件进行输入输出操作
Stream(流) | Description(描述) |
---|---|
cin | standard input stream 标准输入流 |
cout | standard output stream 标准输出流 |
cerr | standard error(output) stream |
clog | standard logging(output) stream |
Stream(流) | Operators(操作符) | Functions(函数) |
---|---|---|
cin | >>含义:extraction operator(流提取运算符) | cin.get()从流中读取并取走一个字符 cin.getline()从流中读取字符,直至行尾或指定的分隔符 cin.ignore()从流中读取并舍弃指定数量的字符 |
cout | <<含义:insertion operator(流插入运算符) | cout.put()将字符写到流中(无格式) cout.flush()将流中缓存内容全部输出 |
Reference(引用)
引用就是变量的另一个名字(别名、外号)
通过引用所做的读写操作实际上是作用于原变量上
- 创建引用变量
int x;
int& rx = x;
or
int x ,&rx = x;
C中&表示为取地址符,C++中当&在声明类型一行时则意为引用
- 区分引用和取地址
意为引用时,必须在声明时就有&例如:int& rx = x;
意为取地址符时,取地址符一般是会和指针绑定出现。
特别说明:引用和取地址还是有较大不同的,引用只是变量的别名,不会占用额外的内存,而取地址用的指针则会占用新内存来保存目标的地址信息。
今日编程规范
C++指针与引用符号应靠近其类型而非名字
例如:
Float* x; //not : float *x;
Int& y=x; //not : int &y=x;
函数参数:引用传递
引用可做函数参数,但调用时只需传普通变量即可
在被调函数中改变引用变量的值,则改变的是实参的值
例如:
引用类型传参
#include<iostream>
int test(int& a){
a = a + 1;
}
int main(){
int a = 0;
//int a{0}; C++11初始化方式
test(a); // a = 1
//std::cout<<a<<std::endl;
return 0;
}
指针类型传参
#include<iostream>
int test(int* a){
*a = *a + 1;
//*a++; 这种不行 DEVC++不会报错,但是结果不对
// VS给了提示:运算顺序可能不正确,已忽略或取消引用
// 根据提示,实际运算顺序会是*(a++)所以错误
//(*a)++ 结果正确!给VS比心!
}
int main(){
int a = 0;
//int a{0}; C++11初始化方式
test(&a); // a = 1
//std::cout<<a<<std::endl;
return 0;
}
特别的:引用一旦绑定,不可更改
例如:
#include<iostream>
Int main(){
const char* a = ”Hello”;
const char* b = “World”;
const char*& c = a; //c绑定a
c = b; //此时会直接将b所指地址的值赋值给c/a
//std::cout<<a<<std::endl;//World
//std::cout<<b<<std::endl;//World
return 0;
}
空指针
在C++03中空指针用“0”表示,既是一个常量整数,也是一个常量空指针,存在二义性
C中,空指针用(void *)0来表示
C++11引入保留字“nullptr”作为空指针
void codeExample(){
auto x{10}; //auto 新增的类型,用于自动推断后面变量x的类型,相当于 int x = 10;
int* p = nullptr;//旧初始化方式
int* q{nullptr};//新初始化方式
q = &x;
}
动态内存管理:分配/释放
C++中通过运算符new申请动态内存
- new <类型名> (初值); //申请一个变量的空间
- new <类型名> [常量表达式]; //申请数组
申请成功返回地址,失败抛出异常或返回空指针(nullptr)。
动态内存使用完毕后,要用delete运算符来释放。
- delete <指针名>; //删除一个变量/对象
- Delete []<指针名>; //删除数组空间
char* s = new char(‘a’);//初始化为a
delete s;
int* p = new int[10];
delete []p;
用new和不用new的区别
- 未使用new,使用的是栈中的内存,效率高,但资源很有限,函数执行完毕后,会销毁
- 使用new,使用的是堆中的内存,几乎可以申请任意多,但必须由程序员自己delete释放掉
请注意以下代码
#include<iostream>
int main() {
const char* p = "Hello";
char* q = new char('a');
std::cout << p << std::endl;
std::cout << *q << std::endl;
delete q;
return 0;
}