《C++ Primer 第五版》第二章(1-4小节)------基本内置类型,初始化和赋值及声明和定义,指针和引用,const和constexpr

        C++ Primer第二章的内容主要介绍了变量和基础类型,包括C++语言定义的基础内置类型、变量的定义及声明、符合类型如指针及引用的介绍和const及常量表达式constexpr的介绍,本次博客也从这四个方面进行系统的介绍,如果有不足之处,还望其他博主留言指正;如果博客对你有一定的帮助,还请点个赞支持一下。

1)基本内置类型

          C++语言具有广泛的数据类型,除了基本内置类型之外,还定义了一些复杂的数据类型,比如可变长字符串string和向量vector等,另外也为码农提供了自定义数据类型的机制,比如类和结构体等,本次博客主要是介绍C++语言中的基本内置类型。

          C++将基本内置类型分为算术类型和空类型(void),算术类型又分为整数类型和浮点数类型,其中整数类型又分为布尔类型(bool 未定义最小尺寸大小,值为true或false),字符类型(char,最小尺寸为8位),short类型(最小尺寸为16位),int类型(最小尺寸为16位),long类型(最小尺寸为32位),long long类型(C++11中新定义的,最小尺寸为64位);另外浮点型包括单精度浮点型(32位,有效位数为5位)和双精度浮点型(64位,有效位数为7位),且浮点数在计算机中的储存结构如下图所示:

         

      C++中定义一个char类型的大小和一个机器字节一样长,同时定义byte(long long)>=byte(long)>=byte(int)>=byte(short)。

      在选择数据类型的时候有以下四条建议:1)合理使用无符号类型,避免无符合和有符号数混合运算;2)整型定义尽量使用int,如果数据较大则使用long long;3)算术表达式尽量不要出现bool和char类型;4)浮点运算选用double类型。

2)初始化及赋值和声明及定义

      初始化赋值时两个完全不同的概念,初始化的含义是创建变量时并对变量赋予一个初始值,其调用的是定义好或默认的构造函数,而赋值的含义是将对象当前的值擦除,并用一个新值来替代,调用的是拷贝构造函数或=重载操作符函数。

      如果变量只是定义但没有指定初值,系统会对变量进行默认初始化。对于内置类型变量的默认初始化值,和其位置有关。如果内置类型变量定义在任何函数之外,则默认初始化为0;如果定义在函数内部,则不会被初始化,此时的值未定义,拷贝和访问没有定义的值会发生错误。绝大多数类都支持默认初始化,这和类中是否有默认构造函数有关,有一些其他的类则需要显示进行初始化。

     C++规定,可以采用初始化列表的形式来初始化变量,即采用一组由花括号括起来的值来初始化变量,但是需要注意的是使用初始化列表的形式初始化内置类型变量时,如果初始化过程中存在数据截断的情况,如把一个浮点数赋值给整数,编译器会报错

     C++为了方便程序实现分离式编译(可以理解成.C和.h文件的独立),将声明和定义区分开。声明的目的是为了让变量的名字为程序所知,声明中只规定变量的类型和名字,并在前面加上extern关键字(但不能对加了extern关键字的变量进行初始化,否则extern关键字失效);定义的目的则是为了创建和名字有关的实体,为变量申请内存空间,还可能初始化变量。

     建议:不管是在函数内还是函数外,使用内置类型都要初始化。在函数体内部初始化一个由extern关键字标记的变量,会发生错误,因为变量只能定义一次,但可以多次声明。

