您的位置:首页 > 编程语言 > C语言/C++

C++ Primer 学习笔记(第二章)

2017-10-25 00:34 281 查看

第二章 变量和基本类型

2.1 基本内置类型

1.变量类型:

布尔型bool;整型int;浮点型(双精度); 符号型等。



 

2.不同类型的变量不要在一起做加减等运算


unsigned u=10;
    int i=-42;
    std::cout << u+i <<std::endl;

结果是乱码,计算会将-42先转换为无符号的数,之后在进行加和。



Unsigned类型的变量永远不会为负,unsigned 的 i=0; i--; 不断循环结果不是负数,原本该出现的-1会变成4294967295这种不合法的正数。

 

3.进制表示

20  //十进制

024  //用0表示八进制

0x14 //用0x表示十六进制

 

4.转义序列

有两种字符不能直接使用

①不可打印字符,如退格附的等。

②转义序列:

换行符  \n  \12

横向制表符 \t

报警(响铃)符 \a   \7

纵向制表符 \v

退格符(Backspace) \b

双引号  \”

单引号  \’

问好  \?

反斜线  \\

回车符 \r

进纸符  \f

空格  \40

空字符  \0   等等

 

2.2 变量

1.声明和定义

声明可以有多次 extern int a;  声明一个变量a,没有任何问题

定义只能有一次,而且一般定义都会直接初始化  int a=3; 这个叫定义。

定义时相当于也顺路做了声明。

(a) extern int ix = 1024;    //定义 虽然有extern但是确实有初始化,属于定义

(b) int iy;                //定义,没有extern

(c) extern int iz;           //声明

 

2.命名规范

①标识符要能体现实际含义;

②变量名一般用小写字母,如index,不要使用Index或INDEX;

③用户自定义的类名一般以大写字母开头,如Sales_item;

④如果表示符由多个单词组成,则单词间应该有明显区分,如:student_loan或studentLoan,不要使用studentloan。

 

3.整体变量和局部变量

int reused =42;      
//全局作用域 
void main()
{
    int unique=0;   
    std::cout<< reused <<" "<<unique<<std::endl; //42 0
    int reused =1;   
//内层作用域内定义 reused=1   
    std::cout<< reused <<" "<<unique<<std::endl; //进入块作用域 1 0
    std::cout<< ::reused <<" "<<unique<<std::endl;
    //因为全局作用域没有名字,所以::表示全局作用域下的reused  42 0
    system("pause");
}

 

4.初始化和赋值

初始化不是赋值,初始化的含义是创建变量时赋予一个初始值。

赋值的含义是把对象的当前值擦除,使用一个新值来代替。

 

5.列表初始化

C++11新标准规定了如下赋值模式:

int units_sold = 0;

int units_sold = {0};

int units_sold{0};

int units_sold (0);

这四种赋值方式都是正确的,它们被称为列表初始化。使用花括号初始化时{},如果初始值存在丢失信息的风险,编译器就会报错:

Long double ld = 3.1415926;

int a{ld}, b={ld};              //报错,出现了信息丢失的危险

int c(ld), b=ld;                //不报错,c和d变成了3,丢失了信息但是可以运行

 

2.
d97a
3复合类型

1.引用

引用是针对类型的,程序把引用和它的初始值绑定在一起,而不是将初值拷贝给引用。引用不是对象,它只是为一个已经存在的对象起的另一个名字。

①如果引用的值发生变化,原值也会发生变化;

②引用的类型必须与原类型一致,如都是:int型;

③如果double给int送数,原来两个对象都不会改变,只是数据会由3.1变成3;

引用的使用方法如下: 类型表示符 &引用名 = 目标变量名

int i=0, &r1=i;
    double d=0, &r2=d;
    r2=3.1415926;
    std::cout<< d <<"  "<< r2 << std::endl;
    //3.14159  3.14159
    r1=r2;
    std::cout<< r1 <<std::endl;  //3
    i=r2;
    std::cout<< i << std::endl;   //3
    r2 = r1;
    std::cout<< r2 <<std::endl;  //3
    system("pause");

 

2.指针

①指针本身是一个对象;

②指针在生命周期内可以先后指向几个不同的对象;

③指针在定义时不需要赋值;

int *ip1, *ip2;   //ip1和ip2是变量名   两者都是指向int型对象的指针

double dp, *dp2;  //dp是double型的对象,dp2是指向double型对象的指针

 


指针不能指向引用,引用没有地址

 

3.设置空指针

空指针不指向任何对象。

int *p1 = nullptr;            //等价于 int*p1 = 0;  空指针

int *p2=0;                  //将p2初始化为字面常量0

int *p3 = NULL;             //等价于int*p3 = 0;  空指针

根据C++11的新标准,尽量用nullptr不要使用NULL。

 

4.初始化指针

使用指针时务必初始化,不初始化的指针很可能指向一个无意义的数据,最后还被当成有效指针。

 

5.void* 指针

void*指针可以指向任何类型的对象。

double obj = 3.14,*pd =&obj;

void *pv= &obj;

pv=pd;    //pv可以存放任何类型的指针

 

6.符号和意义

int i=42;

int &r=i;           //引用

int *p=&i;          //地址符,指针指向

