c++教程(三:Variables and types)

————————————————————————

该系列教程为翻译c++官方教程,点击参考英文原版,水平有限,翻译不通之处敬请谅解!

————————————————————————

变量与类型

上一章的“Hello world”工程的实际用途是相当值得怀疑的。我们只是写几行代码,编译它们,然后执行所产生的程序,只是为了将一个简单的句子写在屏幕上。相对于输入输出句子本身,它当然会很快。

然而,编程并不局限于只在屏幕上打印简单的文本。为了进一步的深入,并能够编写程序,执行有用的任务,真正节省我们的工作,我们需要引入变量的概念。

让我们想象一下,我让你记住数字5,同时也让你记住数字2。你已经在内存中存储了2个不同的数值(5和2)。现在,如果我要你把第一个数字加1,你现在应该保留数字6(即1 + 5)和2在内存中。当然,比如我们也可以再让这两个数相减,得到4这个结果。

上述整个过程是一个就好比计算机能够处理两个变量。同样的过程在C++下可以表示下列语句:

a = 5;
b = 2;
a = a + 1;
result = a - b;

很显然,这是一个非常简单的例子,因为我们只使用了2个小的整型值,但是考虑到你的计算机可以存储上百万的数字,同时也进行复杂的数学运算。

现在我们可以分配一块内存来定义一个变量。

每个变量都需要一个标识它的名称,并将其与其他变量区分开来。例如,在前面的代码中的变量名是a,b,和result,我们可以将变量定义为任何我们能想出的名字,只要他们是有效的C++标识符。

标识符

一个有效的标识符是一个或多个字母、数字或下划线字符(_ )的序列组合。空格、标点符号和符号不能是一个标识符的一部分。此外,标识符必须始终以一个字母开头。他们也有以下划线字符(_ )开始的,但这样的标识符,在大多数情况下是留给编译器特定的关键词或外部标识符,以及含有两个连续的下划线字符的任何标识符。在任何情况下,他们可以从一个数字开始。

C++中使用了大量的关键词来帮助识别操作和数据描述;因此,由程序员不能创建和这些标识符名称相同的变量。不能用于程序员创建标识符的标准保留关键字有:

alignas, alignof, and, and_eq, asm, auto, bitand, bitor, bool, break, case, catch, char, char16_t, char32_t, class, compl, const, constexpr, const_cast, continue, decltype, default, delete, do, double, dynamic_cast, else, enum, explicit, export, extern, false, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, noexcept, not, not_eq, nullptr, operator, or, or_eq, private, protected, public, register, reinterpret_cast, return, short, signed, sizeof, static, static_assert, static_cast, struct, switch, template, this, thread_local, throw, true, try, typedef, typeid, typename, union, unsigned, using, virtual, void, volatile, wchar_t, while, xor, xor_eq

特定的的编译器也可能有额外的特定的保留关键字。

非常重要:C++语言是一种“敏感的”语言。这意味着一个用大写字母写的标识符不等于另一个用小写字母写的相同名字的标识符。所以,例如,变量RESULT与变量 result以及变量 Result 就是不同的。这是三个不同的标识符表示三个不同的变量。

基本数据类型

变量的值以0或1的形式存储在计算机内存中的某个位置。我们的程序并不需要知道一个变量储存的确切位置,它可以用它的名字来表示。程序需要知道的是变量在存储时的数据类型。存储一个简单的整型数和储存一个字母或一个更大的浮点数字所需要内存的大小是不一样的;即使它们都是以0或1在计算机中储存着,但是它们确是以不同的方式在程序中解释,并且在许多情况下,它们占用不同相同的内存。

基本数据类型是大多数系统本身支持的基本存储单元的语言实现的类型。它们主要可以分为:

(1)字符类型:他们用一个字符表示,如“A”或“$”。最基本类型为char,这是一个字节的字符。当然还提供了用于更广泛的其他类型字符。

(2)数值整数类型:它们可以存储整数值,例如7或1024,他们所占的内存大小各异,并且还取决于它们是否有负值或者是有符号或无符号的。

(3)浮点类型:它们可以代表一切实数值,例如3.14或0.01,浮点类型的不同所代表的精确度级别不同。

