对我们程序员来讲,“变量”和“对象”是可以相互互换使用的。-------------开篇之词。

变量:提供一个具有名字的可供程序操作的存储空间。由类型说明符和其后紧跟的数个列表组成,其中变量名之间使用逗号分隔,最后使用分号结尾。像 int sum = 0,value,unit_sold = 0;Sales item;这里的item就是类型为Sales的变量。

对象:是指一块能够存储数据并且具有某种类型的内存空间。

初始化和赋值不是同一概念;初始化是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而用一个新值来替代。自从c++11开始,已经可以使用像int sum{0};这样的初始化了,称为列表初始化!

定义于任何函数之外的变量将被初始化为0;一种例外情况是:定义在函数内部的内置类型变量将不会被初始化。一个未被初始化的内置类型变量的值是未定义的,如果试图拷贝或者以其他形式访问这个类型将会引发错误!!定义于函数体内部的内置类型的对象如果没有初始化,则其值未被定义。类的对象如果没有显示的初始化,则其值由类确定。因此,建议我们初始化每一个内置类型的变量,虽然并非必须这么做,但是如果我们不能确定初始化后程序的运行的安全,那么这么做不失为一种简单可靠地方法--------------养成有变量就初始化的好习惯!!!!

声明规定了变量的类型和名字,但是除此之外还申请了存储空间,也可能会为其变量赋一个初始值。

如果想声明一个变量而非定义它,就在变量前面添加一个关键字extern,而不要显示的初始化变量:extern int i;//声明i而非定义i;int j;//声明并定义j;在函数体内部,如果试图初始化一个由extern关键字标记的变量,将引发错误。变量能且只能被定义一次,但是可以被多次声明!

命名规则:1.用户自定义标示符中不能连续出现两个下划线,也不能使用下划线紧邻大写字母开头,定义函数体以外的标识符不能以下划线开头!

2.变量名要写成小写,方便阅读。

3.用户自定义的类型一般要以大写字母开头。

4.如果标识符由多个单词组成,则单词间应该有明显区分。

建议:当你第一次使用变量时再定义它;也就是说,再对象第一次被使用的地方附近定义它是一种好的选择,因为这样做有助于更加容易地找到变量的定义。更重要的是,当变量的定义与它第一次被使用的地方很近时,我们也会赋予它一个比较合理的初始值!

复合类型:是指基于其他类型定义的类型。主要有:引用和指针。

引用:为对象起的另一个名字,引用类型引用另外一种类型,通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量名。例如;

int ival = 1024;

int &refval = ival;//refval 指向ival(是ival的另一个名字)

int &refval2;//报错,引用必须被初始化。

引用并非对象,相反的,他只是为一个一个已经存在的对象所起的另外一个名字。

指针:是指向另外一种类型的复合类型。也是实现对其他对象的间接访问。

定义指针类型的方法将声明符写成*d的形式,其中d是变量名。如果在一条语句中定义了几个变量,每个变量前面都必须有符号*。

int *ipa,*iP1;

double *db2;//db2是指向double型对象的指针。

指针是存放某个对象的地址,要想获取该地址,需要使用取地址符(&)。

int ival = 42;

int *p = &ival;//p存放变量ival的地址,或者说p是指向变量ival的指针。

建议,初始化所有指针;在大多数编译器环境下,如果使用了未经初始化的指针,则该指针所占内存空间的当前内容将被看成是一个地址值。访问该指针,相当于去访问一个根本不存在的位置上的本不存在的对象。但是如果指针所指内存空间恰好有内容,而这些内容有被当作了某个地址,我们就根本无法分清他是合法还是非法的了。因此建议,初始化所有指针,并在可能的情况下,尽管等定义了对象之后再定义指向它的指针。如果实在分不清应该指向何处,就把它初始化为nullstr或者0,这样的话,程序就能检测并知道它没有指向任何具体的对象了。

任何非0指针对应的条件都是true,如果指针的值是0,那么条件取false。

多个变量的定义。经常出现错误的是如下下情况:

在声明指针时,将空格写在类型修饰符合变量名之中间。int* p;这个情况可能产生误导是因为int*放在一起,让人想到这条语句中所有变量共同的类型一样。其实这样认为是错的。基本数据类型仍然是int而不是int*。*仅仅是修饰p而已,对生命语句中其他变量,它并不起任何作用。例如int* p1,p2;p1是指向int的指针,p2是int型。因此我们要记住,一定将变量标识和修饰符写在一起。这种形式注重强调变量具有的复合类型。

指向指针的指针:

通过*的个数可以区分指针的区别,**表示指向指针的指针,***表示指向指针的指针的指针。

