C++11基础学习系列一


概述

C++11标准越来越趋于稳定和成熟,国外c++11如火如荼而国内却依然处于观望期。每当提到C++很多程序员都很抵触,特别是学术界的呼声更高一些。其实不然,语言即工具,语言的好坏不在于本身,而在于驾驭它和适用它所在的范围所决定的。那么为什么国内大多数程序员都会遭到抵触呢?我觉得原因有如下(不要劈我,仅此个人意见):

  • C++是对C语言进行了抽象同时又支持了很多面向对象的特性,在趋于底层设计时又对上层进行封装和扩展。它是从计算机科学层面去设计和演化的,如果想写出高效和稳定的程序,那么你就必须具备基本的计算机科学基础知识,但是国内大多数程序员很少关注计算机科学的知识,更关注一些新技术、新应用等(自己认为来钱快),还有就是”培训出来的程序员”,如果后天不加以提高和补充基础知识想走的远一点,要么转项目经理,转行,重复性应用层面开发。一提到底层就到了恐慌万状样子。其实无论做应用还是底层、架构等,如果想做的足够好的话,你要有强大的”内功”。
  • C++ 本身查找、分析、定位和开发效率相对于其它语言较慢甚至还有出现内存泄漏、垃圾回收等等问题(c++11以下),一传十,十传百,其实不然,c++仍然在不断进化,越来越符合现代程序语言的特点。
  • c++学习路线相对于其它语言来说成本大,现在人比较现实,所以你懂得。 网上流传一个很经典的话,你恨它->你不得用它->你爱它->你离不开它。 我个人也觉得学习c++不外乎这几阶段。我使用c++一是拓展自己的思路;二是工作中使用它;三是个人觉得前景辉煌。废话不说了,我写一系列的C++(c++11)文章,主要是记录自己学习、看书和遇到问题的总结。好记性不如烂笔头。

类型

“千里之行始于足下”。我们先来看一下c++的内置类型,先从算数类型开始:整型和浮点型。先贴一张图:

该图取自《C++ Primer》

类型说明

  1. wchar_t、char16_t和char32_t,wchar_t用于存放机器最大扩展字符集中的任意一个字符。char16_t和char32_t是针对于Unicode符集的。Unicode主要是统一编码字符集的标准,包括字符集、编码方案等。主要是能使计算机跨语言、跨平台的文本转换处理。Unicode编码字符集编码可以采用UTF-8,UTF-16等等
  2. C++ 语言规定bool并没有指定它最小的存储尺寸,int至少和short一样大,long至少和int一样大,long long是c++11新增的。对于浮点数C++只指定了最小的浮点数有效位数,大多数编译器(GCC,CLANG等等)都已经实现了更高的精度。一般而言,float用4字节表示,double用8字节表示,long double用12或者16个字节表示;float和double分别有7和16个有效位。
  3. char和signed char并不一样,这取决于编译器。所以不要在表达式使用它们,如果需要使用时那么明确指定signed char和unsigned char类型。
  4. 如果整数超过了int,选用long long,这主要是由于long至少和int一样大的特性决定的;如果选用浮点数尽量采用double;在同一个表达式中尽量不要混合使用无符号类型和符号类型。 比如下面:#include <iostream> int main() { for (unsigned int i = 3; i >= 0; --i) { std::cout << "the value of i is " << i << std::endl; } return 0; } #输出结果会不断循环下去 the value of i is 3 the value of i is 2 the value of i is 1 the value of i is 0 the value of i is 4294967295 the value of i is 4294967294 the value of i is 4294967293 the value of i is 4294967292 the value of i is 4294967291 the value of i is 4294967290 the value of i is 4294967289 . . .

这是由于整数的符号位表示造成的。

Literal(字面值常量)

