1.c++中的bool类型:
   
其实c语言中也有bool类型,如果是遵守c90标准的编译器(其实现在大量编译器都是c90标准的),对于bool类型的使用除了要使用头文件
stdbool.h外,与c++中的bool类型完全相同。如果不是c90标准,则此时的bool其实就是int类型。详细见下stdbool.h文件的源码
[cpp]  
#ifndef _STDBOOL_H_  
#define _STDBOOL_H_

#define __bool_true_false_are_defined   1

#ifndef __cplusplus

#define false   0  
#define true    1

#define bool    _Bool  
#if __STDC_VERSION__ < 199901L && __GNUC__ < 3 && !defined(__INTEL_COMPILER)  
typedef int _Bool;  
#endif

#endif /** !__cplusplus */

#endif /** !_STDBOOL_H_ */  
     c++中bool类型有几个特性:
     a.理论上bool变量只占用一个字节,但是如果多个bool变量定义在一起,可能会各占一个bit,这个取决于编译器的实现。
     b.bool类型是一个很严格的类型,只有true和false两个值,一切非零的值都会变成true。测试代码如下:
[cpp]  
#include <stdio.h>  
int main(int argc, char *argv[])  
{  
    int a;  
    bool b = true;

printf("b = %d, sizeof(b) = %d\n", b, sizeof(b));

b = 3;  
    a = b;   
    printf("a = %d, b = %d\n", a, b);

b = -5;  
    a = b;   
    printf("a = %d, b = %d\n", a, b);

a = 10;  
    b = a;     
    printf("a = %d, b = %d\n", a, b);

b = 0;   
    printf("b = %d\n", b);

printf("Press enter to continue ...");  
    getchar();   
    return 0;  
}

2.c++中引用的概念:
     1.引用的定义:
引用是c到c++升级中提出的一个新概念。引用可以看作一个已定义变量的别名。普通引用在声明的时候必须要用其他变量进行初始化,一旦初始化这个引用就不能再是其它变量的别名了。
[cpp]  
<span style="white-space:pre">  </span>Type& name = var;  
      2.引用的作用:引用作为变量的别名,在某些情况下可以替代指针,相对指针来说具有更好的可读性和实用性。
例子:swap函数的对比:
[cpp]  
void swap(int& a,int& b)  //使用引用作为函数参数,进行两个数交换  
{  
      int t = a;  
      a = b;  
      b = t;  
}  
swap(a,b);  
[cpp]  
void swap(int* a,int* b)  //使用地址传递,进行两个数交换  
{  
      int t = *a;  
      *a = *b;  
      *b = t;  
}  
swap(&a,&b);  
可见两个程序,第二个容易被误会成为是a与b地址的交换,可读性不高。切记:引用作为函数参数的时候不用进行初始化,当调用函数的时候才进行初始化。
       3.常引用(const引用):const Type& name = var;    const引用是使name引用具有只读属性。
          常引用的另一个用法:当使用常量,或者类型不一致的变量对const引用进行初始化时,c++编译器会为常量,或者类型不一致的变量的值分配空间,并将引用名作为这段空间的别名。也就是说使用常量对const引用初始化后将生成一个只读变量(与c语言中的只读变量意义相同)。
代码如下:
[cpp]  
int main()  
{  
    char a = 10;  
    const int& b = a;  
    //const int& b = 9;  
    printf("a %x\n",&a);  
    printf("b %x\n",&b);  
    return 0;  
}  
      4.引用的实质:
       
 引用在c++中的内部实现其实就是一个常指针,Type& name  <>   Type * const
name(是地址不能变的一个指针),其实每次给引用初始化的时候Type& name1= var1,就是在给Type * const
name =
&var的过程,也就是说这个地址不能变的特性决定了引用一旦初始化就不能再成为其他变量的别名。当你每次使用引用的时候,无论是作为左值还是右
值的时候,其实var1就是*var。
          注意:引用实质是指针,所有引用有自己的存储空间,所占的空间大小与指针相同。
      5.返回值为引用:
          a.引用为函数返回值:
             若返回栈变量:不能成为其它引用的初始化值(int& b = fun();)、不能成为左值(即不能被赋值 fun() = 10;)、但是可以当做右值使用(int a = fun(); 即把这个引用的值赋值给a变量)。
             若返回静态变量或全局变量:可以成为其它引用的初始化值、即可以作为右值使用,也可以作为左值使用。代码如下:
[cpp]
#include <stdio.h>  
int& f()  
{  
    static int a = 0;     
    return a;  
}  
int& g()  
{  
    int a = 0;   
    return a;  
}