int ival = 1024;

int *pi = &ival;

int **pii = π//ppi指向一个int型的指针。

它们的关系如下:

ppi---〉pi---〉ival

解引用int型指针会得到一个int型数,同样,解引用指向指针的指针得到一个指针,此时要访问最原始的那个对象,需要对指针做两次解引用。

指向指针的引用:

引用本身不是一个对象,因此不能定义指向引用的指针。但是指针是对象,所以存在对指针的引用:

int i= 42;

int *p;//p是一个int型指针

int *&r = p;//r是一个对指针p的引用。

r = &i;//r引用了一个指针,因此给r赋值&i就是令p指向i;

*r = 0;//解引用r得到i,也就是p指向的对象,将i的值改为0.

const限定符:

注意,因为const对象一旦创建后其值不能再改变,所以const对象必须初始化。初始化可以是任意复杂的表达式。

const int i= get_size();//正确,运行时初始化。

const int j = 42;//正确,编译时初始化。

const int k;//错误,k是一个未经初始化的常量。

下面很多人是很容易迷惑的,详解:

在不改变const对象的操作中还有一种是初始化,如果利用一个对象去初始化另外一个对象,则他们是不是const都无关紧要。

int i= 2;

const int ci = i;//正确,i的值被拷贝给了ci

int j = ci;//正确,ci的值被拷贝给了j。

尽管ci是常量,但是无论如何ci中的值还是一个整形数。ci的常量特征仅仅在执行改变ci的操作时才发挥作用。当用ci去初始化j时,根本无需在意ci是不是一个常量。拷贝一个对象的值并不会改变它,一旦拷贝完成,新的对象就和原来的对象没有什么关系。

在编译const变量时,把用到该变量的地方都替换成对应的值。比如const int i = 512;那么在别的地方出现这个i变量,将会全部用512直接替换。

如果程序包含多个文件,则每个用了const对象的文件都必须得能访问到它的初始值才行。要做到这一点,就必须在每个用到变量的文件中都对它进行定义。默认情况下,const对象被设定为仅在本文件内有效。当多个文件中出现了同名的const变量时,其实等同于在不同文件中分别定义了独立的变量。

如果想要让const变量具有在文件间被共享的特点;也就说,只在一个文件中定义const,而在其他多个文件中声明并使用它。解决的办法是:

对于const变量不管是声明还是定义都添加extern关键字,这样只需定义一次就行;

//file.cpp定义并初始化了一个常量,该常量能被其他文件访问。

extern const int bufsize = fcn();

//file.h头文件

extern const int bufsize;//这里的bufsize与file.cpp文件中定义的是同一个。

注意:如果想在多个文件之间共享const对象,必须在变量的定义之前添加extern关键字。

对常量的引用:对常量的引用不能被用作修改它所绑定的对象:

const int ci = 204;

const int &r1 = ci;//正确:引用及其对应的对象都是常量。

r1 = 42;//错误,r1是对常量的引用

int &r2 = ci;//错误,试图让一个非常量引用一个常量对象。

指针和cosnt

指针可以指向常量和非常量。类似于常量引用。指向常量的指针不能用于改变其所指对象的值。要想存放常量对象的地址,只能使用指向常量的指针:

const double pi = 3.14;//pi是个常量,它的值不能改变

double *ptr = π//错误,ptr是一个普通指针、

const double *cptr = π//正确,cptr可以指向一个双精度的指针。

*cptr = 42;//错误,不能给*cptr赋值。

const指针

大家都知道,指针是对象,但是引用却不是对象。因此允许指针本身定为常量。常量指针必须初始化,而一旦初始化,则它的值就不能再改变了。把*放在const关键字之前用以说明指针是个常量,这样写隐含着深层次的意思:不变的是指针本身的值,而不是指向的那个值。

int errNumb = 0;

int *const curErr = &errNumb;//curErr将一直指向errNumb

const double pi = 3.1415;

const double *const pip = π//pip是一个指向常量对象的指针。

字面值类型:

目前接触的数据类型中,算术类型、引用和指针都属于字面值类型。这些可以被定义为constexpr。即使引用和指针都能定义为constexpr,但是收到严格限制。一个constexpr指针的初始值必须是nullptr或者0,或者是存储在某个固定地址中的对象。

另外,定义于函数体内的变量一般来说并非存放在固定的地址中的,因此constexpr指针不能指向这样的变量。相反,定义于所有函数之外的对象其地址是固定不变的,能用来初始化constexpr指针。此外,允许函数定义一类有效范围超出函数本身的变量,这类变量和定义在函数体外的变量一样也有固定的地址。因此,constexpr引用能绑定到这样的变量上,constexpr指针也能指向这样的变量。

