C++Primer 第Ⅰ部分读书笔记

1.变量与基本类型

1.1extern的使用

1.1.1声明而不定义

extern int i;//声明而未定义
int j;//声明并定义

1.1.2在全部文件中使用const量

extern const int size = 0;

1.2.指针和const

const int * p1 = &i;//指向常量的指针
int*const p2 = &i;//指向i的常量指针
const int *const p3 = &i;//指向常量的常量指针

1.3constexpr (C++11)

constexpr int j = 0;//显式告诉编译器这是个常量
constexpr int * p4 = &i;//指向i的常量指针

1.4类型别名

1.4.1 typedef

typedef double wages;

1.4.2 using (C++11)

using wages = double;

1.4.3别名与指针引起的误会

typedef int* wages;//类型别名声明
const wages p1 = 0;//常量指针,而非指向const的指针

1.5 decltype类型 (C++11)

1.5.1 decltype的基本使用

int a = 0,*b=&a,&c=a;
decltype(a) x;//返回int类型
decltype(b) y;//返回int指针类型
decltype(c) z;//错误,返回引用类型必须初始化

1.5.2 decltype和引用

int a = 0,*b=&a;
decltype(*b) c;//错误,*b返回类型为引用
decltype((a)) d;//返回引用int类型,但未初始化,错误
int a = 0,*b=&a,&c=a;
decltype(a) x;//返回int类型
decltype(b) y;//返回int指针类型
decltype(c) z;//错误,返回引用类型必须初始化

1.6头文件保护符

#ifndef STRING_H//判断是否定义变量,若定义返回真,执行直到遇到  #endif
#define STRING_H //把一个名字设定为预处理变量


//源代码



#endif

2.类型转换

2.1 显式强制转换

基本格式:

cast-name<type>(expression);

2.1.1 static_cast

内层不包括const,即可使用 static_cast

找回void*指针的值

void*p1 = &d;
double *p2 = static_cast<double*>(p);

2.1.2 const_cast

只能改变底层const的类型转换,去掉const性质

const int val = 21;//赋值
const int*p1 = &val;//p1指向val
int*p2 = const_cast<int*>(p1);//强制类型转换
*p2 = 7;//改变值,但该行为是未定义的

不能通过p2改变val的值,该行为是未定义的

那么const_cast的作用是什么? 一个函数如果需要非常量作为参数,并且我们明确函数不会修改该值,那么我们可以通过类型转换传递参数达到目的

const_cast从来不是为了修改常量而设计的

2.1.3 reinterpret_cast

这里不细讲,待补充

2.1.4旧式类型强制转换

typename(expr);//函数形式的强制转换
(typename)expr;//C语言风格的强制转换

3.函数

3.1 含有种类可变形参的函数

void fun(initializer_list<int>num);

initiallizer_list可提供多种与容器相同的方法

比如begin(),size(),size()

这样便可以传递多个形参

3.2 主函数main()的返回值

为了返回值不随机器改变而改变,应该使用cstdlib头文件中的两个预处理变量

#include<cstdlib>
int main()
{
      if(some_faliure)
            return EXIT_FAILURE;
      else
            return EXIT_SUCCESS;
}

3.3 返回数组指针

int (*fun(int val) ) [10];  //表示返回一个指向十个元素的数组的指针

3.3.1 使用尾置返回类型

auto fun(int i ) -> int(*)[10];

*必须用括号括上,原因如下

int *p1[10];// 表示一个含有十个指针的数组
int(*p)[10];//表示一个指向十个元素数组的指针

3.3.2 using

using Arrt = int [10];
Arrt fun(int i );

3.4 constexpr函数 (C++11)

constexpr fun(){return 42;)
constexpr int i = fun();

使用constexpr函数需要遵循返回类型为字面值类型,并且函数内只能有一句return语句

除此之外,constexpr函数返回的不一定是常量,当形参为常量表达式时,函数返回常量

否则,返回非常量

3.5调试帮助

3.5.1 assert预处理宏

assert定义再 cassert头文件中

assert(exp);

若exp为真,则继续执行,若exp为假,则终止程序进行

3.5.2 NDEBUG预处理变量

#define NDEBUG

若定义了NDEBUG,则assert什么也不做

_ func _定义存放函数
_ FILE _定义存放文件
_ LINE _定义行数
_ TIME _定义编译时间
_ DATE _定义编译日期

3.6函数指针

3.5.1函数指针的基本使用

bool fun(int i);
bool (*p)(int i );
p = fun;
p = &fun; //两种方式等价
int i = p(4);
int j = (*p)(4);//两种方式等价

与普通指针类似,函数指针需要声明并且不能指向不同类型

3.5.2返回指向函数的指针

int (*p(int i) ) (int i);
using p = int (*q) (int i );
p fun(int i );

4.类

4.1 默认构造函数 =defalut (C++11)

class MAP
{
      MAP() =default;//若类中有别的构造函数,但没有默认构造函数,则需要自己提供一个
}

4.2委托构造函数 (C++11)

class Data
{
public:
           Data(int Val,int Key) : val(Val),key(Key)  {}
           Data(int Val): Data(Val,0)   {}
}

4.3explicit构造函数

class Data{
public:
           explicit Data(int Val):val(Val) {}  //只能用于直接初始化,并且不能隐式转换

4.4 聚合类

1.所有成员为pubilc
2.没有类内初始值
3.没有构造函数
4.没有基类也没有虚方法

struct  Data
{
    string s;
    int val;
}

Data temp = {"s",2);//可直接花括号初始化

4.5 静态成员

在类中声明静态成员,在类外定义并初始化静态成员

与函数类似,值得注意的是,如果是数据类型,也必须给予类型

class MAP
{
    static int a;
}

int a = 5;

也可以这样初始化

class MAP
{
     static constexpr int a = 5;
}

静态成员可以用来声明不完全类型

class MAP
{
public:
     //...
priviate:
    static MAP a;//但不能直接声明
    MAP* b; 
posted @ 2017-08-04 00:04  vhyz  阅读(149)  评论(0编辑  收藏  举报