C++学习从入门到放弃

常用函数

sizeof

计算某个类型或者对象所占的字节数,包括两种形式

sizeof x
sizeof(short)

getline

getline与cin的区别在于cin会从输入的第一个非空格开始读,直到遇到第一个空格,因此无法读取带有空格的字符串。而getline(cin, str)能够读取str中的所有字符,直到遇到换行符。
getline有个问题在于在getline函数之前如果cin输入了回车也会被getline读取,因此在之前可以先cin.get()或者cin.ignore()读取回车再加getline。

编程方法

强制(显式)类型转换

//继承自C语言
int(x)//类型说明符(表达式)
(int)x//(类型说明符)表达式
//C++形式
static_cast<int>(x)//类型转换操作符<类型说明符>(表达式)
//static_cast, const_cast, dynamic_cast, reinterpret_cast

其中const_cast能够将const变量转化为非const变量

自动推断类型

通过两种关键字:auto与decltype

auto val = val1 + val2
decltype(i)j = 2//j与i类型相同,取值为2

内联(inline)函数

建议编译器将这个函数视为内联函数,实际上还得看编译器自己对函数的处理。
好处是对于简单的函数(不能包含循环,switch,异常接口)能够在编译时对调用处的函数体进行替换,节省了参数传递,控制转移等开销。

inline double calArea(double radius){
	return PI * radius * radius;
}

默认参数值的函数

函数体中带默认参数值的形参必须从右到左

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

在使用函数时使用默认值的顺序从左到右

add(1,10)//结果等于26

判断浮点数是否相等

const double eps=1e-10//设置误差阈值
if(fabs(x-y) < eps);//fabs用于求实数的绝对值,abs用于整数的绝对值

string char*之间转换

string转char*,可以使用string提供的c_str()或者data()函数。其中c_str()函数返回一个以’\0’结尾的字符数组,而data()仅返回字符串内容,而不含有结束符’\0’。
c_str()函数返回一个指向C字符串的指针,该指针指向内存内容和string 相同。注意一定要使用strcpy()函数来操作c_str();c_str()返回的是一个临时指针,不能对其进行操作。

length = str.length();
char *c = new char[length];//用数组也行
strcpy(c, str.c_str());

对象和类

构造函数初始化列表

构造函数通过初始化列表对属性赋值的效率比在构造函数中对属性赋值效率要高

委托构造函数

保证代码实现的一致性

复制构造函数

形参需要是本类对象的引用,又不希望修改复制的函数的属性,因此加const使得形参为常引用。在三种情况下会用到复制构造函数:

  1. 定义一个对象,以另一个对象作为初始值
  2. 函数的形参是类的对象
  3. 函数的返回是类的对象

结构体与类的区别

结构体是特殊的类,继承自C语言,缺省访问权限是public,而类的缺省访问权限的private。
结构体可以用来保存一组数据,而没有太多的功能。

类的默认复制构造函数

类的默认复制构造函数是浅层复制,复制出来的对象和原对象共用一块内存空间,因此在对象的属性改变时会同时改变,我们可以手写构造函数将对象中的每一个属性分别复制。

const修饰函数

const修饰的函数表示这个函数不会修改类的成员,因此具有保护成员或参数不被修改的功能:

MyString operator+(const MyString &str) const;//重载+

数组

初始化

数组有三种初始化方法:

static int a[3] = {1,2,3};
static int a[3] = {1};//部分初始化
static int a[] = {1,2,3};//自动识别数组长度为3,二维数组可以省略0维下标,不能全部省略

非静态初始化的数组如果没有初始化,将会存在垃圾数据。而静态初始化的数组有默认值。
只对数组部分初始化,则剩余部分有默认值。

指针

初始化

指针变量的值是一个地址,数组表示的是首地址,因此可以直接赋值,而且在形式上是完全等价的:

int a[10], *p;
p = a;
//则p[i], a[i], *(p+i), *(a+i)都是等价的

变量类型需要与指针类型一致。
0可以赋值给指针,表示空指针。同理可得,指针可以与0进行比较判断是否是空指针如*p == 0,与其他整数类型变量比较大小则没有意义。
void类型的指针可以赋值任意类型的地址:

void *general;

指向常量的指针与常量指针

const指针指向的常量可以改变,但是不能通过指针来修改变量的值:

const int *p = &a;
p = &b;
*p = 1;//编译错误

本身为常量的指针,指针本身的值不能改变:

int * const p = &a;
p = &b;//编译错误

用指针作函数参数

原因在于把数组作为参数传递给函数效率太低,只传递首地址则效率高得多。另外,使得数据能够双向传递(与引用类似)。
如果不想变量在函数中被修改,可以使用常指针作为形参:

void print(const *p, int N);
int array(N);
print(array, N);//array表示地址,可以不加&

指向函数的指针

将函数作为返回值(回调函数)

int compute(int a, int b, int(*func)(int, int)){
	return func(a, b);
}
int max(int a, int b){}
int sum(int a, int b){}
//...
int res = compute(a, b, &sum);

返回引用

如果想要对象返回的值能够被修改,可以返回对象的引用:

Point *points;
int size;
Point &element(int index){
	return points[index];
}

对象指针

指针如果指向的是一个对象的话,可以通过ptr->getX()来代替(*ptr).getX()
this指针隐含于类的每一个非静态成员函数中,指的是成员函数操作的对象

动态分配

动态数组释放指针

动态数组释放指针要加[],否则只释放数组的第一个元素

Point *ptr = new Point[2];
delete[] ptr;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值