C++ Primer 第二章 变量和基本类型

news2024/12/24 9:34:47

C++ Primer 第二章 变量和基本类型

  • 2.1. Primitive Built-in Types
    • 2.1.1. Arithmetic Types
    • 2.1.3. Literals
  • 2.2 Variables
    • 2.2.1. Variable Definitions
      • Initializers
      • List Initialization
      • Default Initialization
    • 2.2.2. Variable Declarations and Definitions
      • 2.2.3. Identifiers
  • 2.3. Compound Types
    • 2.3.1. References
    • 2.3.2. Pointers
  • 2.4. const Qualifier
    • 2.4.1. References to const
    • 2.4.2. Pointers and const
    • 2.4.3. Top-Level const
    • 2.4.4. constexpr and Constant Expressions
      • Constexpr Variables
      • Pointers and constexpr
  • 2.5. Dealing with Types
    • 2.5.1. Type Aliases
      • typedef
      • using
      • Pointers, const, and Type Aliases
    • 2.5.2. The auto Type Specifier
    • 2.5.3. The decltype Type Specifier

2.1. Primitive Built-in Types

2.1.1. Arithmetic Types

  • Integral types
    1

  • Floating-point types

2.1.3. Literals

A value, such as 42, is known as a literal because its value self-evident. Every literal has a type.

  • Integer Literals

    • decimal
      such as 20,30
      By default, decimal literals are signed.
      A decimal literal has the smallest type of int, long, or long long in which the literal’s value fits.
    • octal
      Octal literals begin with 0 (zero), such as 024
      Octal literals can be either signed or unsigned types.
      Octal literals have the smallest type of int, unsigned int, long, unsigned long, long long, or unsigned long long in which the literal’s value fits.
    • hexadecimal
      Hexadecimal literals begin with either 0x or 0X, such as 0x14
      Hexadecimal literals can be either signed or unsigned types.
      Hexadecimal literals have the smallest type of int, unsigned int, long, unsigned long, long long, or unsigned long long in which the literal’s value fits.
  • Floating-Point literals
    Floating-point literals include either a decimal point or an exponent specified using
    scientific notation
    .
    Using scientific notation, the exponent is indicated by either E or e.
    By default, floating-point literals have type double.
    2.1,2.1E0,0.,0e0,.001

  • Character and Character String Literals

    • char
      ‘a’
    • string
      “a”, “hello world!”
      The compiler appends a null character (’\0’) to every string literal.
  • Escape Sequences
    We use an escape sequence as if it were a single character.
    2

    • \ followed by one, two or three octal digits
      The value represents the numerical value of the character.
      If a \ is followed by more than three octal digits, only the first three are associated with the . \1234 represents two characters: octal value 123 and character 4.
    • \x followed by one or more hexadecimal digits
      3
  • Specifying the Type of a Literal
    4

  • Boolean and Pointer Literals


5

  • There are no literals of type short.
  • The value of a decimal literal is never a negative number.
    对于 -42 来说,负号不是 literal 的一部分。

2.2 Variables

A variable provides us with named storage that our programs can manipulate.

2.2.1. Variable Definitions

Variable Definitions: A simple variable definition consists of a type specifier, followed by a list of one or more variable names separated by commas, and ends with a semicolon.

Initializers

An object that is initialized gets the specified value at the moment it is created.

// ok: price is defined and initialized before it is used to initialize discount
double price = 109.99, discount = price * 0.16;
// ok: call applyDiscount and use the return value to initialize salePrice
double salePrice = applyDiscount(price, discount);

Warning: Initialization is not assignment.
Initialization happens when a variable is given a value when it is created.

Assignment obliterates an object’s current value and replaces that value with a new one.

List Initialization

The language defines several different forms of initialization:

int units_sold = 0;
int units_sold = {0};
int units_sold{0};
int units_sold(0);

The generalized use of curly braces for initialization is referred to as list initialization.

The compiler will not let us list initialize variables of built-in type if the initializer might lead to the loss of information:

long double ld = 3.1415926536;
int a{ld}, b = {ld}; // error: narrowing conversion required
int c(ld), d = ld; // ok: but value will be truncated

Default Initialization

When we define a variable without an initializer, the variable is default initialized.

