《C++ Primer》第2章 变量(一)

参考资料:

  • 《C++ Primer》第5版
  • 《C++ Primer 习题集》第5版

2.1 基本内置类型(P30)

C++ 定义的基本类型包括算术类型(arithmetic type)和空类型(void),其中算术类型包括字符、整型、布尔值和浮点数。

2.1.1 算术类型(P30)

算术类型分为整型(包括字符、布尔值)和浮点型。

Screenshot_20230904_192850

char 类型实际上会表现为 signed charunsigned char ,具体是哪种由编译器决定。

如何选择类型?

  • 数值不可能为负时,选用无符号类型。
  • 默认使用 int 进行整型运算,使用 double 进行浮点型运算。

2.1.2 类型转换(P32)

常见的类型转换:

  • 非布尔算数值赋给布尔类型时,初始值为 0 则结果为 false ,否则结果为 true ;把布尔类型赋值给非布尔类型时,初始值为 false 则结果为 0 ,初始值为 true 则结果为 1 。
  • 把浮点数赋值给整型,仅保留小数点前的部分;把整型赋值给浮点数,小数部分记为 0 。
  • 当赋给无符号类型超过其表示范围的值时,其实际结果要取模;当赋给有符号类型超过其表示范围的值时,其结果未定义

由于 C++ 并未对 int 类型的尺寸做出规定,所以我们不应把 int 的尺寸看作一个固定值。

当无符号类型和有符号类型混用时,一般会将有符号类型转换为无符号类型

这部分最好结合数的机器表示、补码等知识进行理解。

2.1.3 字面值常量

整型字面量默认为十进制带符号数,特别地,以 0 开头的整型字面量代表八进制数,以 0x0X 开头的整型字面量代表十六进制数。八进制和十六进制字面值可能是带符号的,也可能是无符号的。

20 /* 十进制 */    024 /* 八进制 */    0x14 /* 十六进制 */

严格地说,字面值不会是负数,形如 -42 的字面值应看作对字面值 42 取负值。

浮点字面值:

3.14    3.14e0    0.    0E0    .001 

由单引号括起来的单个字符为 char 型字面值,双引号括起来的字符为字符串型字面值。字符串以空字符结尾(‘\0’)。

如果两个字符串型字面值位置紧邻或仅由空格、缩进和换行符分隔时,则它们实际上是一个整体

// 多行书写
cout << "hello""world";

泛化的转义序列:\x 后紧跟若干十六进制数字,\ 后紧跟 1~3 个八进制数字:

\12 (换行符)    \xc (换行符)

指定字面值的类型:

Screenshot_20230904_203601

练习

int month = 09;	// 编译报错
double d = 1024f;	// 编译报错,因为1024为整型字面量,不能有f后缀

2.2 变量(P38)

变量提供一个有名字的、可操作存储空间,其数据类型决定占用空间的大小、布局方式、值的范围、能参与的运算类型。

2.2.1 变量定义(P38)

变量定义的基本形式:类型说明符,随后紧跟一个或多个变量名(用逗号分隔)。

int a = 0, b, c = 0;
int a = b = 1;	// 错误

初始化

当变量再创建时获得了初值,就称这个变量被初始化了。用于变量初始化的值可以是任意复杂的表达式

在 C++11 后,允许统一用花括号初始化变量:

int a{0};
int b[4]{1, 2, 3, 4};

这种初始化方式会在初值存在丢失信息的风险时进行报错。

默认初始化

对内置类型的变量,如果在函数体外定义,则初始化为 0 ;如果在函数体内定义,则不会被初始化,未被初始化的变量的值是未定义的。

绝大多数类无须显示初始化,这样的类提供了一个合适的默认值,如 string 类默认空串。

2.2.2 变量声明和定义的关系(P41)

变量声明的作用是告诉编译器某个实体的存在;定义的作用是在程序中为实体分配内存。

定义变量的同时也就声明了这个变量,如果仅仅想要声明一个变量,要使用 extern 关键字,并且不能显式初始化。

变量只能被定义一次,可以被声明多次。

2.2.3 标识符(P43)

2.2.4 名字的作用域(P43)

程序中的每个名字都会指向一个特定的实体。

作用域是程序的一部分,大部分作用域用花括号分隔。

名字的有效区域始于名字的声明语句,结束于声明语句所在的作用域末端

作用域能够嵌套,内层作用域能够访问外层作用域的名字,也能重新定义外层作用域已有的名字。

2.3 复合类型(P45)

声明语句的通用描述:一条声明语句由一个基本数据类型和紧随其后的一个声明符(declarator)列表组成。每个声明符命名了一个变量并指定该变量为与基本数据类型有关某种类型

2.3.1 引用(P45)

引用(reference)为对象起了一个别名,引用并非对象,也无法令引用重新绑定对象,因此引用必须被初始化

int a = 0;
int &b = a;

对引用的所有操作都是在与之绑定的对象上进行的。由于引用本身并不是对象,所以不能对引用进行引用。

一般情况下,引用的类型必须和绑定的对象严格匹配,且只能绑定在对象上。

