前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++11基础学习系列一

C++11基础学习系列一

作者头像
吕海峰
发布2018-04-03 14:59:25
8870
发布2018-04-03 14:59:25
举报
文章被收录于专栏:BrianBrian

概述

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

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

类型

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

C++ 类型
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新增了列表初始化,由花括号括起来,如下:

代码语言:javascript
复制
int a = {12};
int b{12};

声明与定义

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

Complex Type

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

引用与指针

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

代码语言:javascript
复制
#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对象也是常量表达式。例如:

代码语言:javascript
复制
#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,由编译器来验证变量是否是一个常量表达式

代码语言:javascript
复制
#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仅对指针有效,与它所指向的对象无关。

代码语言:javascript
复制
#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的引用,引用类型必须与其所引用对象的类型保持一致,当然在初始化变量时可以使用常量表达式作为初始值:

代码语言:javascript
复制
#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来说只是限定了所修饰的变量,并不能限定右值。我们来看一下指针。 指向常量的指针和常量指针指向常量的指针说明是一个指针,该指针指向的常量的地址。常量指针说明是一个指针本身定义为常量。

代码语言:javascript
复制
#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选择并返回操作数的类型。例如:

代码语言:javascript
复制
#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使用的表达式不是一个变量时,则返回表达式结果对应的类型。比如:

代码语言:javascript
复制
#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在探索着……

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 类型
    • 类型说明
      • Literal(字面值常量)
        • 初始化与赋值
          • 声明与定义
          • Complex Type
            • 引用与指针
              • const和constexpr
              • auto和decltype
              • 总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档