int main()  
{  
    int a = g();  
    int& b = g();

f() = 10;

printf("a = %d\n", a);  
    printf("b = %d\n", b);  
    printf("f() = %d\n", f());

printf("Press enter to continue ...");  
    getchar();   
    return 0;  
}  
          b.c++中三目运算符的升级:c语言中的三目运算符返回的是变量的值,不能作为左值使用。c++中的三目运算符返回的是变量的引用,因此可以即当做右值也当做左值。
             注意:三目运算符可能返回的值中如果有一个是常量,则不能作为左值使用,如:(a<b?1:b) = 10; 是会编译出错的。因为此时的三目运算符返回的是值,而不再是引用了。
课后思考:
1.c++中为什么不允许定义引用数
组,Type&
name[num]:  引用数组理论上是一个数组,每一个元素都是一个引用。但是数组是一段连续内存空间,所有说这些引用的地址也应该是连续的。但是引
用的地址也就是变量的地址,所以说引用数组是没有意义的,直接用原来的变量数组就可以了。换个角度再说,如果引用数组成了,那想访问这个数组,对引用取地
址&&name,不就产生二义性了吗!所以c++里面没有引用数组。
2.如何定义一个数组的引用:其实数组的引用,就是一个数组元素类型的指针的引用,如:int* &d = p;  
3.数组的引用与数组指针有什么区别:数组的引用,是一个数组元素类型的指针的引用。数组指针,是一个指向数组的指针。两者没有什么关系!!!
4.如何定义一个函数的引用:函数的引用,就是函数指针的引用,如:void (* &m)(void) = q;
5.函数的引用与函数的指针有什么区别:没什么区别,函数的引用就是函数指针的引用,两者是一个东西!!!
这里有一个小例子(请仔细查看备注):
[cpp]  
#include <stdio.h>

void fun(void)  
{  
    printf("hello fun\n");  
}  
int main(int argc, char *argv[])  
{  
    int a[10]={1,2,3,4,5};  
    int* p = a;  
    printf("%d\n",p[2]);  
    int* &d = p; //这里定义了一个数组的引用,即int*类型指针的引用   
    printf("%d\n",d[2]);  //此时d就是p

void (*q)(void) = fun;  //这里定义了一个函数指针   
    void (* &m)(void) = q;  //这里定义了一个void (*  )(void)类型的函数指针的引用   
    m();  
    //q();

int qq = 12;  
    int (*nl)[10] = &a;  
    int (*na)[10] = (int (*)[10])qq;  //这里要注意这个强制类型转换的方式 (int (*)[10])为一个整体类型

//要注意给引用初始化的时候  一定要是一个变量 而不能是一个常量  这里&a是一个常量 所以应该用常引用   
    int (* const &n)[10] = &a;//注意a是变量  &a是常量   也可以像上面的方式一样  用一个指针过度下

int (* &pn2)[10] =  (int (* &)[10])n;//同一个原理的强制类型转换  有const与没有const 完全是两个类型   
    int (* &pn)[10] = nl;    //这里定义了一个int(* )[10]类型的数组指针的引用  
    int (* &pn1)[10] = pn;  //因为 pn就是nl   
    printf("%d\n",**n);  
    //printf("%d\n",**pn);  
    printf("Press enter to continue ...");  
    getchar();   
    return 0;  
}  
对于这段代码,有几个要注意的问题:
1.int (*na)[10] = (int (*)[10])qq;  //这里要注意这个强制类型转换的方式 (int (*)[10])为一个整体类型
2.c++是严格检查数据类型的,有const与无const完全是不同的两个类型
3.int (* const &n)[10] = &a; //要注意,给引用初始化的时候,一定要是一个变量而不能是一个常量,这里&a是一个常量,所以应该用常引用 。
4.有数组引用(变量指针的引用 int*
&a = b;),有函数引用(函数指针的引用 void (* &m)(void) = q;),有数组指针的引用(int (*
&pn)[10] = nl;),有引用函数(一个函数的返回值是一个引用 int&fun(void)),但是切记
没有引用数组!!!