2.3.2 指针(P47)

指针是指向另一种类型的复合类型,指针本身是一个对象,允许赋值和拷贝,无须在定义时赋初值。

获取对象的地址

取地址符 &

由于引用不是对象,所以不能定义指向引用的指针。

一般而言,指针的类型要和指向的对象严格匹配。

指针值

指针的值是有效的,当且仅当以下情况:

  • 指向一个对象

  • 指向紧邻对象所占空间的下一个位置

    可以用来判断是否越界

  • 空指针

利用指针访问对象

如果指针指向了一个对象,则可以使用解引用符 * 来访问该对象。对指针解引用会得到指针指向的对象。

空指针

int *p1 = nullptr;
int *p2 = 0;
int *p3 = NULL;

nullptr 是一种特殊类型的字面值,可以被转换成任意类型的指针类型。NULL 是一种预处理变量,会被预处理器处理为 0 。新标准下最好使用 nullptr 并避免使用 NULL

int *p = 0x12345678;    //错误,因为0x12345678会被当成int型字面量

赋值和指针

赋值永远改变的是等号左边的对象

其他指针操作

指针可以用在条件表达式中;两个相同类型的指针可以比较

void* 指针

void* 指针是一种特殊的指针,可以存放任意对象的地址。我们不能直接操作 void* 指针所指向的对象。

练习

2.23 给定指针 p ,可以判断它是否指向了一个合法的对象吗?

答:个人感觉其实不可以的。首先,我们无法确定指针 p 是否有效。再者,即使 p 有效,它仍有可能是指向紧邻某对象的下一个位置。

2.3.3 理解复合类型的声明(P51)

在同一条定义语句中,基本数据类型只有一个,但声明符的形式可以有很多:

int *p, a = 0, &b = a;

指向指针的引用

int i = 0;
int *p = &i;
int *&a = p;

要理解变量 a 的类型,我们可以从右向左阅读 a 的定义,与 a 紧邻的符号(&)对 a 有最直接的影响,所以 a 是一个引用,声明符的其余部分确定了 a 引用的类型。所以,aint 指针的引用。

int *p, a = 0, &b = a;


### 指向指针的引用```cpp
int i = 0;
int *p = &i;
int *&a = p;

要理解变量 a 的类型,我们可以从右向左阅读 a 的定义,与 a 紧邻的符号(&)对 a 有最直接的影响,所以 a 是一个引用,声明符的其余部分确定了 a 引用的类型。所以,aint 指针的引用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/69194.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

菜鸟教程《Python 3 教程》笔记(17):输入和输出

菜鸟教程《Python 3 教程》笔记&#xff08;17&#xff09; 17 输入和输出17.1 读取键盘输入17.2 读和写文件17.3 文件对象的方法17.3.1 read()、readline()、readlines() 17.3.2 tell()17.3.3 seek()17.4 pickle 模块&#xff08;没看懂&#xff09; 笔记带有个人侧重点&#…

LeetCode 面试题 03.01. 三合一

文章目录 一、题目二、C# 题解 一、题目 三合一。描述如何只用一个数组来实现三个栈。 你应该实现push(stackNum, value)、pop(stackNum)、isEmpty(stackNum)、peek(stackNum)方法。stackNum表示栈下标&#xff0c;value表示压入的值。 构造函数会传入一个stackSize参数&#x…

Linux CentOS7 awk的反转功能

处理文本文件&#xff0c;经常会遇到反向输出的要求。 可用命令rev对待处理的文件或标准输入快速完成。 可用命令tac对文件快速完成反向查看。 而对行中字符串(单词)可借助其他命令达到反向输出的目标。 我们在文章《Linux CentOS7sed的替换及逆转功能》讨论了sed流编辑器对…

学习Bootstrap 5的第五天

目录 图像 图像形状 实例 对齐图像 实例 居中图像 实例 响应式图像 实例 Jumbotron 实例 图像 图像形状 .rounded 类可以用于为图像或任何具有边框的元素添加圆角。这个类适用于Bootstrap的所有版本&#xff0c;并且在最新版本中得到了进一步的增强。 实例 <…

CS420 课程笔记 P6 - 游戏逆向中的虚拟内存

文章目录 IntroVirtual memoryExample!Static example Intro 在上个视频中&#xff0c;我们知道有些地址在你重进游戏时就会无效&#xff0c;有的有时有效&#xff0c;我们需要了解称为虚拟内存的东西 记住这些信息&#xff1a;当你双击打开 Squally.exe 游戏时&#xff0c;系…

在C语言中,指针和函数指针是两个不同的概念

指针&#xff1a;指针是一个变量&#xff0c;其值为另一个变量的地址&#xff0c;即&#xff0c;内存位置的直接地址。我们可以通过这个指针来访问该地址存储的值 int a 10; int *p; p &a; // p存储了变量a的地址 printf("%d", *p); // 这会打印出10…

C# winform控件和对象双向数据绑定