int p=&i;           //非初始化下的指向

*p=i;              //指向

Int &r2=*p;         //引用

 

7.定义多个变量

int *p;与int* p;表达的含义相同,但是第二种写法会让人产生误解,尽量用第一种写法。

int* p1,p2;   //p1是指向int的指针,p2是int型变量。

 

8.指针的指针

int ival = 1024 ;

int *pi = &ival ;               //pi指向ival

int **ppi = &pi ;              //*ppi指向pi,ppi指向ival

由此可以知道*ppi指向的是pi,那么*(*ppi)就可以越级指向ival,本质还是利用了pi这个指针做桥,最终指向了ival。

 

9.指向指针的引用(不是很懂)

    int i = 42;
    int *p;                   
//指针p
    int *&r = p;              
//r是个引用,这是引用指针的写法
 
    r= &i;                    //r的赋值&i就是令p指向i
    *r= 0;                    //解引用r得到i,也就是p指向的对象,将i的值改为0

与变量名最近的符号对变量有最直接的影响, *&r ,r是一个引用,因为离&更近一些。

 

 

2.4 const限定符

1.const和static

const:

①必须定义就赋值(初始化);

②不可以改变该值;

③在一个文件内声明则一个文件内有效,在全局声明则全局有效;

④其他文件想调用,可以使用extern来使用其他文件调用;

⑤使用引用无法修改const的值,引用必须用const int &r = pi进行引用;

⑥指针指向const对象:const double *ptr = &pi;

static:

①值可以发生改变;

②定义时可以不用初始化;

③该对象在内存始终保留(文件的生命周期内);

#include
<iostream>
static int a = 2;
void run( )
{
    static
int a ;    //重新开内存,a默认为0
    a= 1;            //默认值赋值程为1     
    std::cout << a << std::endl; //结果为1,如果去掉前两行还是2
}
void main()
{
    const
int i = 42;
    run();
    std::cout << i << std::endl;  //const不变为42
    std::cout << a << std::endl;  //全局变量为2
    getchar();
}

结果是1;42;2.

 

2.const指针

    int errNumb = 0;
    int *const a =&errNumb;     //a始终指向int型的errNumb不可更改
    const
double pi = 3.14159;
    const double *const b = π //b始终指向const double型的pi

 

3.顶层const和底层const

简单说顶层const是不可改变的,底层const是可以改变的。

    int errNumb = 0;
    int *const a =&errNumb; //这个const为顶层const,因为a值不可更改,一直指向&errNumb
    const
double pi = 3.14159;
    const double *const b = π

//第一个const是底层const,它是为了让后边的指针指向一个const型的变量存在的

//第二个const是顶层const,因为它保证了b不可改变的指向了pi

 

4.constexpr变量

 

 

2.5 处理类型

1.类型别名typedef

typedef相当于使用另外一个名字,代替之前的名字。

在宏定义中定义:

typedef
int exam_score;
typedef
struct {
    int key;
    char value;
}DataType;

在主函数中定义:

exam_score Math, Chinese,Physics;

它相当于 int Math, Chinese, Physics;

好处:

①隐藏复杂别名,使用更方便;

②允许同一个名字使用多个对象,更便于理解;

③可以自定义一个结构;

 

2.类型别名using

在C++11的新标中加入了新的类型别名方法

宏定义中定义:

using SI =
int;

后续主函数或其他函数中:

    SI c = 10;

相当于:int c = 10;

 

3.类型说明符auto

编程时常常需要把表达式的值赋给变量,这就要求在声明的时候清楚知道表达的类型,但实际上这样很不容易,C++11定义了auto,它可以自动根据其他变量,自动确定变量定义的类型。

using SI =
int;

       SI c = 10,d=20;
    auto f = c + d;

后定义的f自动根据c和d的类型,自动的定义为int型。

在遇到const时,会自动忽略掉顶层的const,保存底层的const。

 

4.类型指示符decltype(没太懂用法)

通过auto可以推断出变量的类型,但是使用auto必须通过计算才有意义。decltype可以不进行计算,直接推断。

 

2.6 定义数据结构

1.头文件

头文件通常包含那些只能被定义一次的实体,例如:

①定义:类、const、constexpr

②外部变量声明、函数的声明

自己写的头文件用<>,自己写的头文件用” ”

#include
<iostream>
#include "sales_item.h"

 

2.预处理器

头文件中可以调用其他头文件,但是其内部,必须使用预处理器。

预处理:

#include <iostream>

它会在执行程序前先按照路径找到这个头文件,进行编译。

 

3.头文件保护符

头文件容易被重复包含,即一个头文件被包含了多次。为了避免这种情况,可以使用头文件保护符。

一般后边的头文件名称都会大写,并且将最后的【 . 】变成【 _ 】。

#ifndefSALES_ITEM_H      
//如果未定义,继续运行
#define
SALES_ITEM_H       //定义sales_item.h文件
#include
<string>
struct
Sales_data
{
    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};
#endif            //结束

 

4.程序设计全过程

①编辑:平台上编写程序

②预处理:#include等,把头文件内容拷贝到源文件中

③编译:转成二进制的机器语言

④链接

⑤运行/执行

 

5.结构体

struct Sales_data
{
    std::stringbookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
}
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: