你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C++——布尔数据类型(bool)及引用

[复制链接]
gaosmile 发布时间:2020-6-22 20:50
一、布尔数据类型:
在c语言里面我们知道是没有布尔数据类型的,而在C++中添加了布尔数据类型(bool),它的取值是:true或者false(也就是1或者0),在内存大小上它占用一个字节大小:

1、bool类型只有true(非0)和false(0)两个值。

2、C++编译器会将非0值转换为true,0值转换为false。

#include <stdio.h>

int main(int argc, char *argv[])
{
    bool b = false;
    int a = b;
   
    printf("sizeof(b) = %d\n", sizeof(b));
    printf("b = %d, a = %d\n", b, a);
   
    b = 3;
    a = b;
   
    printf("b = %d, a = %d\n", b, a);
   
    b = -5;
    a = b;
   
    printf("b = %d, a = %d\n", b, a);
   
    a = 10;
    b = a;
   
    printf("a = %d, b = %d\n", a, b);
   
    a = 0;
    b = a;
   
    printf("a = %d, b = %d\n", a, b);
   
    return 0;
}

演示结果:
root@txp:/home/txp# ./a.out
sizeof(b) = 1
b = 0, a = 0
b = 1, a = 1
b = 1, a = 1
a = 10, b = 1
a = 0, b = 0

2、C++中的三目运算符:
对三目运算符,想必大家都再熟悉不过了,不过在c++中的三目运算符的用法就比c语言更加高级了,来先看一个示例:

int a = 1;
int b = 2;

( a < b) ? a : b = 3;

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

上面的三目运算符语句看起来怎么有点奇怪,它作为左值了,一般在c语言里面它应该是作为右值赋值给一个变量的,那这样写在c++中有没有错误,答案肯定是没有错的,我们还是来看一下这种写法在c语言中报了啥错误:
root@txp:/home/txp# gcc test.c
test.c: In function ‘main’:
test.c:7:21: error: lvalue required as left operand of assignment
    ( a < b) ? a : b = 3;

这里我们可以发现它不能做为左值来对它进行赋值,而我们在c++编译器里面来编译,很明显它是没有错误的,行的通,那我们再来修改一下:
#include <stdio.h>
int main(void)
{

   int a = 1;
   int b = 2;
   ( a < b) ? a : 4 = 3;

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

}


编译结果(这个错误和在c语言里面一样,注意这里我是在C++编译器里面编译,只是把三目运算符里面修改了一下。):
root@txp:/home/txp# g++ test1.cpp
test1.cpp: In function ‘int main()’:
test1.cpp:7:23: error: lvalue required as left operand of assignment
    ( a < b) ? a : 4 = 3;
                       ^

小结:
1、c语言里面的三目运算符返回的是变量值,它不能作为左值来使用。
2、c++中的三目运算符可以直接返回变量本身,既可以作为右值使用,也可以作为左值来使用。
3、c++中的三目运算符可能返回的值中如果有一个是常量值,则不能作为左值进行使用,这点要切记和理解。
二、C++中的引用:
1、引用的概念:
--引用可以看作一个已定义变量的别名
--引用的语法:Type &name = var;这里举个简单的示例:
int a =4;
int& b =a; //b为a的别名
b = 5;//操作b就是操作a

--注意普通引用在定义时必须用同类型的变量进行初始化。
下面是demo演示:
#include <stdio.h>

int main(int argc, char *argv[])
{
    int a = 4;
    int& b = a;
   
    b = 5;
   
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    printf("&a = %p\n", &a);
    printf("&b = %p\n", &b);
   
    return 0;
}

演示结果:
root@txp:/home/txp# ./a.out
a = 5
b = 5
&a = 0x7fff408ffdec
&b = 0x7fff408ffdec

2、引用的意义:
--引用作为变量名而存在,因此在一些场合可以代替指针。
--引用相对于指针来说具有更好的可读性和实用性。
下面举个经典的例子来对比一下:
(1)引用方式:
#include <stdio.h>

void swap(int& a,int& b)
{
   int t = a;
   a=b;
   b=t;
}
int main(void)
{
    int a =5;
    int b =6;
    printf("a=%d,b=%d\n",a,b);
    swap(a,b);

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

    return 0;

}

演示结果:
root@txp:/home/txp# ./a.out
a=5,b=6
a=6,b=5

(2)指针方式:
#include <stdio.h>

void swap(int *a,int *b)
{
   int t =*a;
   *a=*b;
   *b=t;
}
int main(void)
{
    int a =5;
    int b =6;
    printf("a=%d,b=%d\n",a,b);
    swap(&a,&b);

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

    return 0;

}

演示结果:
root@txp:/home/txp# ./a.out
a=5,b=6
a=6,b=5