3)指针及引用

      指针是一种指向其他类型对象的复合类型(基本数据类型+一组声明符),大多数情况下需要满足定义的指针类型和指针指向对象的类型匹配(两种特殊情况:1)常量指针指向非常量对象。2)virtual类的动态编译)。指针是一个对象,可以进行赋值和拷贝,也可以指向不同的对象,同时不需要在定义的时候进行赋值(和引用的区别)。使用指针时,如果需要分析程序执行的每个时间段指针的指向,可以采用内存四区模型和一个建议(指针指向谁,就把谁的地址赋给指针)来进行分析。

    对于指针而言,指针的值存在四种状态:1)指向一个对象(一般情况);2)指向紧邻对象的一个空间(尾后迭代器);3)空指针,没有指向任何对象;4)无效指针,除1)2)3)情况之外。

    建议:对于使用了指针的情况下,要判断所得到的指针是否有效,访问和拷贝无效指针的值会使程序崩溃。

    引用是指对象的别名,一般情况下的引用都指的是左值引用。引用定义的机制是将引用和变量对象绑定起来,使得引用称为变量的另外一个名字,但是此时的变量对象可以不初始化。由于定义引用需要将引用和变量对象进行绑定,因此引用必须初始化,且一旦绑定了一个对象,引用就不能再绑定另外一个对象了。引用不是对象,它只是变量对象的一个别名,因此不能定义引用的引用或指向引用的指针。由于引用是和变量对象是绑定起来的,因此通常情况下引用的类型和绑定对象的类型要一致(除了两种情况:1)初始化常量引用,可以采用任意表达式作为初始值,只要能够转换成引用类型;2)virtual类的动态编译)。

4)const和常量表达式constexpr

      const限定符的作用是用于限制变量的类型。一般情况下有两种情况:1)默认情况下,const对象只能在文件内有效。多个文件出现相同的const变量时,等同于不同文件中独立定义的const变量。2)当const变量初始值不是一个常量表达式且需要实现多个文件共享变量,需要在一个文件中定义const变量,其他文件中声明并使用它(声明和定义变量时都需要加上extern const标识符)。

      常量引用:也称为对const的引用,是将引用绑定到const对象上。C++规定允许将非常量的对象,字面量和一般表达式绑定给一个常量引用,只要右端的值能够转化为引用的类型即可。但是,在不同类型转换的过程中,其实引用绑定的是一个临时量,而非我们希望绑定的那个数据,具体例子如下所示:

                                         double var=3.14;      ------------>         const int temp=var;

                                         const int &p=var;      _______>          const int &p=temp;

     建议:使用引用绑定对象时,养成引用和绑定对象类型一致的习惯。

     常量表达式(constexpr)指的是值不会改变且在编译过程中能够得到计算结果的表达式。一般来说,可以使用算术类型,引用和指针等字面值类型的变量来初始化常量表达式。除此之外,可以地址固定不变的对象来初始化常量表达式。对于constexpr类型的指针初始值必须为nullptr(0)、存储于某个固定地址的对象或超出函数范围之外的变量(如static和global变量)。

    C++11规定可以采用constex来验证变量的值是否为常量表达式,初始化常量表达式的值必须为常量或constexpr函数。


***知识点补充1:字,字节和位的区别?

     位:即bit,是计算机用来存储数据的最小单元,取值为0或1;

     字节:即byte,是计算机可寻址的最小内存块,一个字节等于8bit;(牵涉到的知识点:定义数据的大小)

     字:即word,是计算机存储的基本单元,通常由几个字节组成;(牵涉到的知识点:数据对齐方式和计算机的位数)

***知识点补充2:变量,对象和值之间的关系?

    变量:提供一个具体名字的,可供程序操作的存储空间。

    对象:具有某种类型的内存空间(数据类型+内存空间)。

    值:只读的数据。

    已命名的对象才称为变量。

***知识点补充3:变量的命名规则?

    变量的命名规则有以下四个建议:1)变量名体现实际含义;2)变量名一般使用小写;3)自定义的类名以大写字母开头;4)如果出现多个单词,单词之间采用下划线连接。

***只是补充点4:指向常量的指针/引用,常量指针,顶层const,底层const区别?

    指向常量的指针/引用:指针指向的/引用绑定的对象为常量,此时不能用指针/引用去改变常量对象的值。

    指针常量:指针的地址不变,指向的对象数据可以发生改变,必须初始化。

    顶层const:定义的对象是常量(如常量指针,常量内置定义类型);

    底层const:定义对象指向的值或者绑定的值为常量(如指针常量,指向常量的引用);

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

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