c++之——————各种变量的更多相关文章

  1. 6 小时 Python 入门

    6 小时 Python 入门 以下操作均在 Windows 环境下进行操作,先说明一下哈 一.安装 Python 1.官网下载 Python 进入官网(https://www.python.org), ...

  2. In-Memory:在内存中创建临时表和表变量

    在Disk-Base数据库中,由于临时表和表变量的数据存储在tempdb中,如果系统频繁地创建和更新临时表和表变量,大量的IO操作集中在tempdb中,tempdb很可能成为系统性能的瓶颈.在SQL ...

  3. 探究javascript对象和数组的异同,及函数变量缓存技巧

    javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...

  4. Shell特殊变量

    $ 表示当前Shell进程的ID,即pid $echo $$ 运行结果 特殊变量列表 变量 含义 $0 当前脚本的文件名 $n 传递给脚本或函数的参数.n 是一个数字,表示第几个参数.例如,第一个参数 ...

  5. Java多线程基础——对象及变量并发访问

    在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...

  6. Js 变量声明提升和函数声明提升

    Js代码分为两个阶段:编译阶段和执行阶段 Js代码的编译阶段会找到所有的声明,并用合适的作用域将它们关联起来,这是词法作用域的核心内容 包括变量声明(var a)和函数声明(function a(){ ...

  7. PHP源码分析-变量

    1. 变量的三要素变量名称,变量类型,变量值 那么在PHP用户态下变量类型都有哪些,如下: // Zend/zend.h #define IS_NULL 0 #define IS_LONG 1 #de ...

  8. JavaScript var关键字、变量的状态、异常处理、命名规范等介绍

    本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...

  9. shell变量

    定义变量 定义变量时,变量名不加美元符号($),如: variableName="value" 注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样.同时,变量名 ...

  10. 引人瞩目的 CSS 变量(CSS Variable)

    这是一个令人激动的革新. CSS 变量,顾名思义,也就是由网页的作者或用户定义的实体,用来指定文档中的特定变量. 更准确的说法,应该称之为 CSS 自定义属性 ,不过下文为了好理解都称之为 CSS 变 ...

随机推荐

  1. Tomcat服务器安装与第一个jsp网页程序

    1.安装tomcat服务器之前需要,先安装相应版本的jdk,个人理解Tomcat的大部分功能是使用了java的 jdk jar包的. jdk包下载方式网上可以查到 下载完后可以解压到一个指定目录,并在 ...

  2. CAD从二制流数据中加载图形(com接口)

    主要用到函数说明: _DMxDrawX::ReadBinStream 从二制流数据中加载图形,详细说明如下: 参数 说明 VARIANT varBinArray 二制流数据,是个byte数组 BSTR ...

  3. python tips:描述符descriptor

    描述符(descriptor)是实现了__get__.__set__.__del__方法的类,进一步可以细分为两类: 数据描述符:实现了__get__和__set__ 非数据描述符:没有实现__set ...

  4. (5.2.1)配置服务器参数——即时文件初始化(IFI)

    关键词:零填充,即时文件初始化 转自:https://www.cnblogs.com/gaizai/p/3516905.html 概念: 所有新申请的空间,sql server都要以0来填充完磁盘文件 ...

  5. 28 I/O限制的异步操作

    28.2 C#的异步函数 private static async Task<string> IssueClientRequestAsync(string serverName, stri ...

  6. Shell脚本备份数据库

    使用crontab 定时备份数据库 1. 编辑crontab 规则,定时执行脚本 2. 在my.cnf 文件中加 [mysqldump] user=root password=密码 3.编写shell ...

  7. 6)STM32使用HAL库实现modbus的简单通讯

    1.判断地址.校验 2.读取本机数据并校验打包 3.发送数据包 4.本机数据长度比要读取的长度短怎么办 4.校验错误怎么办

  8. jquery源码分析(七)——事件模块 event(二)

    上一章节探讨了事件的一些概念,接下来看下jQuery的事件模块. jQuery对事件的绑定分别有几个API:.bind()/.live()/.delegate()/.on()/click(), 不管是 ...

  9. 【codeforces 514B】Han Solo and Lazer Gun

    [题目链接]:http://codeforces.com/contest/514/problem/B [题意] 每次攻击可以把经过自己的一条直线上的所有点都毁掉; 然后给你n个目标物的坐标 问你最少要 ...

  10. BNUOJ 1021 信息战(七)——情报传递

    信息战(七)——情报传递 Time Limit: 3000ms Memory Limit: 262144KB 64-bit integer IO format: %lld      Java clas ...