3、特殊的引用:
--在c++中可以声明const引用。
--const Type& name =var;
--const 引用让变量拥有只读属性。
--当使用常量对const引用进行初始化时,C++编译器会为常量分配空间,并将引用名作为这段空间的别名:
int a = 4;
const int& b =a;
int *p=(int *)&b;
b=5;//错误,只读变量
*p=5;//修改a的值

下面来看一个示例:
#include <stdio.h>

void Example()
{
    printf("Example:\n");
   
    int a = 4;
    const int& b = a;
    int* p = (int*)&b;
   
    //b = 5;
   
    *p = 5;
   
    printf("a = %d\n", a);
    printf("b = %d\n", b);
}



int main(int argc, char *argv[])
{
    Example();
   
    printf("\n");
   
  
    return 0;
}

演示结果:
root@txp:/home/txp# ./a.out
Example:
a = 5
b = 5

4、引用有自己的存储空间吗?
话不多说,看试验就知晓:
#include <stdio.h>

struct TRef
{
    char& r;
};

int main(int argc, char *argv[])
{
    char c = 'c';
    char& rc = c;
    TRef ref = { c };
   
    printf("sizeof(char&) = %d\n", sizeof(char&));
    printf("sizeof(rc) = %d\n", sizeof(rc));
   
    printf("sizeof(TRef) = %d\n", sizeof(TRef));
    printf("sizeof(ref.r) = %d\n", sizeof(ref.r));

    return 0;
}

演示结果:
root@txp:/home/txp# ./a.out
sizeof(char&) = 1
sizeof(rc) = 1
sizeof(TRef) = 8
sizeof(ref.r) = 1

很明显有它的内存大小,下面就来看一下引用的本质。
5、引用的本质:
(1)引用在c++中的内部实现是一个指针常量,比如说说:
Type& name;

void fun(int& a)
{
  a=8;
}

等价于:
Type* const name

void fun(int* const a)
{
  *a=8;
}

(2)C++编译器在编译过程中用指针变量作为引用的内部实现,因此引用所占用的空间大小与指针相同(可以结合上面的那个例子仔细回忆和理解一下)。
(3)从使用的角度,引用只是一个别名,c++为了实用性而隐藏了引用的存储空间这一细节。
(4)c++中的引用大多数的情况下代替指针:
--功能性:可以满足多数需要使用指针的场合。
--安全性:可以避免由于指针操作不当而带来的内存错误。
--操作性:简单易用,又不失功能强大。
#include <stdio.h>

struct TRef
{
    char* before;
    char& ref;
    char* after;
};

int main(int argc, char* argv[])
{
    char a = 'a';
    char& b = a;
    char c = 'c';

    TRef r = {&a, b, &c};

    printf("sizeof(r) = %d\n", sizeof(r));
    printf("sizeof(r.before) = %d\n", sizeof(r.before));
    printf("sizeof(r.after) = %d\n", sizeof(r.after));
    printf("&r.before = %p\n", &r.before);
    printf("&r.after = %p\n", &r.after);

    return 0;
}

演示结果:
@txp:/home/txp# ./a.out
sizeof(r) = 24
sizeof(r.before) = 8
sizeof(r.after) = 8
&r.before = 0x7ffdeacc7a00
&r.after = 0x7ffdeacc7a10

再来看一个函数返回引用示例:
#include <stdio.h>

int& func()
{
    static int s = 0;
   
    printf("func: s = %d\n", s);
   
    return s;
}

int main(int argc, char* argv[])
{
   
    int& rs = func();
   
    printf("\n");
    printf("main: rs = %d\n", rs);
    printf("\n");
  
    rs = 11;
   
   
    func();
   
    printf("\n");
   
    printf("main: rs = %d\n", rs);
    printf("\n");
   
    return 0;
}

演示结果:
root@txp:/home/txp# ./a.out
func: s = 0

main: rs = 0

func: s = 11

main: rs = 11

三、总结:
1、bool的总结:
--bool类型是c++新添加的基础类型。
--bool类型的值只能是true和false。
--c++中的三目运算符可作为左值来使用。
2、引用:
--引用作为变量名而存在旨在代替指针。
--const引用可以使得变量具有可读属性。
--引用在编译器内部使用指针常量实现。
--引用的最终本质为指针。
--引用可以尽可能的避免内存错误。
收藏 评论2 发布时间:2020-6-22 20:50

举报

2个回答
desk1983 回答时间:2020-6-22 23:08:10
非常好的资料,对初学者很有帮助;
希望楼主多多分享,赠人玫瑰,手有余香,念念不忘,必有回响;.
李康1202 回答时间:2020-6-23 08:49:27
顶一下

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版