The value of an object of built-in type that is not explicitly initialized depends on where it is defined.

  • Variables defined outside any function body are initialized to zero.

  • Variables of built-in type defined inside a function are uninitialized.
    It is an error to copy or otherwise try to access the value of a variable whose value is undefined.

Objects of class type that we do not explicitly initialize have a value that is defined by the class.

不同初始化方法:
Is there a difference between copy initialization and direct initialization?
Different forms of initialization
Initialization of variables
Initializers

2.2.2. Variable Declarations and Definitions

To support separate compilation, C++ distinguishes between declarations and definitions.

A declaration makes a name known to the program. A file that wants to use a name defined elsewhere includes a declaration for that name.

A definition creates the associated entity.

A variable declaration specifies the type and name of a variable.

A variable definition is a declaration. In addition to specifying the name and type, a definition also allocates storage and may provide the variable with an initial value.

To obtain a declaration that is not also a definition, we add the extern keyword and may not provide an explicit initializer:

extern int i; // declares but does not define i
int j; // declares and defines j  !!!!

Note:
Variables must be defined exactly once but can be declared many times.

To use a variable in more than one file requires declarations that are separate from the variable’s definition.
To use the same variable in multiple files, we must define that variable in one—and only one—file. Other files that use that variable must declare—but not define—that variable.

Difference between declaration and definition:
What is the difference between a definition and a declaration?
What is the difference between declaration and definition of a variable in C++?
Declare vs Define in C and C++
The differences between initialize, define, declare a variable


C++ is a statically typed language, which means that types are checked at compile time.

The type of every entity we use must be known to the compiler.

As one example, we must declare the type of a variable before we can use that variable.

2.2.3. Identifiers

  • Identifiers in C++ can be composed of letters, digits, and the underscore character.
  • The language imposes no limit on name length.
  • Identifiers must begin with either a letter or an underscore.
  • Identifiers are case-sensitive.

1

2.3. Compound Types

A compound type is a type that is defined in terms of another type.

2.3.1. References

  • There is no way to rebind a reference to refer to a different object.
  • References must be initialized.
  • A reference is not an object. Instead, a reference is just another name for an already existing object.
    1

2.3.2. Pointers

  • Like other built-in types, pointers defined at block scope have undefined value if they are not initialized.
  • void* Pointers
    The type void* is a special pointer type that can hold the address of any object.

2.4. const Qualifier

  • Because we can’t change the value of a const object after we create it, it must be initialized.
  • The compiler will usually replace uses of the variable with its corresponding value during compilation.
  • By Default, const objects are local to a file.
  • To share a const object among multiple files, you must define the variable as extern.
    1

2.4.1. References to const

const Reference is a Reference to const.

int i = 42;
const int &r1 = i; // we can bind a const int& to a plain int object
const int &r2 = 42; // ok: r2 is a reference to const
const int &r3 = r1 * 2; // ok: r3 is a reference to const
int &r4 = r1 * 2; // error: r4 is a plain, non const reference

Two exceptions to the rule that the type of a reference must match the type of the object to which it refers:

  1. We can initialize a reference to const from any expression that can be converted to the type of the reference.
double dval = 3.14;
const int &ri = dval;

To ensure that the object to which ri is bound is an int, the compiler transforms this code into something like:

const int temp = dval; // create a temporary const int from the double
const int &ri = temp; // bind ri to that temporary

In this case, ri is bound to a temporary object. A temporary object is an unnamed object created by the compiler when it needs a place to store a result from evaluating an expression.

  1. A Reference to const May Refer to an Object That Is Not const

It is important to realize that a reference to const restricts only what we can do through that reference.

int i = 42;
int &r1 = i; // r1 bound to i
const int &r2 = i; // r2 also bound to i; but cannot be used to change i
r1 = 0; // r1 is not const; i is now 0
r2 = 0; // error: r2 is a reference to const

2.4.2. Pointers and const

const double pi = 3.14; // pi is const; its value may not be changed
double *ptr = π // error: ptr is a plain pointer
const double *cptr = π // ok: cptr may point to a double that is const
*cptr = 42; // error: cannot assign to *cptr

There are two exceptions to the rule that the types of a pointer and the object to which it points must match:

  1. We can use a pointer to const to point to a nonconst object

  2. Unlike references, pointers are objects