相关文章

455. 分发饼干 golang

455. 分发饼干 Me func findContentChildren(g []int, s []int) int {if len(s) 0 {return 0}sort.Ints(g)sort.Ints(s)var count, i, j int 0, 0, 0for { if g[i] < s[j] {i, j, count i1, j1, count1} else {j}if i > len(g) || j > len(s) {return count}}re…

《C++ Primer 第五版》第二章(第5小节)——using和typedef,auto和decltype总结

1.using和typedef&#xff08;作用&#xff1a;定义类型别名&#xff09; 1)typedef和using都可以用来定义一个类型别名&#xff0c;二者在类型别名上定义没有区别。只是需要注意的是类型和类型别名的顺序&#xff0c;使用typedef定义类型别名的结构为 typedef 类型 类型别名&a…

204. 计数质数 golang

一次尝试&#xff0c;如何击败100%用户&#xff08;用时&#xff0c;内存&#xff09; func countPrimes(n int) int {if n 499979 {return 41537}if n 11 {return 4}if n 12 {return 5}if n 13 {return 5}if n 14 {return 6}if n 15 {return 6}if n 10 {return 4}if n …

leetcode内存消耗

leetcode内存消耗最是多少 执行用时 :0 ms, 在所有 Go 提交中击败了100.00%的用户 内存消耗 :1.9 MB, 在所有 Go 提交中击败了94.81%的用户测试链接 Test

《C++ Primer 第五版》(第2.5节,第3.1-3.4节) ——采用预处理功能编写头文件,string初始化和字符操作,vector初始化和迭代器

1.采用预处理功能编写头文件 在头文件定义(头文件中的内容是只能被定义一次的实体)过程中&#xff0c;为了防止头文件重复包含的情况&#xff0c;采用预处理器的一个头文件保护符功能,格式为&#xff1a;{ #ifndef 预处理变量(通常大写) #define 预处理变量 #end…

《C++ Primer 第五版》(第3.5-3.6节) ——C++中的内置数组类型,string对象和C风格字符串

1.C中的内置数组类型 C中的数组是内置数据类型&#xff0c;但不是基础数据类型而是构造数据类型&#xff0c;是有限个相同数据、占据着连续物理存储空间的有序集合。而内置数据类型定义的下标运算符可以处理负值运算(只要在数组范围之内)&#xff0c;这和vector及string的下标运…

793. 阶乘函数后K个零 golang

Me(AC 33 / 44 个通过测试用例) func preimageSizeFZF(K int) int {count : 0for i : 0; i < 1000000; i {if trailingZeroes(i) K {count}}fmt.Println(count)//fmt.Println(trailingZeroes(25))return count}func trailingZeroes(n int) int {if n 0 {return 0}return …

小程序radio单选框回显

话不多说&#xff0c;效果图如下&#xff1a; 具体代码如下&#xff1a; <radio-group name"radio" bindchange"getSex"><label><radio value"1" checked"{{xingbie1}}" />男</label><label><radio…

172. 阶乘后的零 golang

官解 一般很难想到这个方向&#xff0c;有点类似数学归纳法&#xff1f; func trailingZeroes(n int) int {if n 0 {return 0}return trailingZeroes(n / 5) n / 5 }

《C++ Primer 第五版》(第4.11节类型转换) ————关于无符号数和有符号数的运算探究

1.关于无符号数和有符号数的运算 关于无符号数和有符号数的运算&#xff0c;在我看来一直是觉得只要有无符号数和有符号数的运算&#xff0c;有符号数就转化为无符号数&#xff0c;但是在《C Primer 第五版》的p142介绍&#xff0c;关于无符号数和有符号数的运算如下规定的&…

《C++ Primer 第五版》(第4.1-4.11节) ——运算符的执行顺序问题,负值坐商取余问题,数值的移位操作

1.运算符的执行顺序问题 在C语言中&#xff0c;没有明确规定大多数二元运算符的求值顺序&#xff0c;这给编译器留下了余地&#xff0c;这种策略是在代码生成效率和程序潜在缺陷之间的权衡。 对于运算符而言&#xff0c;如果运算符的两个对象中&#xff0c;存在表达式指向并修改…

543. 二叉树的直径 golang

文章目录543. 二叉树的直径example正确解法question代码&#xff08;wrong)543. 二叉树的直径 概要: 借鉴了这个题的代码。可是有一个测试用例过不去 https://blog.csdn.net/csdn_kou/article/details/104122067 example 给定一棵二叉树&#xff0c;你需要计算它的直径长度。一…

《C++ Primer 第五版》(第4.11-4.12节)——static_cast,const_cast和reinterpret_cast类型转换, 运算符优先级表

1.static_cast,const_cast和reinterpret_cast类型转换 static_cast:强制的类型转换(不能用于底层的const转换),以前C语言中的强制类型转换都可以使用static_cast来完成。如&#xff1a;int i3; double jstatic_cast<double>(i); const_cast&#xff1a;改变底层const(指针…

《C++ Primer 第五版》(第5.1-5.6节) ——异常处理机制(try语句块,throw表达式和catch异常捕捉处理单元)

1. 异常处理机制 C中使用try,throw和catch三个关键字来实现异常的触发、抛出和处理的功能&#xff0c;具体通用语法形式如下&#xff1a; try{ if(true) normal program-statements&#xff1b;//没有触发异常时候执行的代码 if(false) throw(exception); //出现错误&am…

《C++ Primer 第五版》(第6.1~6.3节) 函数形参和实参传递,可变参数列表和函数返回值

1.函数形参和实参传递问题 函数参数传递有两种&#xff1a;值传递(变量&#xff0c;指针&#xff09;,引用传递(使用别名&#xff09;。 在形参和实参的传递过程中&#xff0c;牵涉到大的类类型对象、容器类型对象或者不支持拷贝操作的对象时&#xff0c;不适合采用值传递&…

461. 汉明距离 golang

Me 异或取出1的个数求取异或后1的个数返回 func hammingDistance(x int, y int) int {x x ^ yvar count 0for x ! 0 {x x & (x - 1)count}return count }

《C++ Primer 第五版》(第6.3~6.7节)——返回指向数组/函数的指针,函数重载,默认形参、inline函数和constexpr函数

1.返回指向数组/函数的指针 顾名思义&#xff0c;就是函数返回值为指向数组/函数的指针。 数组的性质&#xff1a;不能被拷贝&#xff0c;函数也不能返回数组。但可以返回数组指针/引用&#xff0c;声明一个返回数组指针的函数&#xff0c;有四种方式&#xff0c;一种是直接声明…

136. 只出现一次的数字 golang

Me 1. 先排序就好做了 执行用时 :16 ms, 在所有 Go 提交中击败了27.90%的用户 内存消耗 :4.7 MB, 在所有 Go 提交中击败了100.00%的用户func singleNumber(nums []int) int {sort.Ints(nums)for i:0; i < len(nums); i {if i len(nums) - 1 {return nums[i]}if nums[i] …

《C++ Primer 第五版》(第1~6章总结)

1.C采用标准库文件iostream定义的两个对象来实现IO机制。 2.代码注释应解释关键数据的变量含义和代码完成了什么功能&#xff0c;力求简洁易懂。 3.正确理解初始化和赋值&#xff0c;声明和定义的含义&#xff1f;初始化是在定义对象的时候同时赋值&#xff0c;赋值是定义对象…

268. 缺失数字 golang

Me 首项加末项乘以项数/2.就是总和。然后剪掉nums里面的数组和 func missingNumber(nums []int) int {var sum intlens : len(nums)for _, value : range nums {sum value}return ((1 lens) * lens) / 2 - sum }