实现目的&#xff1a; 控件和对象双向数据绑定 实现结果&#xff1a; 1. 对象值 -> 控件值 2. 控件值 -> 对象值 using System; using System.Windows.Forms;namespace ControlDataBind {public partial class MainForm : Form{People people new People();public Mai…

JVM的故事——虚拟机类加载机制

虚拟机类加载机制 文章目录 虚拟机类加载机制一、概述二、类加载的时机三、类加载的过程四、类加载器 一、概述 本章将要讲解class文件如何进入虚拟机以及虚拟机如何处理这些class文件。Java虚拟机把class文件加载到内存&#xff0c;并对数据进行校验、转换解析和初始化&#…

KMP超高效匹配算法

简介&#xff1a; KMP算法是一种改进的字符串匹配算法&#xff0c;其中&#xff0c;KMP算法的运用核心是利用匹配失败后的信息&#xff0c;最大进度的减少模式串与目标串的匹配次数以达到快速匹配的效果。算法与暴力求解的改进在于每当一趟匹配过程中出现的字符比较不相等时&am…

2023开学礼中国海洋大学《乡村振兴战略下传统村落文化旅游设计》许少辉新海洋图书馆

2023开学礼中国海洋大学《乡村振兴战略下传统村落文化旅游设计》许少辉新海洋图书馆

SOME/IP TTL 在各种Entry 中各是什么意思?有什么限制?

1 服务发现 SOME/IP SD 服务发现主要用于 定位服务实例检测服务实例状态是否在运行发布/订阅行为管理SOME/IP SD 也是 SOME/IP 消息,遵循 SOME/IP 消息格式,有固定的 Message ID、Request ID 以及 Message Type 等。并对 SOME/IP Payload 进行了详细的定义。 SOME/IP SD …

面试中的自我介绍:首印象决定一切

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

【网络安全带你练爬虫-100练】第21练:批量获取文件夹中文件名

目录 一、目标1&#xff1a;使用python爬取指定文件夹中的文件名 二、目标2&#xff1a;在文件夹指定目录打开命令行 一、目标1&#xff1a;使用python爬取指定文件夹中的文件名 方法一&#xff1a;使用os模块 将/path/to/folder替换为实际的文件夹路径。os.listdir()函数用…

D359周赛复盘:贪心解决求最小和问题⭐⭐+较为复杂的双层线性DP⭐⭐

文章目录 2828.判别首字母缩略词完整版 2829.k-avoiding数组的最小总和&#xff08;贪心解法&#xff09;思路完整版 类似题&#xff1a;2834.找出美丽数组的最小和思路完整版 2830.销售利润最大化⭐⭐思路DP数组含义递推公式 完整版 2828.判别首字母缩略词 给你一个字符串数组…

大数据系列教程之 Kafka基础

kafka概述 一、kafka概述 1.1 定义1.2 消息队列 1.2.1 传统消息队列的应用场景1.2.2 消息队列的两种形式1.3 Kafka 基础架构二、kafka安装部署 2.1安装部署 2.1.1.jar包下载2.1.2.解压到指定的文件夹下2.1.3.创建两个文件夹以供后续使用2.1.4. 修改配置文件 &#xff08;1&…

C语言基础之——结构体

前言&#xff1a;小伙伴们又见面啦&#xff0c;那么本篇文章&#xff0c;我们就将对C语言基础知识的最后一个章节——结构体展开讲解。 世上无难事&#xff0c;只要肯攀登&#xff01; 目录 一.什么是结构体 二.结构体讲解 1.结构体的声明和变量的定义 2.结构体成员的类型…

【Linux】多线程2——线程互斥与同步/多线程应用

文章目录 1. 线程互斥1.1 问题引入1.2 线程互斥的相关概念1.3 互斥量mutex1.4 互斥量实现原理1.5 死锁 2. 线程安全和可重入函数3. 线程同步3.1 同步概念3.2 条件变量 4. 生产消费模型4.1 基于阻塞队列的cp模型4.2 基于环形队列的cp模型POSIX信号量 5. 线程池5.1 互斥量RAII版本…

Mybatis中的关系映射

1.一对一的映射关系 一对一关系&#xff08;One-to-One&#xff09;表示两个实体对象之间存在唯一的关联关系。例如&#xff0c;一个学生只能拥有一个身份证。在 MyBatis 中&#xff0c;我们可以使用结果嵌套或一对一映射来处理一对一关系。 1.1 创建模型类和Vo类 package com…

Vue中启动提示polyfill缺少-webpack v5版本导致

安装 npm i node-polyfill-webpack-plugin 因为我们的项目使用webpack v5&#xff0c;其中polyfill Node核心模块被删除。所以&#xff0c;我们安装它是为了在项目中访问这些模块 vue.config.js文件 const { defineConfig } require("vue/cli-service"); const No…

二叉树的介绍

写在前面&#xff1a; 二叉树是数据结构课程中非常重要的内容&#xff0c;我们针对二叉树的概念、性质以及类型展开详细介绍。 一、概念 二叉树&#xff08;Binary Tree&#xff09;是n&#xff08;n>0&#xff09;个结点的有限集合&#xff0c;该集合或者空集&#xff0…