任何常用的编程语言都具备一组公共的语法特征,最基本的特征包括:
- 整型、字符型等内置类型
- 变量,用来为对象命名
- 表达式和语句,用于操作上述数据类型的具体值
- if 或 while 等控制结构,有选择地执行一些语句或重复地执行一些语句
- 函数,用于定义可供随时调用的计算单元
大多数编程语言通过两种方式来进一步补充其基本特征:
- 自定义数据类型,实现对语言的扩展
- 将一些有用的功能封装成库函数
基本内置类型
基本算数类型:
类型 | 含义 | 最小尺寸 |
---|---|---|
bool | 布尔类型 | 8bits |
char | 字符 | 8bits |
wchar_t | 宽字符 | 16bits |
char16_t | Unicode字符 | 16bits |
char32_t | Unicode字符 | 32bits |
short | 短整型 | 16bits |
int | 整型 | 16bits (在32位机器中是32bits) |
long | 长整型 | 32bits |
long long | 长整型 | 64bits (是在C++11中新定义的) |
float | 单精度浮点数 | 6位有效数字 |
double | 双精度浮点数 | 10位有效数字 |
long double | 扩展精度浮点数 | 10位有效数字 |
如何选择类型
-
- 当明确知晓数值不可能是负数时,选用无符号类型;
-
- 使用int执行整数运算。一般long的大小和int一样,而short常常显得太小。除非超过了int的范围,选择long long。
-
- 算术表达式中不要使用char或bool。
-
- 浮点运算选用double。
类型转换
- 非布尔型赋给布尔型,初始值为0则结果为false,否则为true。
- 布尔型赋给非布尔型,初始值为false结果为0,初始值为true结果为1。
字面值常量
- 一个形如 42 的值被称为字面值常量(literal)。
- 整型和浮点型字面值。
- 字符和字符串字面值。
- 使用空格连接,继承自C。
- 字符字面值:单引号, 'a'
- 字符串字面值:双引号, "Hello World"
- 分多行书写字符串。
std:cout<<"wow, a really, really long string" "literal that spans two lines" <<std::endl;
- 转义序列。
\n
、\t
等。 - 布尔字面值。
true
,false
。 - 指针字面值。
nullptr
字符串型实际上时常量字符构成的数组,结尾处以'\0'结束,所以字符串类型实际上长度比内容多1。
变量
变量提供一个具名的、可供程序操作的存储空间。 C++中变量和对象一般可以互换使用。
变量定义(define)
- 定义形式: 类型说明符(type specifier) + 一个或多个变量名组成的列表。如int sum = 0, value, units_sold = 0;
- 初始化: 对象在创建时获得了一个特定的值。
- 初始化不是赋值!:
- 初始化 = 创建变量 + 赋予初始值
- 赋值 = 擦除对象的当前值 + 用新值代替
- 列表初始化:使用花括号{},如int units_sold{0};
- 默认初始化:定义时没有指定初始值会被默认初始化;在函数体内部的内置类型变量将不会被初始化。
- 建议初始化每一个内置类型的变量。
变量的声明(declaration) vs 定义(define)
- 为了支持分离式编译,C++将声明和定义区分开。声明使得名字为程序所知。定义负责创建与名字关联的实体。
- extern: 只是说明变量定义在其它地方
- 只声明而不定义: 在变量名前添加关键字
extern
,如extern int i
;。但如果包含了初始值,就变成了定义:extern double pi = 3.14
; - 变量只能被定义一次,但是可以多次声明。定义只出现在一个文件中,其他文件使用该变量时需要对其声明。
- 名字的作用域(namescope)
{}
- 第一次使用变量时再定义它。
- 嵌套的作用域
- 同时存在全局和局部变量时,已定义局部变量的作用域中可用::reused显式访问全局变量reused。
- 但是用到全局变量时,尽量不适用重名的局部变量。
变量命名规范
- 需体现实际意义
- 变量名用小写字母
- 自定义类名用大写字母开头:
Sales_item
- 标识符由多个单词组成,中间须有明确区分:
student_loan
或studentLoan
,不要用studentloan
。
左值和右值
- 左值(l-value)可以出现在赋值语句的左边或者右边,比如变量;
- 右值(r-value)只能出现在赋值语句的右边,比如常量。
复合类型
引用
一般说的引用是指的左值引用
- 引用:引用是一个对象的别名,引用类型引用(refer to)另外一种类型。如
int &refVal = val
;。 - 引用必须初始化。
- 引用和它的初始值是绑定bind在一起的,而不是拷贝。一旦定义就不能更改绑定为其他的对象
指针
int *p;
//指向int型对象的指针
- 是一种 "指向(point to)"另外一种类型的复合类型。
- 定义指针类型:
int *ip1;
,从右向左读有助于阅读,ip1是指向int类型的指针。 - 指针存放某个对象的地址。
- 获取对象的地址: int i=42; int *p = &i;。 &是取地址符。
- 指针的类型与所指向的对象类型必须一致(均为同一类型int、double等)
- 指针的值的四种状态:
- 1.指向一个对象;
- 2.指向紧邻对象的下一个位置;
- 3.空指针;
- 4.无效指针。
- 对无效指针的操作均会引发错误,第二种和第三种虽为有效的,但理论上是不被允许的
- 指针访问对象: cout << *p;输出p指针所指对象的数据, *是解引用符。
- 空指针不指向任何对象。使用int *p=nullptr;来使用空指针。
- 指针和引用的区别:引用本身并非一个对象,引用定义后就不能绑定到其他的对象了;指针并没有此限制,相当于变量一样使用。
- 赋值语句永远改变的是左侧的对象。
void*
指针可以存放任意对象的地址。因无类型,仅操作内存空间,对所存对象无法访问。- 其他指针类型必须要与所指对象严格匹配。
- 两个指针相减的类型是
ptrdiff_t
。 - 建议:初始化所有指针。
int* p1, p2;
//*是对p1的修饰,所以p2还是int型
const限定符
- 动机:希望定义一些不能被改变值的变量。
初始化和const
- const对象必须初始化,且不能被改变。
- const变量默认不能被其他文件访问,非要访问,必须在指定const定义之前加extern。要想在多个文件中使用const变量共享,定义和声明都加const关键字即可。
const的引用
- reference to const(对常量的引用):指向const对象的引用,如
const int ival=1; const int &refVal = ival;
,可以读取但不能修改refVal
。 - 临时量(temporary)对象:当编译器需要一个空间来暂存表达式的求值结果时,临时创建的一个未命名的对象。
- 对临时量的引用是非法行为。
指针和const
- pointer to const(指向常量的指针):不能用于改变其所指对象的值, 如
const double pi = 3.14; const double *cptr = π
。 - const pointer:指针本身是常量,也就是说指针固定指向该对象,(存放在指针中的地址不变,地址所对应的那个对象值可以修改)如
int i = 0; int *const ptr = &i;
顶层const
顶层const
: 指针本身是个常量。底层const
: 指针指向的对象是个常量。拷贝时严格要求相同的底层const资格。
constexpr
和常量表达式(▲可选)
- 常量表达式: 指值不会改变,且在编译过程中就能得到计算结果的表达式。
C++11
新标准规定,允许将变量声明为constexpr
类型以便由编译器来验证变量的值是否是一个常量的表达式。
处理类型
类型别名
- 传统别名:使用typedef来定义类型的同义词。
typedef double wages;
- 新标准别名:别名声明(alias declaration):`using SI = Sales_item;(C++11)
// 对于复合类型(指针等)不能代回原式来进行理解
typedef char *pstring; // pstring是char*的别名
const pstring cstr = 0; // 指向char的常量指针
// 如改写为const char *cstr = 0; // 不正确,为指向const char的指针
// 辅助理解(可代回后加括号)
// const pstring cstr = 0;代回后const (char *) cstr = 0;
// const char *cstr = 0;即为(const char *) cstr = 0;
auto类型说明符 c++11
- auto类型说明符:让编译器自动推断类型。
- 一条声明语句只能有一个数据类型,所以一个auto声明多个变量时只能相同的变量类型(包括复杂类型&和*)。
auto sz = 0, pi =3.14//错误
int i = 0, &r = i; auto a = r;
推断a
的类型是int
。- 会忽略
顶层const
。 const int ci = 1; const auto f = ci;
推断类型是int
,如果希望是顶层const需要自己加const
decltype类型指示符
- 从表达式的类型推断出要定义的变量的类型。
- decltype : 选择并返回操作数的数据类型。
decltype(f()) sum = x;
推断sum
的类型是函数f
的返回类型。- 会忽略
顶层const
。 - 如果对变量加括号,编译器会将其认为是一个表达式,如int i-->(i),则decltype((i))得到结果为int&引用。
- 赋值是会产生引用的一类典型表达式,引用的类型就是左值的类型。也就是说,如果 i 是 int,则表达式 i=x 的类型是 int&。
C++11
自定义数据结构
struct
尽量不要吧类定义和对象定义放在一起。如 struct Student{} xiaoming,xiaofang;
- 类可以以关键字
struct
开始,紧跟类名和类体。 - 类数据成员:类体定义类的成员。
C++11
:可以为类数据成员提供一个类内初始值(in-class initializer)。
编写自己的头文件
- 头文件通常包含哪些只能被定义一次的实体:类、
const
和constexpr
变量。
预处理器概述: - 预处理器(preprocessor):确保头文件多次包含仍能安全工作。
- 当预处理器看到#include标记时,会用指定的头文件内容代替
#include
- **头文件保护符&&(header guard):头文件保护符依赖于预处理变量的状态:已定义和未定义。
#indef
已定义时为真#inndef
未定义时为真- 头文件保护符的名称需要唯一,且保持全部大写。养成良好习惯,不论是否该头文件被包含,要加保护符。
#ifndef SALES_DATA_H // //SALES_DATA_H未定义时为真
#define SALES_DATA_H
struct Sale_data{
...
}
#endif
标签:const,定义,int,笔记,类型,变量,指针
From: https://www.cnblogs.com/sys-123456/p/18550819