前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >c++ 之布尔类型和引用的学习总结!

c++ 之布尔类型和引用的学习总结!

作者头像
用户6280468
发布于 2022-03-21 06:24:54
发布于 2022-03-21 06:24:54
47500
代码可运行
举报
文章被收录于专栏:txp玩Linuxtxp玩Linux
运行总次数:0
代码可运行

一、布尔数据类型:

在c语言里面我们知道是没有布尔数据类型的,而在C++中添加了布尔数据类型(bool),它的取值是:true或者false(也就是1或者0),在内存大小上它占用一个字节大小:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

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

2C++编译器会将非0值转换为true0值转换为false
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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;
}

演示结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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语言更加高级了,来先看一个示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

int a = 1;
int b = 2;

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

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

上面的三目运算符语句看起来怎么有点奇怪,它作为左值了,一般在c语言里面它应该是作为右值赋值给一个变量的,那这样写在c++中有没有错误,答案肯定是没有错的,我们还是来看一下这种写法在c语言中报了啥错误:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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++编译器里面来编译,很明显它是没有错误的,行的通,那我们再来修改一下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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++编译器里面编译,只是把三目运算符里面修改了一下。):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;这里举个简单的示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 int a =4;
 int& b =a; //b为a的别名
 b = 5;//操作b就是操作a

--注意普通引用在定义时必须用同类型的变量进行初始化。

下面是demo演示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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;
}

演示结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
root@txp:/home/txp# ./a.out
a = 5
b = 5
&a = 0x7fff408ffdec
&b = 0x7fff408ffdec

2、引用的意义:

--引用作为变量名而存在,因此在一些场合可以代替指针。

--引用相对于指针来说具有更好的可读性和实用性。

下面举个经典的例子来对比一下:

(1)引用方式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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;

}

演示结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
root@txp:/home/txp# ./a.out
a=5,b=6
a=6,b=5

(2)指针方式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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;

}

演示结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
root@txp:/home/txp# ./a.out
a=5,b=6
a=6,b=5

3、特殊的引用:

--在c++中可以声明const引用。

--const Type& name =var;

--const 引用让变量拥有只读属性。

--当使用常量对const引用进行初始化时,C++编译器会为常量分配空间,并将引用名作为这段空间的别名:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int a = 4;
const int& b =a;
int *p=(int *)&b;
b=5;//错误,只读变量
*p=5;//修改a的值

下面来看一个示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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;
}

演示结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
root@txp:/home/txp# ./a.out
Example:
a = 5
b = 5

4、引用有自己的存储空间吗?

话不多说,看试验就知晓:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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;
}

演示结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
root@txp:/home/txp# ./a.out
sizeof(char&) = 1
sizeof(rc) = 1
sizeof(TRef) = 8
sizeof(ref.r) = 1

很明显有它的内存大小,下面就来看一下引用的本质。

5、引用的本质:

(1)引用在c++中的内部实现是一个指针常量,比如说说:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Type& name; 

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

等价于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Type* const name

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

(2)C++编译器在编译过程中用指针变量作为引用的内部实现,因此引用所占用的空间大小与指针相同(可以结合上面的那个例子仔细回忆和理解一下)。

(3)从使用的角度,引用只是一个别名,c++为了实用性而隐藏了引用的存储空间这一细节。

(4)c++中的引用大多数的情况下代替指针:

--功能性:可以满足多数需要使用指针的场合。

--安全性:可以避免由于指针操作不当而带来的内存错误。

--操作性:简单易用,又不失功能强大。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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;
}

演示结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@txp:/home/txp# ./a.out
sizeof(r) = 24
sizeof(r.before) = 8
sizeof(r.after) = 8
&r.before = 0x7ffdeacc7a00
&r.after = 0x7ffdeacc7a10

再来看一个函数返回引用示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#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;
}

演示结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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引用可以使得变量具有可读属性。

--引用在编译器内部使用指针常量实现。

--引用的最终本质为指针。