Hence, as with any other object type, we can have a pointer that is itself const.

int errNumb = 0;
int *const curErr = &errNumb; // curErr will always point to errNumb
const double pi = 3.14159;
const double *const pip = π // pip is a const pointer to a const object

2.4.3. Top-Level const

We use the term top-level const to indicate that the pointer itself is a const.

When a pointer can point to a const object, we refer to that const as a low-level const.

int i = 0;
int *const p1 = &i; // we can't change the value of p1; const is top-level
const int ci = 42; // we cannot change ci; const is top-level
const int *p2 = &ci; // we can change p2; const is low-level
const int *const p3 = p2; // right-most const is top-level, left-most is not
const int &r = ci; // const in reference types is always low-level

When we copy an object, top-level consts are ignored:

On the other hand, low-level const is never ignored.

In general, we can convert a nonconst to const but not the other way round:


  • int const * , const int * and int *const
    What is the difference between const int*, const int * const, and int const *?
    website to auto-translates C declarations
    Clockwise/Spiral Rule
int const *p; // declare p as pointer to const int
const int *p; // same as int const * p
int * const p; // declare p as const pointer to int 

2.4.4. constexpr and Constant Expressions

  • A constant expression is an expression whose value cannot change and that can be evaluated at compile time.

  • A literal is a constant expression.

  • A const object that is initialized from a constant expression is also a constant expression.

const int max_files = 20; // max_files is a constant expression
const int limit = max_files + 1; // limit is a constant expression
int staff_size = 27; // staff_size is not a constant expression
const int sz = get_size(); // sz is not a constant expression

Constexpr Variables

Variables declared as constexpr are implicitly const and must be initialized by constant expressions:

constexpr int mf = 20; // 20 is a constant expression
constexpr int limit = mf + 1; // mf + 1 is a constant expression
constexpr int sz = size(); // ok only if size is a constexpr function

We can use constexpr functions in the initializer of a constexpr variable.

Variables defined inside a function ordinarily are not stored at a fixed address. Hence, we cannot use a constexpr pointer to point to such variables.

On the other hand, the address of an object defined outside of any function is a constant expression, and so may be used to initialize a constexpr pointer.

Pointers and constexpr

It is important to understand that when we define a pointer in a constexpr declaration, the constexpr specifier applies to the pointer, not the type to which the pointer points:

const int *p = nullptr; // p is a pointer to a const int
constexpr int *q = nullptr; // q is a const pointer to int

2.5. Dealing with Types

2.5.1. Type Aliases

A type alias is a name that is a synonym for another type.

typedef

typedef double wages; // wages is a synonym for double
typedef wages base, *p; // base is a synonym for double, p for double*

using

using SI = Sales_item; // SI is a synonym for Sales_item

Pointers, const, and Type Aliases

typedef char *pstring;
const pstring cstr = 0; // cstr is a constant pointer to char
const pstring *ps; // ps is a pointer to a constant pointer to char

The base type in these declarations is const pstring.

The type of pstring is “pointer to char.” So, const pstring is a constant pointer to char—not a pointer to const char.

const char *cstr = 0; // wrong interpretation of const pstring cstr

2.5.2. The auto Type Specifier

  1. auto tells the compiler to deduce the type from the initializer.

  2. By implication, a variable that uses auto as its type specifier must have an initializer:

  3. As with any other type specifier, we can define multiple variables using auto.

auto i = 0, *p = &i; // ok: i is int and p is a pointer to int
auto sz = 0, pi = 3.14; // error: inconsistent types for sz and pi
  1. The type that the compiler infers for auto is not always exactly the same as the initializer’s type. Instead, the compiler adjusts the type to conform to normal initialization rules.
  • using a reference
int i = 0, &r = i;
auto a = r; // a is an int (r is an alias for i, which has type int)
  • auto ordinarily ignores top-level consts
    As usual in initializations, low-level consts, such as when an initializer is a pointer to const, are kept.
    When we ask for a reference to an auto-deduced type, top-level consts in the initializer are not ignored.
    As usual, consts are not top-level when we bind a reference to an initializer.
