zoukankan      html  css  js  c++  java
  • c++之——————各种变量

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

    变量:提供一个具有名字的可供程序操作的存储空间。由类型说明符和其后紧跟的数个列表组成,其中变量名之间使用逗号分隔,最后使用分号结尾。像 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指针也能指向这样的变量。

  • 相关阅读:
    【leetcode】1365. How Many Numbers Are Smaller Than the Current Number
    【leetcode】1363. Largest Multiple of Three
    【leetcode】1362. Closest Divisors
    【leetcode】1361. Validate Binary Tree Nodes
    【leetcode】1360. Number of Days Between Two Dates
    【leetcode】1359. Count All Valid Pickup and Delivery Options
    【leetcode】1357. Apply Discount Every n Orders
    【leetcode】1356. Sort Integers by The Number of 1 Bits
    ISE应用入门的一些问题
    DDR的型号问题
  • 原文地址:https://www.cnblogs.com/NongSi-Net/p/4758454.html
Copyright © 2011-2022 走看看