--引用可以尽可能的避免内存错误。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 txp玩Linux 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
再论C++中的const和引用
今天给大家分享一下这段时间学习c++的总结学习:c++里面的const关键字和引用。
用户6280468
2022/03/21
4500
C语言之const和volatile"究极"学习
关于const的用法,现在大概前前后后应该写了有两篇文章,以前学习的时候,用法体会不是那么深刻,为啥这么说呢,因为在学习c++的时候,会发现const关键字有新的玩法,关于这个新的玩法,大家可以去看最近学习总结写的c++文章专辑。
用户6280468
2022/03/21
4090
C语言之const和volatile"究极"学习
【编程基础】C++比C牛逼的七个点
1. 函数检测增强 在C语言中,重复定义多个同名的全局变量是合法的,在C++中,不允许定义多个同名的全局变量。 C语言中多个同名的全局变量最终会被链接到全局数据区的同一个地址空间上。 下面的代码在c中
程序员互动联盟
2018/03/12
1.3K0
【编程基础】C++比C牛逼的七个点
C++之函数模板的深入理解学习总结
在昨天的文章里面,我们给大家简单的分享了关于c++里面的函数模板的概念,通过代码示例,我们对函数模板的优势有了一个比较清楚的认识。咋们今天继续来深入学习函数模板。以下内容是今天知识学习总结笔记。
用户6280468
2022/03/21
2600
C++之函数模板的深入理解学习总结
C++之类成员函数重载学习总结
从上面回顾重载函数的知识中,我们要注意到一点函数重载必须发生在同一作用域里面(其他两点问题不大),所以的构造函数和普通成员函数是可以构造重载的,而与全局函数是不可以构成重载的。
用户6280468
2022/03/21
5530
C++之操作符重载学习总结
1、我们先来看一个问题实现,下面的复数解决方案是否可行,复数大家应该都不陌生(分为实部和虚部):
用户6280468
2022/03/21
2730
C++之标准库的学习总结
从上面我们可以看到,不直接使用printf函数去打印这个值,这个以前在书上,都是直接讲解把数值说送到输出流中去,但是你一开始学习cout函数(或者说你还没有接触到对象的时候,根本不明白这什么意思);如果进行了左移的重载之后,那么程序将产生神奇的变化,所以在 main() 中不用 printf() 和格式化字符串 '\n' 了,因为编译器会通过重载的机制会为我们选择究竟使用哪一个重载机制。
用户6280468
2022/03/21
5160
C++之标准库的学习总结
C++之函数模板的概念和意义
我们再用使用函数的方式来实现这个功能,当然以前我们在c语言里面使用指针传参方式来实现这种两个数值直接的交换,现在我们利用c++里面更加高级的方式来实现,就是使用引用来实现(不过它的本质还是指针来实现,只是我们只用引用再不用去考虑指针的细节了)
用户6280468
2022/03/21
4540
C++之函数模板的概念和意义
c++学习之析构函数和const总结,你真的掌握了吗?
大家好,今天再次写c++的文章,首先给各位网友说明一下这段时间为啥都是写c++的文章,没有Linux的文章;原因是这样的,自己立了一个flag,八月份把c++的基本语法全部过完(目前完成三分之一),所以文章过程中我写的可能没有很详细的解释一些概念;所以文章中有不理解的地方,可以私聊我,我会尽力解答好。同时昨天遇到一位刚高考完的网友,人家都这么努力学习,你还打酱油吗?
用户6280468
2022/03/21
2550
c++学习之析构函数和const总结,你真的掌握了吗?
手撕C++入门基础
在C/C++中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全局作⽤域中,可能会导致很多冲突。使⽤命名空间的⽬的是对标识符的名称进⾏本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
凯子坚持C
2024/09/23
1420
手撕C++入门基础
c++中的构造函数学习总结(一)
大家晚上好,今天给大家分享的是c++中的构造函数,这段时间可能分享c++、Uboot、linux内核的文章会比较多一点,自己的拖延症太强了,得改掉这个坏习惯来。每天进步一点点,日积月累你也是专家。
用户6280468
2022/03/21
6880
c++之重载函数学习总结
从上面报错的结果里面有一个单词ambiguous(意思是梦棱两可的),也就是说默认参数这种使用时不允许的。
用户6280468
2022/03/21
4130
C++之静态成员变量和静态成员函数学习总结
平时我们在写类的时候,类中的成员变量,我们一般是通过对象名来访问public成员变量的,一般private(私有)的成员变量,对象是不能直接访问的;同时我们要明白每个对象的成员变量都是专属的,而且成员变量是不能在对象之间共享的,这就是专属性。下面我们来做一个小的程序需求来慢慢引出静态成员变量:
用户6280468
2022/03/21
6310
C++之布尔类型和类型
布尔类型 C++中的布尔类型 C++在C语言的基本类型系统之上增加了bool C++中的bool可取的值只有true 和 false 理论上bool只占用一个字节 布尔类型是C++中的基本数据
程序手艺人
2018/05/18
1.1K0
2.C++中的bool类型,三目运算符,引用
在C++中,bool类型只有true(非0)和flase(0)两个值,且bool类型只占用了一个字节.
诺谦
2019/05/24
1.1K0
C++之友元的学习总结
注意:func() 全局函数是 Test 类的友元,func() 可以访问Test 类的所有成员,但是 func() 不是 Test 的成员函数。
用户6280468
2022/03/21
2500
C++之友元的学习总结
【C++】入门基础介绍(下)输入输出,函数重载,缺省与引用
iostream是 Input Output Stream 的缩写,是标准输入、输出流库,定义了标准的输入、输出对象。 包含C++标准库是不需要+.h后缀。
fhvyxyci
2024/10/08
1400
【C++】入门基础介绍(下)输入输出,函数重载,缺省与引用
C++之初始化列表学习总结
1、在介绍列表之前,我们先来看看使用const关键字来修饰类中的成员会有什么事情发生,下面是一段简单代码:
用户6280468
2022/03/21
2500
C++之拷贝构造函数的浅copy和深copy
当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空;换句话来说,就是我们在类中,不用我们程序猿自己写,编译就自动提供了无参构造函数(只是我们肉眼看不到!)
用户6280468
2022/03/21
4150
C++之拷贝构造函数的浅copy和深copy
c++之对象构造顺序和销毁(析构函数)
这里我们可以看出当程序流执行到相应的构造对象的那条执行语句时,就会调用构造函数(或者拷贝构造函数)。goto语句想必大家不陌生,但是都害怕这玩意,下面我们加入goto语句看看会产生什么现象:
用户6280468
2022/03/21
6360
相关推荐
再论C++中的const和引用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验