C++基础入门
知识点
-
初始化列表
-
IO输入输出
-
const和指针
-
引用和const
-
inline函数
-
缺省函数
-
函数重载
-
函数模板
-
命名空间namespace
-
new/delete
-
C++11的部分特性
-
string使用
1. 初始化列表{ }
int main(){
//初始化列表
int a = 10;
int b(10);
int c = int(10);
//C++11
int d = {10};
int e{10};
return 0;
}
int main(){
int arr[] = {1, 2, 3, 4, 5};
int br[]{1, 2, 3, 4, 5};
int *p{br};
int *s{nullptr};
return 0;
}
int main(){
int a(10);
int b();
//b()没有初始值,编译器认为函数声明
//Empty parentheses interpreted as a function declaration
int c{};//{}默认初始化0
double d{};
int *p{};
return 0;
}
2. IO输入输出
-
C语言输入scanf,输出printf
-
C++引入**iostream*,using namespace std,使用cin和cout
#include <iostream>
using namespace std;
int main(){
char ch;
int a;
//cin输入流对象
cin >> ch >> a;
cout << "a=" << a << "ch=" << ch << endl;
return 0;
}
int main(){
char str[20];
//cin输入流对象,输入空格结束
cin >> str;
cout << str << endl;
return 0;
}
int main(){
char str[20];
//cin输入流对象
cin.getline(str, 20);
cout << str << endl;
return 0;
}
3. const和指针
-
const在C和C++中的区别
- C语言中以变量为主
int main(){ const int a = 10; int arr[a] = {1, 2, 3, 4, 5};//C语言error int *p = (int *)&a; *p = 100; printf("a = %d *p = %d\n", a, *p); return 0; }
- C++语言中以常量为主
int main(){ const int a = 10; int arr[a] = {1, 2, 3, 4, 5};//编译时a被替换为10,arr[10] int b = 0; int *p = (int *)&a; *p = 100;//a在内存中的值已经被指针p间接修改为100 b = a;//编译时a被替换为10,b = 10; printf("a = %d b = %d *p = %d \n", a, b, *p);//a = 10 b = 10 *p = 100 return 0; }
-
const在*的左边,指针指向的变量不可修改,指针自身的值可以修改
-
const在*的右边,指针指向的变量可以修改,指针自身的值不可修改
int main(){
int a = 5, b = 20;
int *p1 = &a;
const int *p2 = &a;
int * const p3 = &a;
const int * const p4 = &a;
return 0;
}
- const指针的兼容性
int main(){
int a = 5;
const int b = 10;
int *p1 = &a;
const int *p2 = &b;
/*int *p2 = &b;
error:Cannot initialize a variable of type 'int *'
with an rvalue of type 'const int *'
*/
return 0;
}
- const指针之间相互赋值,搞清楚下面两个实例
int main(){
const int a = 10;
const int *p1 = &a;
//int *p2 = p1;//error
const int *p3 = p1;
//int * const p4 = p1;//error
const int * const p5 = p1;
return 0;
}
int main(){
int a = 10, b =20;
int * const p1 = &a;
int *p2 = p1;
const int *p3 = p1;
int * const p4 = p1;
const int * const p5 = p1;
return 0;
}
4. 引用和const
-
定义引用必须初始化
-
没有空引用
-
没有引用的引用
-
const在&左边,常引用;const在&右边,const会被忽略掉
-
常引用可以引用普通变量,也可以引用常变量,也可以引用字面常量(万能引用)
int main(){
int a = 5;
const int b = 10;
const int &rx = a;
const int &ry = b;
const int &rz = 100;
//tmp = 100;
//const int &rz = tmp;
return 0;
}
-
左值和右值(C++11)
-
左值可以取地址
-
右值不可用取地址,如字面常量
int &&r = 10;//右值引用 //int tmp = 10; //int &r = tmp;
-
-
数组元素和数组的引用
int main(){
int arr[5] = {1, 2, 3, 4, 5};
int &a = arr[1];
//int &br[5];//error
int (&cr)[5] = arr;
cout << "sizeof(arr)" << sizeof(arr) << endl;//20
cout << "sizeof(cr)" << sizeof(cr) << endl;//20
return 0;
}
- 引用和指针的别名
int main(){
int a = 10, b = 20;
int *p1 = &a;
int &x = a;
int *p2 = p1;
int *&p3 = p1;//指针的引用
*p3 = 100;
cout << "*p3 = " << *p3 << " " << "*p1 =" << *p1 << endl;
p3 = &b;
cout << "*p3 = " << *p3 << " " << "*p1 =" << *p1 << endl;
*p3 = 200;
cout << "*p3 = " << *p3 << " " << "*p1 =" << *p1 << endl;
return 0;
}
-
指针和引用的区别
-
1、语法规则:指针变量存储某个变量或对象的地址,引用是某个变量或对象的别名
-
2、程序为指针变量分配内存空间,不为引用分配内存空间
-
3、解引用是指针使用时在前面加*,引用可以直接使用
-
4、指针变量的值可以发生改变,存储不同变量或对象的地址,引用在定义时就被初始化,之后无法改变
-
5、指针变量的值可以为空,引用没有空引用
-
6、指针变量作为形参时需要测试他的合法性(判空NULL),引用不需要判空
-
7、指针变量sizeof得到的是指针变量的大小,引用变量sizeof得到的是变量的大小
-
8、理论上指针的级数没有限制,可以有指针的指针,但引用只有一级
-
9、++引用和++指针的效果不一样,对指针变量的操作会使指针变量指向下一个实体的地址,而不是改变所指实体的内容;对应用的操作直接改变引用实体的内容
-
-
指针和引用的相同点:不允许把局部变量以引用或指针的形式返回
- 引用本质是自身为常性的指针
void func(int &x){ int *p1 = &x; x = 100; } int main(){ int a = 120; int &b = a; func(a); func(b); return 0; }
void func(int * const x){ int *p1 = x; *x = 100; } int main(){ int a = 120; int * const b = &a; func(&a); func(b); return 0; }
5. inline函数
-
当程序执行函数调用时,操作系统要建立栈空间,保护现场,传递参数以及控制程序执行的转移等,这些工作需要系统时间和空间的开销
-
inline以空间换时间,省去调用函数的额外开销
-
但当函数体的代码过长或者是递归函数即便加上inline关键字,也不会在调用点以inline展开该函数
-
inline函数声明和定义分离,会产生链接错误,找不到函数名。inline函数被展开,就没有函数地址,链接不到
inline bool IsNum(char ch){
return (ch > '0' && ch < '9') ? true : false;
}
int main(){
char ch;
while (cin>>ch, ch != '\n') {
if(IsNum(ch)){
cout << "是数字" << endl;
break;
}
else{
cout << "不是数字" << endl;
}
}
return 0;
}
6. 缺省函数
-
函数调用时的实参个数应与形参相同,但为了更方便地使用函数,C++允许定义具有缺省参数的函数,这种函数调用时实参个数可以与形参不同
-
缺省函数指在定义函数时为形参指定缺省值(默认值)
-
对于缺省参数,可以给出实参值,也可以不给出参数值。如果给出实参,将实参传递给形参进行调用,如果不给出实参,则按缺省值进行调用
-
在声明时定义缺省参数,不要在函数定义时给缺省参数
void func(int a, int b = 0, int c = 0, int d = 0){
printf("a = %d, b = %d, c = %d, d = %d \n", a, b, c, d);
}
int main(){
func(1, 2, 3, 4);
func(1, 2, 3);
func(1, 2);
func(1);
return 0;
}
- 缺省参数的函数调用,缺省实参并不一定是常量表达式,可以是任意表达式,甚至可以通过函数调用给出。如果缺省实参是任意表达式,则函数每次被调用时该表达式被重新求值,表达式必须有意义
int myRand(){
srand(time(NULL));
int ra = rand() % 100;
return ra;
}
void func(int a, int b = myRand()){
printf("a = %d, b = %d \n", a, b);
}
int main(){
func(10);
return 0;
}