(4)布尔类型:布尔类型,在C++称为布尔(bool),只有两种状态,真的(True)或假的(False);

C++的基本数据类型表如下:

某些整数类型的名称可以用没有signed或者int的写法简短表示;上述图中只有部分没有斜体需要必须标识出来类型,而斜体部分是可选的。即signed short int可简写为signed short,short int,或者简单的short;他们都表示相同的基本类型。

在上述的每一个类型中,种类之间的差别仅是它们的大小(即,他们在存储器占用多少),各组中的第一种类型占用内存是最小的,而最后是最大的,每一种类型是后面的至少大于同一个组的前面的。除此之外,一组中的类型具有相同的其他属性。

在上面表格中,除了字符(确切的一个字节的大小),没有一个基本类型有一个标准的大小(但至少有一个最小的大小)。因此,类型有时候是不需要的(在许多情况下),因为有最小尺寸限制着。这并不意味着这些类型是一个不确定大小的类型,只是在不同的编译器和机器没有一个统一的标准,每个编译器可能根据自己的架构指定这些该程序在运行数据类型的大小。这种一般化的的大小规格类型规定使得C++语言有很大的灵活性,能够适应现在与未来各种平台的优化工作。

各种类型的大小定义如下,代表的数字范围越大,相应的需要的内存也就越多;

对于整数类型,表示的值越多,意味着他们可以代表的数就越大;例如,一个16位的无符号整数能够在范围0到65535代表了65536种不同的值,而其有符号的值在大多数情况下能够代表-32768和32767之间的值。注意与无符号类型的值相比,正值的表示范围是有符号的。因为是用一个16位来表示有符号的数;这是一个可以在完全符号类型的基础上表示一个范围上相对差异大的数据类型。

对于浮点类型,其大小会影响其精度,通过他们具有多少的位数来显式。

如果需要表示的一个类型的大小或精度都不要求的话,那么char,int或者一些常用的整型、浮点型都可以表示。在每个类型里其他类型仅在非常特殊的情况下使用。

在一个特定系统的基本类型,编译器实现的性能可以通过使用numeric_limits等级获得(见标准库 )。如果因为某些原因,需要具体尺寸类型,标准库定义了一定的固定大小类型别名头。

以上类型(characters,integers,浮点数,和布尔值)是已知的作为算术类型的数据类型。但还有两类其他的基础类型存在,void,表示标识缺乏类型;nullptr,这是一个特殊类型的指针。这些类型都将在后续章关于指针的时候谈到。

C++支持多种基于上述基本类型;这些类型被称为复合数据类型,这也是C++语言的主要优势。我们也将在未来的章节中看到更多的细节。

变量的声明:

C++是硬性的语言,并要求每个变量在第一次使用前一定要声明它的类型。这让编译器在内存中保留变量的大小,以及如何解释它的值。在C++的语法来声明一个新变量是简单的:我们只写类型与变量名(即它的标识符)。例如:

int a;
float mynumber;

上述声明了两个有效的变量类型,第一个声明一个int类型的变量a,第二个声明的float类型的mynumber。一旦声明,后面就可以在其他程序中使用该两个变量。

如果想要声明同一类型的多个变量,可以通过用逗号分隔的标识符在一个语句中声明。例如:

int a, b, c;

声明3个变量a、b、c,他们的类型相同,下面的方式和上面的效果相同:

int a;
int b;
int c;

看看变量声明在一个程序中是怎样的,让我们看看在文章开头的一个C++代码的例子:

// operating with variables
#include <iostream>
using namespace std;
int main ()
{
  // declaring variables:
  int a, b;
  int result;

  // process:
  a = 5;
  b = 2;
  a = a + 1;
  result = a - b;

  // print out the result:
  cout << result;

  // terminate the program:
  return 0;
}

不要担心,如果其他的变量声明看起来有点奇怪,大部分在未来的章节中会有更多的细节解释。

变量初始化:

当上面的变量被声明后,他们就有一个不确定的值,直到他们被分配一个值。但是,它可能在被声明的时候就有一个特定的值,这被称为变量的初始化。

在C++中,有三种方式来初始化变量。在多年的演化过程中,他们都是相当的;

