C++学习笔记之C++特性

1.类 class

#include <iostream>
using namespace std;

struct Student{
    int sid;
    int score;
    //C++ 可以在结构体中定义函数
    void hehe(){
        cout << "Hehe..." << endl;
    }
};

/* 
    之所以结构体中可以定义函数,是因为C++并没有区别对待结构体与类
*/

class Student{
public: //如果不加说明,默认是不公开的
    int sid;
    int score;
    void hehe(){
        cout << "Hehe..." << endl;
    }
}


int main(){
    Student zs;
    //C: struct Student zs;
    zs.sid = 100;
    zs.hehe();    //变量调用
    /*
    Student *pz;
    pz = &zs;
    pz->hehe();
    指针调用
    */
    cout << "Hello zs!" << endl;
    return 0;
}

2.bool
C语言
int flag = 5 > 3;
true 1
false 0
C语言真假和整型是可以做转换的
!0 ---> true
0 ---> false

C++
同样整型可以与真假相联系
bool值取true or false

bool flag;
flag = 123;
cout << flag << endl;
output: 1


说明C++还是对整形和布尔型进行了一个转换的
但如果在C语言中将flag定义为int,其输出仍为123

3.auto
令编译器推断变量的类型,但是在定义变量的时候应该让编译器能够判断变量的类型
下面是错误示范:
auto a;
a = 2;
C语言是一种强类型的语言,即每一个变量应该有明确的类型
所以一般不推荐在定义变量的时候使用auto

4.引用 reference
首先看这样一个例子:

int a = 3;


//定义a这个变量,并且拿3给a做初始化
//此处'='是初始化,不是运算符

int a;
a = 3;


//定义a这个变量但是没有初始化,把3赋值给a
//此处'='为赋值,是运算符
再来回忆一下指针:

int *p;


//要看定义了什么,先看中心点,中心点永远是名字,所以为p
//抓住了中心点以后再向两边看谁靠的近,*靠的更近,所以p是一个指针
//再往远看是int,所以指针是指向int的。则p是指向int的指针
//*不是运算符,仅表示一个类型

int a = 3;
p = &a;
*p = 6;


//此处的*为运算符,与上面的*是不一样的
//意义为根据后面指针p的值去找到p所指向的a
接下来看引用:

int b = 6;
int &r = b;
r = 123;
cout << b << endl;
output: 123


//看r的定义:中心点是r,右边是初始化内容,不看;左边&靠得最近
//此处&并不是取地址,而同样是一个类型,表示引用型。再往左边看是int
//所以r是一个int的引用。这个引用是拿b来初始化的,但并不是把b的值赋给r
//是拿b过来初始化,让r变成b的引用,即取一个“外号”,此时r与b等价
引用同指针一样,一般应用在函数中

void fun(int *p){
    *p = 666;
}

int a = 3;
fun(&a);


/*
C语言中分为值传递与地址传递
在一个普通函数中如果采用值传递
比如func(c)
可能会发生很大的空间的复制,比较低效
*/

void fun(int &k){
    k = 2233;
}

int b = 6;
fun(b);


/*
C++用值传递与引用传递
此处fun(b)传引用
如何区分一个函数是传值还是传引用呢?
看函数的参量列表中的参量是否为引用型
C++规定:引用必须在创建时指明它所引的对象
一旦绑定不可再更改
*/

int &r = 123; //error
const int &r = 123;
int &&r = 123;    //右值引用,暂不深入

5.赋值
 

int a, b, c;
a = b = c = 3;


//C++和C语言都可通过

(a = b = c = 3) = 666;
cout << a << " " << b << " " << c << endl;


//C++可通过,但是C语言会报错 
C++  output: 666 3 3
/*
C++跟C语言赋值有一点不一样
C语言:a = 3,是把3赋值给a,然后整个赋值语句的值为3
C++: a = 3,把3赋值给a,然后整个赋值语句变成左边a的引用
(a = 3) = 666;
在C语言中即为(3) = 666;
C++: (a) = 666;
a = b = c = 3;
C++中逐步赋值为:
a = b = c;
a = b;
a;
*/
int a = 3;
C++给出了一种不用等号初始化的方法:

