博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【C++】入门基础概念
阅读量:4185 次
发布时间:2019-05-26

本文共 3927 字,大约阅读时间需要 13 分钟。

如何选择类型?

1.当明确不可能为负值时,选用无符号类型

2.一般选用int,如果超过了int,就选择long long
3.在算术表达式中不要选用char 或 bool 类型,只有在存放字符或者布尔值时才引用
4.执行浮点数时用double,因为float通常精度不够,而单精度和双精度的计算代价相差无几。

含有无符号类型的表达式

把负数转换成无符号数类似于直接给无符号数赋一个负值,结果等于这个负数加上无符号数的模。

如果表达式里既有无符号类型又有带符号类型,当带符号类型取值为负时会出现异常结果,这是因为带符号数会自动转换成无符号数。
比如 

a*b = -1;而   unsigned a=b=-1;    a*b = 4294967295;

类型转换

对象的类型定义了对象能包含的数据和能参与的运算

类型表示的范围决定了转换的过程:

1.浮点数赋给整数:仅保留小数点之前的内容
2.整数赋给浮点数:小数点后为0,若整数所占空间超过浮点类型的容量,可能损失精度
3.赋给无符号类型一个超出它表示范围的值时:结果是初始值对无符号类型表示数值总数取模后的余数
4.赋给带符号类型一个超出它范围的值时:结果是未定义的

新的类型转换符

1.const_cast   

用来移除对象的常量性

一般用于指针或者引用,不用于一般对象
使用const_cast去除const限定的目的不是为了修改它的内容,通常是为了函数能够接受这个实际参数

const int val = 100;    //int n = const_cast
(val);//error //int *p = &val; //error :必须是const int *p = const_cast
(&val); *p = 200; cout << p << endl; //p确实指向了val,但不能改变val的值,有一个临时对象,操作的是临时对象的空间,常量是不能被更改的 cout << val << endl; const int val2 = 200; //int &q = val2; int& q = const_cast
(val);

2.static_cast

附:隐式转换  编译器可以自动完成的(一般来说是安全的)    

  显式转换(强制类型转换)
(1).编译器隐式执行的任何类型转换都可以有static_cast完成
(2).当较大的算术类型赋值给较小的类型时,可以用static_cast进行强制转换
(3).可以将void*指针转换为某一类型的指针
(4).可以将基类指针指向派生类指针
(5).无法将const转换为nonconst,只能用const_cast

int n = static_cast
(3.14); cout << n << endl; //3 void *p = &n; int *p1 = static_cast
(p); cout << *p1 << endl; //3

3.reinterpret_cast

通常为操作数的位模式提供较低层的重新解释,也就是说将数据以二进制存在形式的重新解释。

新式类型转换总结

这三种都可以用旧式类型转换替代

还有dynamic_cast<T>(expr):作为一个向下的类型安全转换,来进行运行时类型识别。以后再讨论)

类型转换规则

(1).尽可能避免使用强制转换

(2).如果无法避免,推荐使用新式类型转换

引用

1.一般在初始化对象时,初始值会被拷贝到新建的对象中,然而定义引用时,程序把引用和它的初始值绑定在一起,共享空间,而不是被初始值拷贝给引用

2.引用并非对象,它只是为一个已经存在的对象所起的另外一个名字,所以不能定义引用的引用
3.对引用的任何操作都是在与之绑定的对象上进行的
4.引用类型的初始值必须是一个对象,而且引用的类型要和与之绑定的对象类型严格匹配
5.引用没有独立的空间
6.引用一经初始化,不能重新指向其他变量

引用的用法

1.函数的参数(按引用传递)

2.引用做为返回值:可以将函数返回值放在赋值运算符的左边
注意:不能返回对局部变量的引用:局部变量在函数返回时被销毁了

