【C++ grammar】常量、指针、Usage of using, typedef, and #define

1、常量 (Constant)

常量是程序中一块数据,这个数据一旦声明后就不能被修改了。

如果这块数据有一个名字,这个名字叫做命名常量;比如 const int A = 42; 其中A就是命名常量;
如果这块数据(这个常量)从字面上看就能知道它的值,那它叫做“字面常量”,比如上面例子中的“42”就是字面常量

//const datatype CONSTANTNAME = VALUE;
const double PI = 3.14159;
const int SIZE = 3;
int const X = 5;
const char C = 'k';
const char* STR = "Hello";		//字符串常量Hello放在常量区,而且是一个指针类型,所以必须加上const

如果我们对PI进行赋值操作,会报错:表达式必须是可以修改的左值。
关于这个问题详细的讲解见:
1、https://blog.csdn.net/qq_42604176/article/details/108909002
2、https://blog.csdn.net/JQ_AK47/article/details/53169799

2、指针(Pointer)

指针有两个属性:
1、指针变量本身
2、指针变量指向的数据
在这里插入图片描述
在这里插入图片描述

int y = 10;
const int x=5;
const int* p =&x; 
p = &y;				//不会报错
*(p) = y;       //报错

解释:由于x是个常量,所以它的值不可以被改变,也就是说地址不能修改,也就是说p存的地址是个常量,所以要加const。p可以指向其他变量

int x=5;
int* const  p =&x; 

解释:p指针是个常量,它不能指向其他变量了。但是它指向的数据x是可以改变值的。

const int x=5;
const int* const  p =&x; 

解释:x是个常量,p也是个常量,不能指向其他变量了
在这里插入图片描述
指针是一个地址,它长得像 0x8FFF 这个样子。地址呢,就是某个内存位置的一个编号。那这个位置的内存是可以存放一些数据的。这些数据就叫做“指针所指的数据”或者“指针指向的数据”。
一些概念:

我们把指针放到一个变量里面,就是指针变量
我们把指针放到常量中,就是指针常量

那如果一个指针(也就是地址,比如0x8FFF)所指的数据(也就是0x8FFF这个内存位置存放的数据)是常量,这个指针被称为常量指针
所以,有一种东西,叫做“常量指针常量”。就是说,一个常量中存着一个指针,这个指针又指向另外一个常量。

Pointer to Constant (常量指针/常指针)
特征:指针所指向的内容不可以通过指针的间接引用(*p)来改变。

const int x = 1;
const int* p1;
p1 = &x;        //指针p1类型是const int*
*p1 = 10;		//Error:表达式必须是可以修改的左值。

Pointer Constant (指针常量)
指针常量”的含义是:指针本身的内容是个常量,不可以改变

int x = 1, y = 1;
int* const p2 = &x;     //常量p2的类型是(int *)
*p2 = 10;               //okay->x=10
p2 = &y;                //Error:p2是一个常量:表达式必须是可以修改的左值。

小结
从左往右看,先看到 * 即为常量指针,先看到const 即为指针常量。
const int * x
int * const y
在这里插入图片描述
问题:请你尝试解释下面代码中的 pp 是个什么东西?

int x = 0, * const px = &x;
const int* const &pp = px;

引用。px的别名,px是指针常量,pp是常指针常量

3、Usage of using, typedef, and #define

1、#define是预处理指示符,用来定义宏,编译器不做检查
2、typedef 创建能在任何位置
C++11中为 using 关键字赋予了一个类型声明的新功能

using ConstPointer = const unsigned long int *;
ConstPointer p;

ConstPointer q;

ConstPointer r;
using UInt = unsigned int;
UInt x = 42u;
//表明这是一个指向函数的指针,它是一个类型
using FuncType = void(*) (int,int);
void example(int,int) {
    
    }
//f是变量
FuncType f = example;
//这里的using替代typedef =>等同于typedef void (*FuncType) (int,int);

这里的using是为了解决类型别名的问题。
之前我们遇到过这样的语句:

using std::cin;

表明将std空间的cin标识符引入到当前的程序里面来。cin是一个对象而不是一个类型。
所以如果我们这么写:

using in = std::cin;

编译器会报错。
using与typedef的区别
typedef是把类型放在前面,而简写的别名放在后面
如:typedef 类型 简写的别名;
using用法:
using 简写的类型别名 = 类型;
这样类似于赋值的语法很直观。
using的写法比typedef的写法更加直观,所以,我们应尽量使用using声明新类型名。而且当涉及到模版类型名时,只能使用using。
编码规范:
Names representing types must be in mixed case starting with upper case.
代表类型的名字必须首字母大写并且其它字母大小写混合

猜你喜欢

转载自blog.csdn.net/qq_42604176/article/details/108910244