【C++】入门基础概念

如何选择类型?

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<int>(val);//error

    //int *p = &val; //error :必须是const
    int *p = const_cast<int *>(&val);
    *p = 200;

    cout << p << endl; 
    //p确实指向了val,但不能改变val的值,有一个临时对象,操作的是临时对象的空间,常量是不能被更改的

    cout << val << endl;

    const int val2 = 200;
    //int &q = val2;
    int& q = const_cast<int&>(val);
2.static_cast

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

    int n = static_cast<int>(3.14);
    cout << n << endl;  //3

    void *p = &n;
    int *p1 = static_cast<int*>(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] <<endl;

    int s = add(2,3);
    int &n = add(4,5);
    cout << "2+3 = " << s << endl; //error
    cout << "4+5 = " << n << endl;
    return 0;
}

指针与引用的区别

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 _cpluscplus
extern "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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值