第一个,称为C类初始化(因为它是从C语言继承),包括添加一个等号后面的值的变量来初始化:

type identifier = initial_value; 

例如,声明int类型的x变量,初始化为零,我们可以写:

int x = 0;

另一种方法,称为构造函数的初始化(介绍了C++语言),在括号中的初始化(()),比如:

int x (0);

最后,第三种方法,称为统一的初始化,和上面的类似,但是使用大括号({})而不是圆括号(这是由C++标准,修订2011介绍),比如:

int x {0};

上面三种类型的一个程序:

// initialization of variables
#include <iostream>
using namespace std;
int main ()
{
  int a=5;               // initial value: 5
  int b(3);              // initial value: 3
  int c{2};              // initial value: 2
  int result;            // initial value undetermined

  a = a + b;
  result = a - c;
  cout << result;

  return 0;
}

类型推断:auto和decltype

当一个新的变量被初始化,编译器可以由初始化自动给出变量的类型,这时,可以使用auto标识符定义变量的类型:

int foo = 0;
auto bar = foo;  // the same as: int bar = foo;

在这里,变量bar被声明为具有auto型;因此,bar的类型就是初始化它的值的类型:在这种情况下它使用foo的类型,也就是int.

没有初始化的变量也可以使用decltype说明符来间接推到变量的类型:

int foo = 0;
decltype(foo) bar;  // the same as: int bar;

在这里,bar被声明为具有foo相同的类型。

auto和decltype是最近添加到c++语言的强大功能。但使用类型推导功能一般用在类型无法确定或使用时能提高代码的可读性上。上面的两个例子没有用到这两个功能。事实上,他们可能会降低可读性,因为,阅读代码的时候,必须寻找找到bar对应的foo的类型才行。

字符串简介:

基本类型是计算机代码可以运行的最基本的类型。但C++语言的主要优势在于其丰富的复合类型,这时组成模块化的基石。

复合型的一个例子就是字符串类。该类型的变量可以存储字符序列,如单词或句子,这在c++中是一个非常有用的功能!

基本数据类型的一个差异是为了声明和使用对象(变量)这种类型,程序需要包含这种类型所在的标准库的头文件(头文件 < string >):

// my first string
#include <iostream>
#include <string>
using namespace std;
int main ()
{
  string mystring;
  mystring = "This is a string";
  cout << mystring;
  return 0;
}

前面的例子可以看到,字符串初始化可以是任何有效的字符串,就像数值类型的变量可以被初始化为任何有效的数值一样。与基本类型,下面所有的初始化格式都是有效的字符串初始化:

string mystring = "This is a string";
string mystring ("This is a string");
string mystring {"This is a string"};

字符串还可以执行所有的基本数据类型的基本操作,如可以不被初始值,也可以在执行过程中改变其值:

// my first string
#include <iostream>
#include <string>
using namespace std;
int main ()
{
  string mystring;
  mystring = "This is the initial string content";
  cout << mystring << endl;
  mystring = "This is a different string content";
  cout << mystring << endl;
  return 0;
}

注:插入endl是执行结束一行操作(打印一个换行符和一个输出流)。

String类是一种复合型类型。在上面的例子中可以看到,复合类型用于声明变量并初始化与基本类型相同的方式。

关于标准C++字符串的更多细节,参见string类的说明。

时间: 2024-08-03 08:33:16

c++教程(三:Variables and types)的相关文章

微信开放平台 公众号第三方平台开发 教程三 一键登录授权给第三方平台

原文:微信开放平台 公众号第三方平台开发 教程三 一键登录授权给第三方平台 教程导航: 微信开放平台 公众号第三方平台开发 教程一 平台介绍 微信开放平台 公众号第三方平台开发 教程二 创建公众号第三方平台 微信开放平台 公众号第三方平台开发 教程三 一键登录授权给第三方平台 微信开放平台 公众号第三方平台开发 教程四 代公众号调用接口的SDK和demo 公众号第三方平台的开放,是为了让公众号运营者,在面向垂直行业需求时,可以一键登录授权给第三方的公众号运营平台,通过第三方开发者提供的公众号第三

struts2 官方系列教程三:使用struts2 标签 tag