c++学习笔记(c++中的引用)的更多相关文章

  1. ArcGIS案例学习笔记-点集中最近点对和最远点对

    ArcGIS案例学习笔记-点集中最近点对和最远点对 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 目的:对于点图层,查找最近的点对和最远的点对 数据: 方法: 1. ...

  2. 《Cocos2d-x游戏开发实战精解》学习笔记3--在Cocos2d-x中播放声音

    <Cocos2d-x游戏开发实战精解>学习笔记1--在Cocos2d中显示图像 <Cocos2d-x游戏开发实战精解>学习笔记2--在Cocos2d-x中显示一行文字 之前的内 ...

  3. Struts2学习笔记-jsp中引用struts2框架

    如果在jsp中需要引用struts2 框架,需在前面加上以下内容 <%@taglib prefix="s" uri="/struts-tags" %> ...

  4. 电磁兼容性设计学习笔记--PCB中地的布局

    http://bbs.ednchina.com/BLOG_ARTICLE_3010439.HTM PCB上元器件的布局对整个PCB板的电磁兼容性影响很大,所以从事硬件电路设计的工程师很有必要学习PCB ...

  5. JavaScript学习笔记——JS中的变量复制、参数传递和作用域链

    今天在看书的过程中,又发现了自己目前对Javascript存在的一个知识模糊点:JS的作用域链,所以就通过查资料看书对作用域链相关的内容进行了学习.今天学习笔记主要有这样几个关键字:变量.参数传递.执 ...

  6. Swift 学习笔记 (三) 之循环引用浅析

    原创:转载请注明出处 110.自动引用计数实践 下面的例子展示了自动引用计数的工作机制.例子以一个简单的Person类开始,并定义了一个叫name的常量属性: class Person {     l ...

  7. Java学习笔记之深入理解引用

    引言:Java中数据传递的方式,除了基本数据类型是按照值传递,其它类型全部是按照引用传递,这和C++有很大区别,但是很多网上文章都解释的不清楚,甚至是错误的,在查阅资料之后,下面整理出一个比较容易理解 ...

  8. Python学习笔记6-Python中re(正则表达式)模块学习

    今天学习了Python中有关正则表达式的知识.关于正则表达式的语法,不作过多解释,网上有许多学习的资料.这里主要介绍Python中常用的正则表达式处理函数. re.match re.match 尝试从 ...

  9. 设计模式学习笔记——java中常用的设计模式

    单例设计模式(Singleton Pattern) 观察者模式(Observer Pattern) 工厂模式(Factory Pattern) 策略模式(Strategy Pattern) 适配器模式 ...

随机推荐

  1. STM32F10xxx启动模式分析(详细)

    STM32的启动模式: STM32有三种启动模式,对应的存储介质均是芯片内置的:      1. User Flash Memory(Main Memory)  = 芯片内置的Flash,用户程序存放 ...

  2. 关于mwArray和一般数组的区别

    可以用下面的代码详细理解mwArray和一般数组之间的区别 mwArray a(, , mxDOUBLE_CLASS); double *aData; aData = ]; int iii; ; ii ...

  3. HDU 1016 Prime Ring Problem (回溯法)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  4. C based

    switch(ch){case '\n':    lines += 1;    /*fail thru*/case ' ':case '\t':    words += 1;default:    c ...

  5. Js节点属性与方法

    属性: Attributes     存储节点的属性列表(只读) childNodes 存储节点的子节点列表(只读) dataType     返回此节点的数据类型 Definition     以D ...

  6. 项目中常用方法总结(将将DataTable数据集映射到实体对象)【转】

    本篇把项目中用到的一些通用方法总结出来, 这些方法因为经常需要在项目中用到,所以把它们归纳在一起, 形成一个.dll 文件是一个理想的选择. 这样也便于日后缩短开发周期. 一. 把一个DataGrid ...

  7. AS3: Socket 数据包 收 发

    AS3.0中使用Socket使用tcp服务器协议,它是一种流协议,不停的将分片传输给客户端,P作为流,发包是不会整包到达的,而是源源不断的. 它不同于UDP服务器协议,UDP作为数据包协议,整包到达. ...

  8. 【DFS+小操作判重】【HDU2610+HDU2611】Sequence

    题意 2610 按照长度优先 位置次之 输出所有不递减序列 2611 按照长度优先 大小次之 输出所有不递减序列 题解不写了 来源于http://www.cnblogs.com/wally/archi ...

  9. 牛掰的图片等比缩放js代码

    function resizeImg(img,oAW,oAH){ var oimgW = img.width, oimgH = img.height, oimg = img, oY = (oimgH/ ...

  10. ASP.NET怎么防止多次点击提交按钮重复提交

    今天做一个系统,由于服务器有点慢,所以常会被点击两次或三次,提交的数据就是多次了.所以要让按钮点击后,不能再次点击. 对于一个按钮,要让变成恢色的,只要this.disabled=true就可以了,可 ...