int a {3};
int array[5] {1, 2, 3, 4, 5};


同样可以用来初始化结构体变量,类的对象

6.动态内存分配
C:

int *p;
p = (int*)malloc(sizeof(int)*10);


/*
malloc()返回值为void*,被强制转换为(int*)
malloc()不关心开辟的内存空间是用来放什么的
*/
C++:

int *p;
p = new int;


/*
new关键字:使C++申请一个空间用来放int,并且把
用于存放int的空间的地址返回给p
new后面跟的不像malloc()一样是空间的大小,而是
一个类型
p = new int[10];
int[10]是一个类型,是由10个int组成的数组的类型
*/
空间申请好之后,需要记得释放空间
C:

free(p);


C++:

delete p;


/*
简单类型的数组可以直接用delete p,但如果是自己定义的结构体/类
的数组,比如p = new Student[10],应为delete [] p,如果写为delete p
这些元素的析构会出问题
所以建议在释放数组的时候,一律使用delete []
*/

7.新的for语句(C++11之后)
 

for(int x : array)
    cout << x << ' ';


//冒号右边是容器,可以是数组,也可以是vector等各种容器

int array[5] = {1, 2, 3, 4, 5};
for(int x : array){
    x += 100;
    cout << x << ' ';
}
cout << endl;
for(int i = 0; i < 5; i++)
    cout << array[i] << ' ';
cout << endl;

output:
101 102 103 104 105
1 2 3 4 5


/*
int x : array只是把array中元素的值给了x,而本身数组中的
1, 2, 3, 4, 5是没有改变的
如果想要改变array数组中元素的值,可以写为int &x : array
此时x是数组中元素的引用(不是元素值的引用)
如果容器中元素的类型比较复杂,可以写为auto x : array
*/

8.重载 overload
 

int add(int x, int y){
    return x + y;
}

int add(int x, int y, int z){
    return x + y + z;
}


重载:函数名一样,但调用时参量不同
因为参量不同,所以是不同的函数
而参量是否相同,是看函数原型是否相同

int add(int x, int y){
    return x + y;
}

int add(int y, int x){
    return x + y;
}


两个函数的函数原型都是:
int add(int, int);
所以第二个函数不是合法的重载,会被认为是函数的重定义
只有返回类型不一样,也是不能作为重载的,因为编译器
不好判断调用哪个函数

int add(int x, int y){
    return x + y;
}

double add(double x, double y){
    return x + y;
}

int main(){
    cout << add(3, 5.5) << endl;
    cout << add(3.5, 1) << endl;
    return 0;
}


提示:Call to 'add' is ambiguous
当向两个函数都可以进行转化的时候
会提示函数具有二义性

struct Vector{
    int x;
    int y;
};

Vector operator + (const Vector &a, const Vector &b){
    Vector temp;
    temp.x = a.x + b.x;
    temp.y = a.y + b.y;
    return temp;
}

/*
为了尽量避免传结构体,所以用到了引用
const是为了避免a和b的改动
*/

int main(){
    Vector a, b;
    a.x = 3;
    a.y = 4;
    b.x = 1;
    b.y = 2;
    /*
    C:
    a.x + b.x;
    a.y + b.y;
    C++:
    a + b;    // +(Vector, Vector);
    +:双目运算符,可以把'+'看作一种操作
    而a, b看作是操作所需要的参数
    */
    Vector sum;
    sum = a + b;
    cout << sum.x << ' ' << sum.y << endl;
    return 0;
}

9.lambda表达式
 

auto f = [](int a, int b) -> int{return a + b;};
cout << f(3, 5) << endl;
output: 8


f是指向函数的一个指针,[]中写要捕获的东西,()写函数的参数
参量的类型可以写成auto,->后面{}前面写函数返回的类型
可以写成auto,{}里面写函数
当我们想用一个函数,但是又不想去写定义的时候,可以用lambda表达式

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值