const int ci = i, &cr = ci;
auto b = ci; // b is an int (top-level const in ci is dropped)
auto c = cr; // c is an int (cr is an alias for ci whose const is top-level)
auto d = &i; // d is an int*(& of an int object is int*)
auto e = &ci; // e is const int*(& of a const object is low-level const)
const auto f = ci; // deduced type of ci is int; f has type const int
auto &g = ci; // g is a const int& that is bound to ci
auto &h = 42; // error: we can't bind a plain reference to a literal
const auto &j = 42; // ok: we can bind a const reference to a literal
auto k = ci, &l = i; // k is int; l is int&
auto &m = ci, *p = &ci; // m is a const int&;p is a pointer to const int
// error: type deduced from i is int; type deduced from &ci is const int
auto &n = i, *p2 = &ci;

2.5.3. The decltype Type Specifier

  • decltype returns the type of its operand.

  • The compiler analyzes the expression to determine its type but does not evaluate the expression.

  • When the expression to which we apply decltype is a variable, decltype returns the type of that variable, including top-level const and references.
    It is worth noting that decltype is the only context in which a variable defined as a reference is not treated as a synonym for the object to which it refers.

const int ci = 0, &cj = ci;
decltype(ci) x = 0; // x has type const int
decltype(cj) y = x; // y has type const int& and is bound to x
decltype(cj) z; // error: z is a reference and must be initialized
  • When we apply decltype to an expression that is not a variable, we get the type that that expression yields.
// decltype of an expression can be a reference type
int i = 42, *p = &i, &r = i;
decltype(r + 0) b; // ok: addition yields an int; b is an (uninitialized) int
decltype(*p) c; // error: c is int& and must be initialized

Here r is a reference, so decltype(r) is a reference type. If we want the type to which r refers, we can use r in an expression, such as r + 0, which is an expression that yields a value that has a nonreference type.

  • The dereference operator is an example of an expression for which decltype returns a reference.
    The type deduced by decltype(*p) is int&, not plain int.

  • When we apply decltype to a variable without any parentheses, we get the type of that variable.

  • If we wrap the variable’s name in one or more sets of parentheses, the compiler will evaluate the operand as an expression.
    A variable is an expression that can be the left-hand side of an assignment.
    decltype((variable)) (note, double parentheses) is always a reference type, but decltype(variable) is a reference type only if variable is a reference.
    As a result, decltype on such an expression yields a reference:

// decltype of a parenthesized variable is always a reference
decltype((i)) d; // error: d is int& and must be initialized
decltype(i) e; // ok: e is an (uninitialized) int

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

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

相关文章

set系列集合、collection集合的总结

无序 不重复 无索引 HashSet 元素无序的底层原理:哈希表: JDk1.7之前: JDK1.8之后: 总结: HashSet 元素去重复的底层原理: 因为传入的参数值一样,所以重写之后的hashcode方法所给出的哈希值是…

开科唯识冲刺创业板:年营收3.7亿 红杉奕信是二股东

雷递网 雷建平 12月19日北京开科唯识技术股份有限公司(简称:“开科唯识”)日前递交招股书,准备在深交所创业板上市。开科唯识计划募资8亿元,其中,3.19亿用于开科唯识智能财富管理及投研一体化平台建设项目&…

怎样使用Odoo 16 实现多公司管理

专业人士面临的最具挑战性的任务之一是在同一系统内管理多家公司。我们希望在浏览产品时不从一家公司切换到另一家公司。母公司下各公司的集中管理制定了多公司方法。一个组织由多个地点的分支机构组成,而母公司管理他分支机构的产品列表。母公司的每个分支机构都使…

[附源码]Python计算机毕业设计Django医院挂号住院管理系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

后端必知:遵循Google Java规范并引入checkstyle检查

IDEA配置Code Style 协同工作时,为了保证统一的代码风格,要求我们使用的规范,如果大家都用的是 IDEA,则推荐使用 Google Code Style,推荐阅读Google Java 编程风格中文文档。 先下载配置文件:github.com/…

牛客竞赛每日俩题 - Day10

目录 输入输出的细节 函数find()的用法 输入输出的细节 收件人列表__牛客网 细节一:当输入转行后又要使用getline()时,必须先使用getchar()吃掉前面的转行符\n;细节二&#xff1a…

介绍一个助你事半功倍的数据挖掘神器!!