避免被爬,先贴上本帖地址:struts2 官方系列教程一:使用struts2 标签 tag http://www.cnblogs.com/linghaoxinpian/p/6901316.html 本教材假定你已完成了HelloWorld项目,你可以在 struts2 官方系列教程三:使用struts2 标签 tag 下载本章节的代码 在上一节教程中,我们在index.jsp中使用 url tag 创建了一个超链接hello.action 这节我们将探索struts2中其它tags Web应用程

Junit 4 Tutorials(Junit 4 教程) 三、Junit4 断言方法

Junit 4 断言方法允许检查测试方法的期望结果值和真实返回值.Junit的org.junit.Assert类提供了各种断言方法来写junit测试.这些方法被用来检查方法的真实结果值和期望值.下列一些有用的断言方法列表: Junit 4 Assert Methods Method Description assertNull(java.lang.Object object) 检查对象是否为空 assertNotNull(java.lang.Object object) 检查对象是否不为空 as

Swift中文教程(三)--流程控制

原文:Swift中文教程(三)--流程控制 Swift用if和switch编写条件控制语句,用for-in,for,while和do-while编写循环.条件控制语句和循环语句中,小括号是可选的,但花括号包住这个循环体是必须的: 1 let individualScores = [75, 43, 103, 87, 12] 2 var teamScore = 0 3 for score in individualScores { 4 if score > 50 { 5 teamScore += 3

Struts2.x教程(三) Struts2拦截器

一.Struts2拦截器介绍 Struts2拦截器是使用AOP实现的,主要是针对action对象进行拦截,可以在访问action的某个方法.字段之前或之后实施拦截. 可以为action配置多个拦截器,Struts2会将这一组拦截器按照一定顺序组织成一个拦截器栈.action可以直接引用某个拦截器栈来实现配置多个拦截器的目的. 对于继承struts_default的package中的action,都会默认引用name=defaultStack的拦截器栈(在struts_default中定义了Str

jQuery 入门教程(三): Selectors

jQuery Selector 是jQuery库中非常重要的一个组成部分. jQuery Selector 用来选择某个HTML元素,其基本语句和CSS的选择器(Selector)是一样的,所有jQuery selector 都是以$()开始. 选择HTML标记 选择某个HTML元素的方法是直接使用该元素的标记名称,比如选择所有<p>元素 $("p") 下面的例子当用户点击一个按钮时,隐藏所有的<p>元素 $(document).ready(function()

BootStrap入门教程 (三)

上讲回顾:Bootstrap的基础CSS(Base CSS)提供了优雅,一致的多种基础Html页面要素,包括排版,表格,表单,按钮等,能够满足前端工程师的基本要素需求. Bootstrap作为完整的前端工具集,内建了大量的强大优雅可重用的组件,包括按钮(Button),导航(Navigation),标签(Labels),徽章(Badges),排版(Typography),缩略图( thumbnails),提醒(Alert),进度条(progress bar),杂项(Miscellaneous).

CRL快速开发框架系列教程三(更新数据)

本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框架系列教程四(删除数据) CRL快速开发框架系列教程五(使用缓存) CRL快速开发框架系列教程六(分布式缓存解决方案) CRL快速开发框架系列教程七(使用事务) CRL快速开发框架系列教程八(使用CRL.Package) CRL快速开发框架系列教程九(导入/导出数据) CRL快速开发框架系列教程十(

Laravel教程 三:视图变量传递和Blade

Laravel教程 三:视图变量传递和Blade 此文章为原创文章,未经同意,禁止转载. Blade 上一篇我们简单地说了Router,Views和Controllers的工作流程,这一次我就按照上一篇的计划,来说说下面几个内容: 向视图中传递变量 Blade模板的用法 向视图中传递变量 我们在开发web应用当中,通常都不是为了写静态页面而生的,我们需要跟数据打交道,那么这个时候,问题就来了,在一个MVC的框架中,怎么将数据传给视图呢?比如我们要在 ArticleController 的 ind

Flask实例教程三

一:Flask中url的工作方式 # encoding=utf-8 from flask import Flask app = Flask(__name__) @app.route("/task/") def task_list():     return "List of all task" @app.route("/task/<int:task_id>/") def task_detail(task_id):     return