/*对局部变量的引用的返回*/int &add(int a,int b){    int sum;    sum = a + b;    return sum;}/*对全局变量的引用返回*/int array[] = {
0,1,2,3,4}; int &index(int i){ return array[i];}void swap(int &a,int &b){ int temp; temp = a; a = b; b = temp;}int main(){ int a = 10,b = 20; swap(a,b); cout << "a=" << a << " "; cout << "b=" << b << endl; /*引用做为函数的返回值,在函数返回的时候初始化*/ index(3) = 100; //array(3)被初始化为a[3] cout << array[3] <

指针与引用的区别

1.指针本身就是一个对象,允许对指针赋值和拷贝;引用只是原变量的一个别名

2.指针无须在定义时赋初值(最好初始化),还可以为空,引用必须初始化
3.一旦定义了引用,就无法再绑定到另外的对象,之后每次访问这个引用都是访问最初的那个对象;给指针赋值就是存放一个新的地址,从而指向一个新的对象
4.指针可以有多级;引用不是一个对象,不能定义引用的引用
5.引用访问一个变量是直接访问,而指针是间接访问
注:面对一条复杂的指针或引用的声明语句时,从右往左阅读有助于弄清楚它的真是含义,离变量名名最近的符号对变量的类型有最直接的影响。
注意:尽可能使用引用,不得已时使用指针。

new+delete

new:

1.分配内存空间 -- malloc
2.调用析构函数
delete:
1.调用析构函数
2.释放内存

//int *p1 = new int;  //分配一个int 空间 4字节   int *p1 = new int(33);    //圆括号()表示分配一个空间并初始化   cout << *p1 << endl;      //p1 = 33   int *p2 = new int[10];  //[]分配连续的10个整数空间 40字节

重载

相同的作用域,如果两个函数名称相同,而参数不同,我们把它们称为重载。

函数重载的不同形式:参数不同
形参数量不同;
形参类型不同;
形参顺序不同;
形参数量和类型都不同。注意:如果返回类型不同而其余部分相同则是非法的重载!
1.C++为了支持重载,在编译时进行了名字改编,即函数名在编译时并不以原函数名出现
extern “C” void fun(int a) //加上extern “C”表示不进行名字改编,就和C语言一样
2.实现C和C++混合编程:

#indef _cpluscplusextern "C"{#endif……#ifdef _cpluscplus}#endif

带默认形参值的函数

1.函数没有声明时,在函数定义时指定形参的默认值

2.如果未给函数指定实参,则用默认参数值
3.函数既有定义又有声明时,声明时指定后,定义后就不能再指定默认值
4.默认值定义必须遵守从右到左的顺序,如果某个形参没有默认值,则它左边的形参也不能有默认值
重载的函数中如果形参带有默认值时,可能会产生二义性,即可以调用不止一个函数,此时编译器会报错。

内联函数

(一)why?

当程序执行函数调用时,系统要建立栈空间,保护现场,传递参数以及控制程序执行的转移等等,这些工作需要系统时间和空间的开销。有些情况下,函数本身功能简单,代码很短,但使用频率却很高,程序频繁调用函数花费的时间很多,从而使得程序执行效率降低。所以,为了协调好效率和可读性之间的矛盾,定义内联函数。

一般函数进行调用时,要将程序执行权转到被调用函数中,然后再返回到调用它的函数中;而内联函数在调用时,是将调用表达式用内联函数体来替换。
内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。编译时,类似宏替换。
 

(二)内联函数和带参数宏的区别

1.内联函数会进行类型检查,而宏调用只是实参简单地替换形参

2.内联函数是在编译的时候、在调用的地方将代码展开,宏是在预处理时进行替换的
注:C++高层次编程,推荐用 const、enum 来代替宏常量 inline代替带参数的宏

(三)内联函数的注意事项

1.内联函数必须是和函数体声明在一起,只能先定义后使用,才有效。

2.如果内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。
3.递归函数不能定义为内联函数。
4.内联函数一般适合于不存在while和switch等复杂的结构且只有1~5条语句的小函数上,否则编译系统将该函数视为普通函数。
5.对内联函数不能进行异常的接口声明。

(四)用法

inline int fun(int a,int b)

wan an

转载地址:http://eouoi.baihongyu.com/

你可能感兴趣的文章
JAVA编写HTTP代码并发布在网上
查看>>
JDBC连接数据库的原理和步骤
查看>>
开发微信公众平台的基本功能
查看>>
JSP内置对象的学习
查看>>
用java写文件输入输出流,实现复制粘贴的方法
查看>>
学习JSP的方法步骤(参考)
查看>>
JSP中常见TOMCAT错误代码原因
查看>>
MyEclipse中WEB项目加载mysql驱动方法
查看>>
常见编写JAVA报错总结
查看>>
org.gjt.mm.mysql.Driver和com.mysql.jdbc.Driver的区别
查看>>
UTF-8和GBK有什么区别
查看>>
增加MyEclipse分配内存的方法
查看>>
头痛与早餐
查看>>
[转]在ASP.NET 2.0中操作数据::创建一个数据访问层
查看>>
Linux命令之chmod详解
查看>>
【java小程序实战】小程序注销功能实现
查看>>
leetcode Unique Paths II
查看>>
几个大数据的问题
查看>>
CareerCup Pots of gold game:看谁拿的钱多
查看>>
CarreerCup Sort Height
查看>>