IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++ 变量 (variable) 初始化 - 赋值 - 声明 - 定义 -> 正文阅读

[C++知识库]C++ 变量 (variable) 初始化 - 赋值 - 声明 - 定义

C++ 变量 (variable) 初始化 - 赋值 - 声明 - 定义

变量提供一个具名的、可供程序操作的存储空间。C++ 中的每个变量都有其数据类型,数据类型决定着变量所占内存空间的大小和布局方式、该空间能存储的值的范围,以及变量能参与的运算。对 C++ 程序员来说 变量 (variable)对象 (object) 一般可以互换使用。

1. 变量定义

变量定义的基本形式是:首先是 类型说明符 (type specifier),随后紧跟由一个或多个变量名组成的列表,其中变量名以逗号分隔,最后以分号结束。列表中每个变量名的类型都由类型说明符指定,定义时还可以为一个或多个变量赋初值:

/* yong、value 和 qiang 都是 int。 */
/* yong 和 qiang 的初值为 0。 */
int yong = 0, value, qiang = 0;

/* item 的类型是 Sales。 */
Sales item;

/* string 表示一个可变长的字符序列。初始化 string 对象,把字面值拷贝给 string 对象。 */
std::string book("yongqiang");

string 在命名空间 std 中定义,string 是一种表示可变长字符序列的数据类型。

1.1 对象 (object)

通常情况下,对象是指一块能存储数据并具有某种类型的内存空间。

1.2 初始值

当对象在创建时获得了一个特定的值,我们说这个对象被初始化 (initialized) 了。用于初始化变量的值可以是任意复杂的表达式。因此在同一条定义语句中,可以用先定义的变量值去初始化后定义的其他变量。

/* price 先被初始化为 99.99,随后被用于初始化 discount。 */
double price = 99.99, discount = price * 0.16;

/* 调用函数 YongQiang,然后用函数的返回值初始化 sale_price。 */
double sale_price = YongQiang(price, discount);

在 C++ 语言中,初始化和赋值是两个完全不同的操作。初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而以一个新值来替代。

1.3 列表初始化

C++ 语言定义一个名为 yongqiang 的 int 变量并初始化为 0。

	int yongqiang1 = 0;
	int yongqiang2 = { 0 };
	int yongqiang3{ 0 };
	int yongqiang4(0);

用花括号来初始化变量的形式被称为列表初始化 (list initialization)。当用于内置类型的变量时,这种初始化形式有一个重要特点:如果我们使用列表初始化且初始值存在丢失信息的风险,则编译器将报错:

//============================================================================
// Name        : Yongqiang Cheng
// Author      : Yongqiang Cheng
// Version     : Version 1.0.0
// Copyright   : Copyright (c) 2020 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>

int main()
{
	long double yq = 3.1415926536;

	// 错误:转换未执行,存在丢失信息的危险。
	int a{ yq }, b = { yq };

	//正确:转换执行,确实丢失信息。
	int c(yq), d = yq;

	return 0;
}

1>d:\visual_studio_workspace\...\yongqiang.cpp(16): error C2397: conversion from 'long double' to 'int' requires a narrowing conversion
1>d:\visual_studio_workspace\...\yongqiang.cpp(19): warning C4244: 'initializing': conversion from 'long double' to 'int', possible loss of data

使用 long double 的值初始化 int 变量时可能丢失数据,所以编译器拒绝了 a 和 b 的初始化请求。至少 yq 的小数部分会丢失掉,而且 int 也可能存不下 yq 的整数部分。

1.4 默认初始化

如果定义变量时没有指定初值,则变量被默认初始化 (default initialized),此时变量被赋予了默认值。

如果是内置类型的变量未被显式初始化,它的值由定义的位置决定。定义于任何函数体之外的变量被初始化为 0。定义在函数体内部的内置类型变量将不被初始化 (uninitialized)。一个未被初始化的内置类型变量的值是未定义的,如果试图拷贝或以其他形式访问此类值将引发错误。

每个类各自决定其初始化对象的方式。是否允许不经初始化就定义对象也由类自己决定。如果类允许这种行为,它将决定对象的初始值到底是什么。绝大多数类都支持无须显式初始化而定义对象,这样的类提供了一个合适的默认值。string 类规定如果没有指定初值则生成一个空串:

	/* empty 非显式地初始化为一个空串。 */
	std::string empty;

	/* 被默认初始化的 Sales 对象。 */
	Sales item;

一些类要求每个对象都显式初始化,此时如果创建了一个该类的对象而未对其做明确的初始化操作,将引发错误。

定义于函数体内的内置类型的对象如果没有初始化,则其值未定义。类的对象如果没有显式地初始化,则其值由类确定。

未初始化的变量含有一个不确定的值,使用未初始化变量的值是一种错误的编程行为并且很难调试。尽管大多数编译器都能对一部分使用未初始化变量的行为提出警告,但严格来说,编译器并未被要求检查此类错误。

建议初始化每一个内置类型的变量。虽然并非必须这么做,但如果我们不能确保初始化后程序安全,那么这么做不失为一种简单可靠的方法。

2. 变量声明和定义

C++ 语言支持分离式编译 (separate compilation) 机制,该机制允许将程序分割为若干个文件,每个文件可被独立编译。如果将程序分为多个文件,则需要有在文件间共享代码的方法。std::cout 和 std::cin,它们定义于标准库,却能被我们写的程序使用。

为了支持分离式编译,C++ 语言将声明和定义区分开来。声明 (declaration) 使得名字为程序所知,一个文件如果想使用别处定义的名字则必须包含对那个名字的声明。而定义 (definition) 负责创建与名字关联的实体。变量声明规定了变量的类型和名字,在这一点上定义与之相同。但是除此之外,定义还申请存储空间,也可能会为变量赋一个初始值。

如果想声明一个变量而非定义它,就在变量名前添加关键字 extern,而且不要显式地初始化变量。

	extern int i;  // 声明 i 而非定义 i。
	int j;  // 声明并定义 j。

任何包含了显式初始化的声明即成为定义。我们能给由 extern 关键字标记的变量赋一个初始值,但是这么做也就抵消了 extern 的作用。extern 语句如果包含初始值就不再是声明,而变成定义了:

	/* 定义 */
	extern double pi = 3.1416;

在函数体内部,如果试图初始化一个由 extern 关键字标记的变量,将引发错误。变量能且只能被定义一次,但是可以被多次声明。

声明和定义的区别看起来也许微不足道,但实际上却非常重要。如果要在多个文件中使用同一个变量,就必须将声明和定义分离。此时,变量的定义必须出现在且只能出现在一个文件中,而其他用到该变量的文件必须对其进行声明,却绝对不能重复定义。

2.1 静态类型

C++ 是一种静态类型 (statically typed) 语言,其含义是在编译阶段检查类型。其中,检查类型的过程称为类型检查 (type checking)。对象的类型决定了对象所能参与的运算。在C++语言中,编译器负责检查数据类型是否支持要执行的运算,如果试图执行类型不支持的运算,编译器将报错并且不会生成可执行文件。

References

(美) Stanley B. Lippman, (美) Josée Lajoie, (美) Barbara E. Moo 著, 王刚, 杨巨峰 译. C++ Primer 中文版[M]. 第 5 版. 电子工业出版社, 2013.
https://www.informit.com/store/c-plus-plus-primer-9780321714114

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-14 13:50:50  更:2021-08-14 13:51:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 4:48:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码