类型unsigned int可缩写成unsigned
int、char、double这些内置类型,实际上可以看成int类类型、char类类型、double类类型,因为类设计的目的之一是让我们能像使用C++内置类型一样自然地使用类
负数转换为无符号数,结果等于这个负数对无符号类型表示的数值总数(看这个无符号类型所占字节,即2的几字节次方)取模后的余数
2的32次方=4294967296
-32转换为无符号整型数为4294967264(负数加上无符号整型数能表示最大值),-1转换为无符号整型数为4294967295!
‘a’和"a"是不一样的,‘a’只有一个字符a,而"a"有两个字符,分别是’a’和空字符’\0’
初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,而以一个新值来替代。
初始化每一个内置类型的变量
全局作用域本身没有名字,所以如果想在块作用域(有和全局作用域的同名变量的话)访问全局作用域的同名变量,就这么写(也要会认):
::全局作用域的变量名最基本的一点:引用是为对象起了另外一个名字,且引用必须被初始化!
定义引用(&),程序是把引用和它的初始值死绑一起,即不能让引用重新去和别的对象绑定,也不是将初始值拷贝给引用(初始化变量是把初始值拷贝给新建的对象中)
对引用的所有操作都是对这个引用所绑定的对象的操作!
如:
int ival = 1024;
int &refVal = ival;
refVal = 2;//即ival = 2;
int ii = refVal;//即 int ii = ival;
- 最好用nullptr,比如
int *p1=nullptr;这等价于int *p1=0; - 指针的值为0(控制之),则指针作为条件时,条件表达式取false,除此之外条件表达式都取true
- 要理解一个变量(对象)的类型到底是什么,最简单的办法就是从右往左阅读这个变量的定义,离变量名最近的符号对变量的类型有最直接的影响
- 一个对象去初始化另外一个对象,这两个对象是否有const修饰都可,比如:(拷贝一个对象的值是不会改变被拷贝的对象的)
int i=42;
const int ci=i;
int j=ci;
以上三行都正确。
- 多文件使用相同const变量,就对这个const变量不管声明还是定义,都在最前加一个extern,如:(如果想在多个文件之间共享const对象,必须在变量的定义之前添加extern关键字)
//file_1.cpp定义并初始化一个常量,该常量能被其他文件访问
extern const int bufSize=fcn();
//file_1.h
extern const int bufSize;
//与file_1.cpp中定义的bufSize是同一个
- 定义非const的引用不可绑定(指向)一个const对象,但const的引用可以绑定到非const对象上。
- 如
int i=42;const int &r2=i;此意是指不可以通过r2这个引用来修改i的值 - 指针是对象,引用不是对象
关于const指针和引用,通过以下几点可以区分:
- 关于const引用
const int ci=1024;
const int &ri=ci;//正确,引用和其绑定的对象都是const型
ri=42;//错误,const型对象不可变值
int &r2=ci;//非const型引用不可绑定到一个const型对象上!
int i=42;
const int &r1=i;//const型引用可以绑定到非const型对象(注意类型匹配)
const int &r2=42;//const型引用可以被赋值常量(字面值)
const int &r3=r1*2;//对,r3是const型引用,和r1类型一样的
int &r4=r1*2;//错误,r4是非const型引用,不可绑定到const型对象(通过r1这个const型引用)
//刷新,所有定义失效。
int i=42;
int &r1=i;//这两行都没问题,懂得都懂
const int &r2=i;//这个const型引用绑定到普通对象i,
//但是不允许通过r2这个const型引用来改变i的值
r1=0;//对的,相当于i=0;
r2=0;//这行错误,r2为一个const型引用,
//这里体现了不允许通过r2这个const型引用来改变i的值
- 关于const指针
- 注意说法,指向常量(const型对象)的指针如下第3行,这种指针不能用于改变其所指向的对象的值,并且可以存放常量对象的地址
const double pi=3.14;//定义一个const型对象,这个对象的值不可以被改变
double *ptr=π//ptr是一个非const型指针
const double *cptr=π//正确,cptr是指向常量的指针,指向一个双精度型常量(相当于cptr这个指向常量的指针存放常量对象pi的地址)
*cptr=42;//错误,因为cptr是指向常量的指针,这种指针不能用于改变其所指向的对象的值
double dval=3.14;//dval是个普通的双精度型对象,它的值可以被改变
cptr=&dval;//这行正确,但是不能通过cptr这个指向常量的指针来改变dval的值,仅可以存放dval的地址。
- 所以说指向常量的指针可以指向常量/非常量的对象,指向常量的指针说明不能通过该指针来改变对象的值,而可以通过其他途径来改变对象的值。
- 所以说指向常量的指针/引用,指向(或绑定)了常量后,就不能通过指向常量的指针/引用来改变其所指(或绑)对象的值了
int errNumb=0;
int *const curErr=errNumb;//curErr是一个const指针(常量指针,注意,与指向常量的指针有所区分),指向非const对象errNumb
const double pi=3.14159;
const double *const pip=π//pip是指向常量(对象)的常量指针
*pip-2.74;//错误,pip是指向常量的常量指针,不可改变其所指的对象的值
if(*curErr)
{
errorHandler();
*curErr=0;//正确,curErr常量指针指向一个普通对象(int errNumb=0;),
//所以可以通过curErr这个常量指针来修改它所指向的普通对象的值
}
- 好了,下面说明一下const指针(常量指针)
常量指针必须初始化,也就是必须给它赋值一个对象的地址,初始化完成,这个常量指针存放的地址就不可再改变!
*放在const前(如int *const curErr=errNumb)意味着不变的是指针本身的值,这个常量指针指向的对象如果不是const型,对象的值还是可以改变的(通过其他途径)!
指向常量的常量指针,不论是常量指针所指的对象值还是常量指针自己存储的地址,都是不可以被改变的!
如果指向非常量(对象)的常量指针,那么可以通过*常量指针=...的方式改变非常量对象 - 重要的一点,弄清楚上述的声明的含义,最好的办法是一行从右往左读。
- 编译器以引用的对象的类型作为auto的类型
- auto一般忽略掉顶层const,如果希望推断出的auto类型是一个顶层const,则需这么写:
const auto f=ci;//之前有一个const int ci=i;因auto忽略顶层const的特性,
//ci的推演类型是int,所以f的推演类型是const int
- 类体后面(以struct形式定义的类的{}后)可以紧跟变量名,以示对该(类)类型对象的定义。
- 类定义体后分号忘写,会出现以下情况

- 类所在头文件的名字应与类的名字一样
- 头文件的内容被修改后,相关(包含该头文件的)源文件必须重新编译以获取更新过的声明。
- 预处理变量(比如#define 什么什么。。。)无视C++中关于作用域的规则
- 预处理变量名必须大写,而且整个程序中的预处理变量包括头文件保护符(#ifdef、#ifndef、#endif、#define等)必须唯一,并且每个头文件都加上这些头文件保护符
- 基于头文件中类的名字来构建保护符的名字,如:
//在sales_data.h这个类头文件中
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include<string>
struct Sales_data{
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
#endif
版权声明:本文为weixin_45910408原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。