零开通的整数代表8进制,0x和0X开头的整数代表16进制。值得注意一点是,浮点数的默认是double类型。字符串字面值如下:

  • u前缀代表Unicode 16 字符,对应类型是char16_t
  • u8前缀代表UTF-8存储对应的类型是char。
  • U前缀代表Unicode 32 字符,对应类型是char32_t。
  • L前缀代表宽字符,对应类型是wchar_t。

初始化与赋值

在C++中初始化是创建变量并赋予初始值因此叫初始化,赋值操作是更新对象值即将右值更新到操作符左侧对象中。C++11新增了列表初始化,由花括号括起来,如下:

int a = {12};
int b{12};

声明与定义

在C++中如果在代码中使用变量,必须先声明该变量。定义是指在初次使用变量时就需要定义变量。变量可以多次声明,但只能定义一次。

Complex Type

C++ 中的复合类型(Complex Type)有引用、指针、类等。

引用与指针

引用即别名,引用必须被初始化,引用不是对象。,引用主要是通过bind技术来实现,并不是拷贝。指针即地址,指针是对象,通过解引用获取值。。两者都间接提供了访问对象的功能,其中C++11提供字面值nullptr来初始化指针。void * 可以存放任意对象地址.

#include <iostream>

int main() {
    int a = 12;
    int &b = a;
    int *c = nullptr;
    c = &a;
    std::cout << "a==" << a << ";b==" << b << ";c==" << *c << std::endl;
    return 0;
}
### 输出
a==12;b==12;c==12

const和constexpr

常量表达式不会改变且在编译期间得到结果,字面值是常量表达式,用常量表达式初始化的const对象也是常量表达式。例如:

#include <iostream>

int main() {
	#是常量表达式
    const int a = 12;
    #是常量表达式
    const int c= a+24;
    #不是常量表达,是变量。
    int b = 12;
    #不是常量表达式,在运行时获得值。
    const int count = get_count();
    return 0;
}

c++11规定,可以通过将变量声明未constexpr,由编译器来验证变量是否是一个常量表达式

#include <iostream>

int main() {
    const int a = 12;
    const int c= a+24;.
    #是常量表达式
    constexpr int b = 12;
    constexpr int count = get_count();
    return 0;
}

自定义类、IO库和string类型不属于字面值类型,所以不能被定义为constexpr,而算术类型、引用和指针都属于字面值类型所以可以定义为constexpr,但是constexpr指针必须是nullptr或者固定地址中的对象,并且constexpr仅对指针有效,与它所指向的对象无关。

#include <iostream>

int main() {
    const int c = 12;
    #a是一个指向常量整数的指针
    const int *a = &c;
    #d是一个指向整数的常量指针
    constexpr int *d = nullptr;
    return 0;
}
###输出结果
main.cpp: In function 'int main()':
main.cpp:6:25: error: invalid conversion from 'const int*' to 'int*' [-fpermissive]
     constexpr int *d = &c;

const 是修饰一个变量且该变量的值是不可被改变的,const对象必须初始化,const对象是对文件有效,如果想跨多个源文件都使用一个const对象,需要在定义和声明是都添加extern。即extern const int a = 12。对于const的引用,引用类型必须与其所引用对象的类型保持一致,当然在初始化变量时可以使用常量表达式作为初始值:

#include <iostream>

int main() {
    int a = 12;
    float k = 12.0;
    const int &b = a;
    const int &c = 42;
    #是可以编译通过,主要是在编译器创建一个临时常量对象。
    const int &j = k;(const int j = k;const int &j=k)
}

对于const来说只是限定了所修饰的变量,并不能限定右值。我们来看一下指针。 指向常量的指针和常量指针指向常量的指针说明是一个指针,该指针指向的常量的地址。常量指针说明是一个指针本身定义为常量。

#include <iostream>

int main() {
    int a = 12;
    const int b = 23;
    #指向常量整型的指针,不能通过该指针改变所指向那个对象的值,并没有规定该指针对象的值不能通过其它路径改变。
    const int *c = &b;
    c = &a;
    #指向整型的常量指针,指针本身是一个常量,不能通过其它路径改变该指针对象的值。
    int* const d = &a;
}

auto和decltype

auto和decltype是c++11新增的特性,auto能让编译器自动分析表达式所属类型;decltye选择并返回操作数的类型。例如:

#include <iostream>
#类似c语言的typedef作用,类型别名
using INTER = int;

int sum(const INTER &a, const INTER &b) {
    return a + b;
}

int main(void) {
    INTER a = 10, b = 20;
    auto c = a + b;
    std::cout << "c====" << c << std::endl;
    decltype(sum(a, b)) d = b;
    std::cout << "d====" << d << std::endl;

}

auto作用在带有const变量时一般会忽略掉。decltype使用的表达式不是一个变量时,则返回表达式结果对应的类型。比如:

#include <iostream>


int main(void) {
    const int a = 10, b = 20;
    auto c = a + b;
    #可以看到auto已经忽略了const的限定
    c = 30;
    const auto d = a + b;
    #编译器将会报错
    d = 30;
    int j=22,*p=&j,&r=j;
    #i是一个int,j+21结果还是int.
    decltype(j+21) i;
    #p是一个指针,*p对指针进行解引用将得到引用类型,即int &k
    decltype(*j) k;
    #双括号永远是引用
    decltype((j)) q;
}

总结

c++11在探索着……

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从流域到海域

Python 函数

Python的函数与其他语言的函数概念上是一致的,只是形式上有所不同。在面向过程的编程语言中(C语言),函数是代码的基本组成形式,是功能的基本模块;在面向...

22170
来自专栏chenjx85的技术专栏

leetcode-561-Array Partition I

20170
来自专栏数据结构与算法

P1338 末日的传说

题目描述 只要是参加jsoi活动的同学一定都听说过Hanoi塔的传说:三根柱子上的金片每天被移动一次,当所有的金片都被移完之后,世界末日也就随之降临了。 在古老...

32890
来自专栏IT可乐

Java数据结构和算法(七)——链表

  前面博客我们在讲解数组中,知道数组作为数据存储结构有一定的缺陷。在无序数组中,搜索性能差,在有序数组中,插入效率又很低,而且这两种数组的删除效率都很低,并且...

47870
来自专栏java思维导图

【一分钟知识】面对对象、基本类型

【一分钟回顾】系列 很多知识都是概念性的东西,有时候你知道这个技术的用法,但未必就能准确地说出它代表的含义与思想。一分钟回顾系列文章会从基础开始到后期的高级,带...

30350
来自专栏take time, save time

初级程序员面试不靠谱指南(五)

四、递归的第一次亲密接触     我经常会想,如果给没有学过计算机或者数学的人说递归这个词他们脑中会怎样理解这个词的意思。递归这个概念在面试中出现的概率大于85...

35780
来自专栏积累沉淀

各种排序算法的总结和比较

1 快速排序(QuickSort) 快速排序是一个就地排序,分而治之,大规模递归的算法。从本质上来说,它是归并排序的就地版本。快速排序可以由下面四步组成。...

20160
来自专栏于晓飞的专栏

DualPivotQuickSort 双轴快速排序 源码 笔记

这个算法是Arrays.java中给基本类型的数据排序使用的具体实现。它针对每种基本类型都做了实现,实现的方式有稍微的差异,但是思路都是相同的,所以这里只挑了i...

10920
来自专栏程序员互动联盟

【编程基础】Java面向对象基础知识

前言: 前面一系列文章讲了Java的一些语法基础知识、Java中的数据类型和Java中的运算符,基本上都是学习Java语言的基础知识,从这一讲开始将会逐步介绍J...

35550
来自专栏黑泽君的专栏

Java语言中:在数据类型的讲解中补充的几个小问题

============================================================================= 1...

8510

扫码关注云+社区

领取腾讯云代金券