在Pandas模块当中,对于表格数据的分组操作(groupby)和透视表(pivot_table)的制作一直都是比较常见的,今天小编为大家分享一个数据分析的利器,能够自动为我们完成上述提到的一系列操作&#xff0…

arcgis读取NetCDF格式的数据(c#读取数据)

项目里面要用到降雨的数据,正好是.NC格式的,以前也没用过,正好记录下,大家也可以参考下,首先是arcgis是如何处理NC数据的,在arcgis软件里面有个多维工具箱,我用的是汉化版本的,英文版…

[附源码]计算机毕业设计Python的剧本杀管理系统(程序+源码+LW文档)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等…

Verilog 简易单周期CPU

目录 本实验包含: 简易结构图: 各部件代码或实现: 控制器: 寄存器堆: ALU: 数据存储器: 指令存储器: CPU: tp(仿真文件): 仿真…

如何去掉idea的诸多警告

File->setting->Editor->inspections 选择漏斗,选中warning,筛选出所有警告级别,然后去掉勾选,然后重启idea即可

重构物理Entity架构,支持更多的形状

上一节实战如何编译BEPUphysicsint源码到自己的项目, 如何整合物理引擎与Unity图形渲染。本节来从新调整设计,让物理的Entity基本操作与物理的形状分离,支持更多的物理形状,支持物理entity与Unity物体位移与旋转同步。主要分成以下3个部分: 1: 设计PhyBaseEntity,让…

学到一招!PyCharm连接MySQL竟如此简单!

在 PyCharm 中是可以通过内置的工具来连接、操作数据库的,并且对于市面上大多数主流数据库都是支持的。 连接 MySQL 首先打开 PyCharm ,点击菜单栏的 View --> Tool Windows --> Database 或者直接点击 PyCharm 右侧的 Database 然后就会在 PyCh…

【QT开发笔记-基础篇】| 第五章 绘图QPainter | 5.6 矩形、圆角矩形

本节对应的视频讲解:B_站_视_频 https://www.bilibili.com/video/BV1mg411J7u5 本节讲解如何绘制矩形、圆角矩形 1. 相关的 API 直接查看官方的帮助文档,可以看到有多个重载的方法用于绘制矩形、圆角矩形 1.1 矩形 // 带 F 表示参数为浮点数&#x…

【电商】电商系统---合同管理

说一下合同管理部分,希望对大家有帮助,如果大家觉得简单可以直接略过,谢谢! 合同分类 合同主要分为采购类合同、销售类合同、其他合同。 采购合同和销售合同分别与采购订单和销售订单建立对应关系,通过采购订单和销售…

ChatGDP:人类未来世界的主宰

先简单介绍一下今天的主角——ChatGPT。 ChatGPT是一款由OpenAI开发的聊天机器人,它具有出色的自然语言处理能力,能够与人类进行真实的对话。它的核心技术是GPT-3语言模型,能够自动学习语言特征,并进行语义理解、文本生成等任务。…

HCL与Pipe、Autoit和MobaXterm的组合使用

我们平时做实验一般会用到真机或者是模拟器,因为我主要接触的都是一些H3C的产品和技术,所以模拟器用HCL会多一些。为了呈现出相对好一些的视觉效果,我一般会使用MobaXterm工具进行命令操作,所以大家看到的回显一般是这样的&#x…

哈工大视听觉信号处理——听觉部分报告——一种智能家居命令词识别系统的设计

题 目 听觉部分 专 业 软件工程 学   号 120L0219XX 班   级 2037101 姓 名 李启明 报 告 日 期 2022.12.20 一、基频 (一&#xff…

肝了一周总结的SpringBoot常用注解大全,一目了然~

平时使用SpringBoot开发项目,少不了要使用到它的注解。这些注解让我们摆脱了繁琐的传统Spring XML配置,让我们开发项目更加高效,今天我们就来聊聊SpringBoot中常用的注解! SpringBoot实战电商项目mall(50kstar&#xf…

《c专家编程》读书笔记

《c专家编程》第一章 C:穿越时空的迷雾第二章 这不是Bug,而是语言特性gets实验第三章 分析C语言的声明const实验第四章 令人震惊的事实:数组和指针并不相同指针与数组实验第五章 对链接的思考简单静态库动态库实验第六章 运动的诗章&#xff…