知识导图 知识导图
首页
iOS知识
计算机软件
  • 即时通讯网 (opens new window)
  • 开发常用网站 (opens new window)
首页
iOS知识
计算机软件
  • 即时通讯网 (opens new window)
  • 开发常用网站 (opens new window)
  • MD

  • Vue

  • C语法

  • C++语法

    • C++基础概念(上)
      • 基础概念
        • 版本、库历史
        • 编译器安装
        • Hello World
        • 编译 & 执行
        • 语句结束符
        • 代码块
        • 命名规范
        • 关键字
        • 三字符组
        • 注释
        • 日期 & 时间
      • 数据
        • 数据类型
        • typedef 别名
        • 枚举类型
        • 【变量、常量】
        • 左值、右值
        • 局部变量
        • 全局变量
        • 整数常量
        • 浮点常量
        • 布尔常量
        • 字符常量
        • 字符串常量
        • [#define] 预处理器
        • const 常量
      • 数据修饰符
        • 类型限定符
        • 存储类
        • 存储修饰: auto
        • 存储修饰: register
        • 存储修饰: static
        • 存储修饰: extern
        • 存储修饰: mutable
      • 数据运算
        • 数据占用大小
        • 字节、字、位、比特
        • 【运算符】
        • 运算符:算术
        • 运算符:关系
        • 运算符:逻辑
        • 运算符:位运算
        • 运算符:赋值
        • 运算符:其他
        • 运算符:优先级
        • 【运算逻辑】
        • 运算:原码、反码、补码
        • 运算:正、负
        • 运算:加、减
    • C++基础概念(下)
    • C++语法速查
    • C++面向对象(上)
    • C++面向对象(下)
    • C++高级教程(上)
    • C++高级教程(中)
    • C++高级教程(下)
  • 汇编语言

  • 软件编程及算法
  • C++语法
2023-05-31
目录

C++基础概念(上)

# 基础概念

1、静态编译类型,非动态(OC默认动态,Swift默认是静态)

2、区分大小写(敏感)

3、支持面向过程编程、面向对象编程和泛型编程(Swift支持泛型编程)

4、介于低级语言和高级语言之间

5、兼容大部分中低版本的C语法

6、面向对象四大特性:封装、抽象、继承、多态

7、标准库: C++ 三部分组成

基础语言、变量、数据类型和常量,等等

大量的 标准库函数,操作文件、字符串等

标准模板库操作数据结构等

8、通用性:一般C++代码在 Mac、UNIX、Windows、Alpha 计算机上都能通过编译

9、C++ 程序的源文件通常使用扩展名 .cpp(默认)、.cp 或 .c(少)

10、编译器: GNU 的 gcc 编译器适合于 C 和 C++ 编程语言的编译

11、基本语法组成:类对象、方法、变量

# 版本、库历史

发布时间 通称 备注
2020 C++20 第六个C++标准
2017 C++17 第五个C++标准
2017 coroutines TS 协程库扩展
2017 ranges TS 提供范围机制
2017 library fundamentals TS 标准库扩展
2016 concurrency TS 用于并发计算的扩展
2015 concepts TS 概念库,用于优化编译期信息
2015 TM TS 事务性内存操作
2015 parallelism TS 用于并行计算的扩展
2015 filesystem TS 文件系统
2014 C++14 第四个C++标准
2011 - 十进制浮点数扩展
2011 C++11 第三个C++标准
2010 - 数学函数扩展
2007 C++TR1 C++技术报告:库扩展
2006 - C++性能技术报告
2003 C++03 第二个C++标准
1998 C++98 第一个C++标准

# 编译器安装

GNU 的 C/C++

Linux 或 UNIX 安装 GCC,按照 http://gcc.gnu.org/install/ (opens new window) 安装

Mac OS X,苹果系统的Xcode 会携带

Xcode 目前可从 developer.apple.com/technologies/tools/ (opens new window) 上下载

Windows 上安装 GCC,要安装 MinGW,请访问 MinGW 的主页 www.mingw.org (opens new window)

# Hello World

#include <iostream> // 引入支持输入输出的库
using namespace std; // 命名空间

int main(){ // 程序开始执行入口函数
    cout << "Hello World"; // cout 输出
    return 0; 
} 

# 编译 & 执行

1、将上面代码保存文件为 hello.cpp

2、gcc编译文件,并默认生成 a.out可执行文件
$ g++ hello.cpp  

3、键入' a.out' 来运行程序
$ ./a.out

4、屏幕上显示
Hello World

也可以使用 makefile 来编译 C/C++ 程序

# 语句结束符

分号是语句结束符。

int a = 1;

# 代码块

块是一组使用大括号括起来的按逻辑连接的语句

{
    cout << "Hello World"; // 输出 Hello World
    return 0;
} 

# 命名规范

标识符规范:

标识变量、函数、类、模块,或任何其他用户自定义项目的名称。

以字母 A-Z 或 a-z 或下划线 _ 开始,后跟零个或多个字母、下划线和数字(0-9)

不允许出现标点字符,比如 @、$ 和 %。

命名区分大小写

# 关键字

关键字,就是被系统占用的名称,需要取其它名称,避开它

asm else new this
auto enum operator throw
bool explicit private true
break export protected try
case extern public typedef
catch false register typeid
char float reinterpret_cast typename
class for return union
const friend short unsigned
const_cast goto signed using
continue if sizeof virtual
default inline static void
delete int static_cast volatile
do long struct wchar_t
double mutable switch while
dynamic_cast namespace template

# 三字符组

通过?? 加上符号来表示另一个符号,这很少有,通常编译器也不支持,g++支持但是会警告。

三字符组 替换
??= #
??/ \
??' ^
??( [
??) ]
??! |
??< {
??> }
??- ~

假如开启了三字符编译,??= 字符串该如何表示? 使用 ??=

# 注释

三种注释区别:

#include <iostream>
using namespace std;

/* 注释
 * 可以跨行
 */
int main()
{
   /* 单行局部注释,后面代码有效 */ int a = 2;
	
   // 输出 Hello World!( 后面所有代码都是注释范围 )
   cout << "Hello World!"; 
 
   return 0;
}

# 日期 & 时间

获取当前系统的日期和时间,包括本地时间和协调世界时(UTC)。

#include <iostream>
#include <ctime>

using namespace std;

int main(){
    // 基于当前系统的当前日期/时间
    time_t now = time(0);
    cout << "1970年1月1日到目前经过的秒数:" << now << endl;

    tm *ltm = localtime(&now);

    // 输出 tm 结构的各个组成部分
    cout << "年: "<< 1900 + ltm->tm_year << endl;
    cout << "月: "<< 1 + ltm->tm_mon<< endl;
    cout << "日: "<<  ltm->tm_mday << endl;
    cout << "时间: "<< 1 + ltm->tm_hour << ":";
    cout << 1 + ltm->tm_min << ":";
    cout << 1 + ltm->tm_sec << endl;
} 

结果:

1970年1月1日到目前经过的秒数:1688304716
年: 2023
月: 7
日: 2
时间: 14:32:57

# 数据

# 数据类型

1、系统类型

类型 关键字
布尔型 bool
字符型 char
整型 int
浮点型 float
双浮点型 double
无类型 void
宽字符型 wchar_t

2、基本类型修饰符:(可以使用一个或多个)

  • signed
  • unsigned
  • short
  • long

3、变量类型占用的内存(不同系统会有所差异)

类型 位 范围
char 1 个字节 -128 到 127 或者 0 到 255
unsigned char 1 个字节 0 到 255
signed char 1 个字节 -128 到 127
int 4 个字节 -2147483648 到 2147483647
unsigned int 4 个字节 0 到 4294967295
signed int 4 个字节 -2147483648 到 2147483647
short int 2 个字节 -32768 到 32767
unsigned short int 2 个字节 0 到 65,535
signed short int 2 个字节 -32768 到 32767
long int 8 个字节 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
signed long int 8 个字节 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
unsigned long int 8 个字节 0 到 18,446,744,073,709,551,615
float 4 个字节 精度型占4个字节(32位)内存空间,+/- 3.4e +/- 38 (~7 个数字)
double 8 个字节 双精度型占8 个字节(64位)内存空间,+/- 1.7e +/- 308(~15 个数字)
long double 16 个字节 长双精度型 16 个字节(128位)内存空间,可提供18-19位有效数字。
wchar_t 2 或 4 个字节 1 个宽字符

sizeof:获取类型内存大小

#include <iostream>
using namespace std;

int main()
{
   cout << "Size of char : " << sizeof(char) << endl;
   cout << "Size of int : " << sizeof(int) << endl;
  
   return 0;
}

# typedef 别名

使用 typedef 为一个已有的类型取一个新的名字(别名)

#include <iostream>
using namespace std;


int main()
{
   typedef int count; // 取别名,下面可以用Count 替换 int
   count min = 3;
   cout << "min =" << min << endl; 
 
   return 0;
}

结果

min =3

# 枚举类型

#include <iostream>
using namespace std;

int main()
{
  enum RGB { 
    red, 
    green, 
    blue 
  } rgb1, rgb2, rgb3;
   
  rgb1 = red;
  rgb2 = green;
  rgb3 = blue;

  cout << "RGB:" << rgb1 << endl; 
  cout << "RGB:" << rgb2 << endl;
  cout << "RGB:" << rgb3 << endl;
 
  return 0;
}

结果:

RGB:0
RGB:1
RGB:2

默认情况下,第一个枚举值为 0,第二个枚举值为 1,第三个枚举值为 2,以此递增。

可以尝试设置某个值

# 【变量、常量】

包括基础数据类型变量、枚举、指针、数组、引用、数据结构、类等等

未初始化阶段:

1、数据类型声明通常都是0

2、对象类型声明通常默认NULL

#include <iostream>
using namespace std;

// 变量声明:extern 关键字允许函数体外声明变量
extern int a, b;
  
// 函数声明
int func_area(int a, int b);

int main ()
{
    // 变量定义, 此时变量还是0
    int a, b;
 
    // 实际初始化
    a = 10;
    b = 20;
 
    cout << func_area(a, b) << endl ;
  
    return 0;
} 

// 函数定义(如果没有函数声明,那么文件上面的代码不能调用,通常函数编译时能读取上面的定义)
int func_area(int a, int b)
{
    return a*b;
}

# 左值、右值

左值(Lvalues)和右值(Rvalues)

通常对象是左值,数据是右值

int a = 10; // a 是左值, 10 是右值
int b = a; // a 是右值

# 局部变量

在函数或一个代码块内部声明的变量,称为局部变量:

int main ()
{
    // 局部变量声明
    int a, b;
    
    return 0; 
} 

# 全局变量

函数外部定义的变量(通常是在程序的头部),称为全局变量。

程序的整个生命周期内都是有效的。

全局变量可以被任何函数访问。

#include <iostream>
using namespace std;
 
// 全局变量
int g = 4;

void print_g() {
	cout << "g=" << g << endl; // 取的是全局变量g,不可能访问main函数内的g变量,作用域限制的。
}

int main ()
{
    // 局部变量
    int g = 2;

    print_g();
	
    cout << "g=" << g << endl; // 取当前函数内的局部变量g
    return 0;
 } 

结果

g=4
g=2

⚠️ 都是打印g 结果不一样,一个取的是全局变量g。一个取当前函数内的局部变量g

# 整数常量

常量:固定的值,又叫做字面量。

例:

85         // 十进制
0213       // 八进制 
0x4b       // 十六进制 
30         // 整数 
30u        // 无符号整数 
30l        // 长整数 
30ul       // 无符号长整数

212         // 合法的
215u        // 合法的
0xFeeL      // 合法的
078         // 非法的:8 不是八进制的数字
032UU       // 非法的:不能重复后缀

# 浮点常量

例:

3.14159       // 合法的 
314159E-5L    // 合法的 
510E          // 非法的:不完整的指数
210f          // 非法的:没有小数或指数
.e55          // 非法的:缺少整数或分数

# 布尔常量

  • true 值代表真(不是1)
  • false 值代表假(不是0)

在Object-C中有值且非0表示真,否则都是假

Swift同C++,bool都是表示真假

# 字符常量

转义序列 含义
\ \ 字符(转义字符表示后面的内容特殊含义)
' ' 字符
" " 字符
? ? 字符
\a 警报铃声
\b 退格键
\f 换页符
\n 换行符
\r 回车
\t 水平制表符
\v 垂直制表符
\ooo 一到三位的八进制数
\xhh . . . 一个或多个数字的十六进制数

# 字符串常量

下面这三种形式所显示的字符串是相同的:

#include <iostream>
using namespace std;

int main ()
{
	string a = "hello, string";

	string b = "hello, \
string";

	string c ="hello" ", " "string";
	
  cout << "字符串a=" << a << endl;
	cout << "字符串b=" << b << endl;
	cout << "字符串c=" << c << endl;
	
    return 0;
 } 

结果:

字符串a=hello, string
字符串b=hello, string
字符串c=hello, string

# [#define] 预处理器

预处理#define : 定义常量的一种方式, 不可修改,不能使用变量

例:

#include <iostream>
using namespace std;

// 宏定义
#define kWidth 39

int main()
{
   cout << kWidth;
   return 0;
}

# const 常量

例:

#include <iostream>
using namespace std;

int main()
{
   const int kWidth = 39; // 定义const常量,不可修改
   cout << kWidth;
   return 0;
} 

⚠️

const常量,不可修改,否则 error: assignment of read-only variable ‘kWidth’

# 数据修饰符

1、数据类型修饰符可以限制数据类型的精度和符号

2、修饰符 signed、unsigned、long 和 short 可应用于整型,

3、signed 和 unsigned 可应用于字符型,

4、long 可应用于双精度型。

5、也可以双修饰

例如:unsigned long int。

6、特殊修饰

可以不写 int 而表示整型:只写单词 unsigned short 或 unsigned long,int 是隐含的

# 类型限定符

类型限定符提供了变量的额外信息。

限定符 含义
const 编译器开始就是固定的,不可修改
volatile 修饰符 volatile 告诉编译器,变量的值不确定的(不会缓存,每次都会重新获取)
restrict 由 restrict 修饰的指针是唯一一种访问它所指向的对象的方式。只有 C99 增加了新的类型限定符 restrict。

# 存储类

存储类:限定变量/函数的范围(可见性)和生命周期。

# 存储修饰: auto

auto 存储类是所有局部变量默认的存储类,可以不记

{
   int a;
   auto int b;
}

# 存储修饰: register

通常定义存储在寄存器中,用于需要快速访问的变量

{
   register int  m;
}

# 存储修饰: static

static 修饰符也可以应用于局部(函数体内)、全局变量(当前文件内访问)。

static 修饰变量是被类共享的,多个对象,不同函数体内读取的都是同一份

# 存储修饰: extern

extern :

1、字面意思:外部链接的,也即是可供其他文件使用

2、存储类全局变量的引用,它是跨文件访问的,不只是当前文件访问

//file1
extern const int a = 88; //声明并定义拥有外部链接的全局常量a,供外部文件file2访问

//file2
extern const int a; //声明全局常量a, 但是定义是来自于file1或其他文件的,当前文件拿来使用

# 存储修饰: mutable

mutable :

1、表示修饰成员是可以修改的,通常需要和const(常量的)结合使用

2、仅适用于类的对象

3、通常使用场景:const 修饰的成员函数内修改的变量需要是mutable修饰的,否则编译错误(因为const修饰后,原本默认可修改的成员调用时都相当于被const修饰,除非显式mutable修饰)

4、const修饰成员函数

const修饰成员函数的时候,const需要放在成员函数的后面,不能放在一开始,,若是放在一开始的话,那么const修饰的是函数的返回值,而非是修饰成员函数了

(示例不是很恰当)

#include <iostream>
#include <ctime>
using namespace std;


class Person
{
   public:
      string name;  
      int borth_year;
      mutable int age;  // 年龄

      // const修饰成员函数(非mutable修饰的成员均不能在此函数内存在修改行为)
      void desc() const {
        time_t curtime;
        time(&curtime);
        tm *nowtime = localtime(&curtime);
        // 如果 age 没有mutable修饰,那么这里就会报错
        age = 1900 + nowtime->tm_year - borth_year;
        cout << "姓名:" << name <<endl;
        cout << "年龄:" << age <<endl;
      }
};

int main( )
{
    Person person;
    person.name = "小明";
    person.borth_year = 2018;
    person.desc();
   
   return 0;
}

结果:

姓名:小明
年龄:5

上述示例中,const 成员函数中可以修改 mutable 修饰可变成员 age。

但是早先mutable 是不支持的,我们进行如下改造:

#include <iostream>
#include <ctime>

using namespace std;

class Person
{
    public:
      string name;  
      int borth_year;
		
		Person(string n, int y);
		
		int age() const { // const修饰成员函数
			time_t curtime;
			time(&curtime);
			tm *nowtime = localtime(&curtime);
			return 1900 + nowtime->tm_year - borth_year;
		}
	
    // const修饰成员函数
    void desc() const {
       cout << "姓名:" << name <<endl;
       cout << "年龄:" << age() <<endl;
    }
};

Person::Person(string n, int y) {
		name = n;
		borth_year = y;
	}

int main( )
{
   Person person("小树", 2018);
   
   person.desc();
   
   return 0;
}

结果:

姓名:小树
年龄:5

# 数据运算

不同数据类型,不同系统,以及相同系统下不同算法优化 下所占用的内存大小均可能不相同

# 数据占用大小

常见数据类型不同系统内存大小:

数据类型 16位系统(占字节数) 32位系统(占字节数) 64位系统(占字节数)
char 1(个字节,下同) 1 1
short 2 2 2
int 2 4 4
unsigned int 2 4 4
float 4 4 4
double 8 8 8
long 4 4 8
long long 8 8 8
unsigned long 4 4 8
指针 2 4 8
最大数据范围 2^16 2^32 2^64

# 字节、字、位、比特

1字母a = 1 byte = 8 bit = 8 位二进制数

1 汉字 = 2 个字节byte = 16 字节bit(2*8) = 16 位二进制数

# 1、位

计算机都是二进制数,由0和1表示

1001 为4位

# 2、比特(bit)

表示二进制位的单位

1001 为4 bit

# 3、字节(byte)

字节(byte)是组成文字和字母的单位

1 byte = 8 bit = 8 位二进制数

# 4、字

比如汉字 “中国” 包含两个字,一个字占两个 “字节 ”, “中国” 字符串占 4个字节

比如字母 “abc” 占3个字节,也就是每个字母占一个字节

1字母a = 1 byte = 8 bit = 8 位二进制数

1 汉字 = 2 个字节byte = 16 字节bit(2*8) = 16 位二进制数

# 5、字块(连续的字)

多个文字或者字母等组成的内容为一个字块

比如磁道上的字群就称为一个字块。在磁带上通常每120个字符就间隔一个字块际志,也称为一个字块

# 6、字长(长度度量)

“中国” 两个字,

字节(byte)为度量单位时,字长为4个字节的长度

比特(bit)为度量单位时,字长为4*8=32个 bit的长度

# 【运算符】

# 运算符:算术

算术运算符:

运算符 描述 实例
+ 把两个操作数相加 A + B
- 从第一个操作数中减去第二个操作数 A - B
* 把两个操作数相乘 A * B
/ 分子除以分母 B / A
% 取模运算符,整除后的余数 B % A
++ 自增运算符,整数值增加 1 A++
-- 自减运算符,整数值减少 1 A--

# 运算符:关系

关系运算符:

运算符 描述 实例
== 值相等则条件为真,否则假 (A == B)
!= 值不相等则条件为真,否则假 (A != B)
> 值大于则条件为真,否则假 (A > B)
< 值小于则条件为真,否则假 (A < B)
>= 值大于或等于则条件为真,否则假 (A >= B)
<= 值小于或等于则条件为真,否则假 (A <= B)

# 运算符:逻辑

关系逻辑运算符:

运算符 描述 实例
&& 左右均为真,则条件为真。 (A && B)
|| 左右至少一个为真,则条件为真 (A || B)
! 取反 !A

# 运算符:位运算

位运算符(二进制操作):

运算符 描述 实例
& 同位数操作,都是1计算为1,否则0 101 & 11 = 101
| 同位数操作,至少一个1,则1 10 | 11 = 11
^ 不相同的值为1,相同为0 1^1=0;0^1=1;1^0=1;0^0=0
~ 二进制取反运算符:"翻转"位效果,依赖数据类型 ~ 0010 = 1101
<< 二进制左移运算符 11 << 2 为 1100
>> 二进制右移运算符 11 >> 2 为 0

位运算符作用于位,并逐位执行操作。&、 | 和 ^ 的真值表如下所示:

p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

# 运算符:赋值

下表列出了 C++ 支持的赋值运算符:

运算符 描述 实例
= 简单的赋值运算符,把右边操作数的值赋给左边操作数 C = A + B 将把 A + B 的值赋给 C
+= 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 C += A 相当于 C = C + A
-= 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 C -= A 相当于 C = C - A
*= 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 C *= A 相当于 C = C * A
/= 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 C /= A 相当于 C = C / A
%= 求模且赋值运算符,求两个操作数的模赋值给左边操作数 C %= A 相当于 C = C % A
<<= 左移且赋值运算符 C <<= 2 等同于 C = C << 2
>>= 右移且赋值运算符 C >>= 2 等同于 C = C >> 2
&= 按位与且赋值运算符 C &= 2 等同于 C = C & 2
^= 按位异或且赋值运算符 C ^= 2 等同于 C = C ^ 2
|= 按位或且赋值运算符 C |= 2 等同于 C = C | 2

请看下面的实例,了解 C++ 中所有可用的赋值运算符。

复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序。

#include <iostream>
using namespace std;

int main()
{
    int a = 21;
    int c ;
    c =  a;
    cout << "Line 1 - =  运算符实例,c 的值 = : " <<c<< endl ;
    c +=  a;
    cout << "Line 2 - += 运算符实例,c 的值 = : " <<c<< endl ;
    c -=  a;
    cout << "Line 3 - -= 运算符实例,c 的值 = : " <<c<< endl ;
    c *=  a;
    cout << "Line 4 - *= 运算符实例,c 的值 = : " <<c<< endl ;
    c /=  a;
    cout << "Line 5 - /= 运算符实例,c 的值 = : " <<c<< endl ;
    c  = 200;
    c %=  a;
    cout << "Line 6 - %= 运算符实例,c 的值 = : " <<c<< endl ;
    c <<=  2;
    cout << "Line 7 - <<= 运算符实例,c 的值 = : " <<c<< endl ;
    c >>=  2;
    cout << "Line 8 - >>= 运算符实例,c 的值 = : " <<c<< endl ;
    c &=  2;
    cout << "Line 9 - &= 运算符实例,c 的值 = : " <<c<< endl ;
    c ^=  2;
    cout << "Line 10 - ^= 运算符实例,c 的值 = : " <<c<< endl ;
    c |=  2;
    cout << "Line 11 - |= 运算符实例,c 的值 = : " <<c<< endl ;
    return 0; 
} 

尝试一下

当上面的代码被编译和执行时,它会产生下列结果:

Line 1 - =  运算符实例,c 的值 = 21
Line 2 - += 运算符实例,c 的值 = 42
Line 3 - -= 运算符实例,c 的值 = 21
Line 4 - *= 运算符实例,c 的值 = 441
Line 5 - /= 运算符实例,c 的值 = 21
Line 6 - %= 运算符实例,c 的值 = 11
Line 7 - <<= 运算符实例,c 的值 = 44 Line 8 - >>= 运算符实例,c 的值 = 11
Line 9 - &= 运算符实例,c 的值 = 2
Line 10 - ^= 运算符实例,c 的值 = 0
Line 11 - |= 运算符实例,c 的值 = 2

# 运算符:其他

下表列出了 C++ 支持的其他一些重要的运算符。

运算符 描述
sizeof sizeof 运算符 (opens new window)返回变量的大小。例如,sizeof(a) 将返回 4,其中 a 是整数。
Condition ? X : Y 条件运算符 (opens new window)。如果 Condition 为真 ? 则值为 X : 否则值为 Y。
, 逗号运算符 (opens new window)会顺序执行一系列运算。整个逗号表达式的值是以逗号分隔的列表中的最后一个表达式的值。
.(点)和 ->(箭头) 成员运算符 (opens new window)用于引用类、结构和共用体的成员。
Cast 强制转换运算符 (opens new window)把一种数据类型转换为另一种数据类型。例如,int(2.2000) 将返回 2。
& 指针运算符 & (opens new window) 返回变量的地址。例如 &a; 将给出变量的实际地址。
* 指针运算符 * (opens new window) 指向一个变量。例如,*var; 将指向变量 var。

# 运算符:优先级

运算符的优先级确定表达式中项的组合。这会影响到一个表达式如何计算。某些运算符比其他运算符有更高的优先级,例如,乘除运算符具有比加减运算符更高的优先级。

例如 x = 7 + 3 * 2,在这里,x 被赋值为 13,而不是 20,因为运算符 * 具有比 + 更高的优先级,所以首先计算乘法 3*2,然后再加上 7。

下表将按运算符优先级从高到低列出各个运算符,具有较高优先级的运算符出现在表格的上面,具有较低优先级的运算符出现在表格的下面。在表达式中,较高优先级的运算符会优先被计算。

类别 运算符 结合性
后缀 () [] -> . ++ - - 从左到右
一元 + - ! ~ ++ - - (type)* & sizeof 从右到左
乘除 * / % 从左到右
加减 + - 从左到右
移位 << >> 从左到右
关系 < <= > >= 从左到右
相等 == != 从左到右
位与 AND & 从左到右
位异或 XOR ^ 从左到右
位或 OR | 从左到右
逻辑与 AND && 从左到右
逻辑或 OR || 从左到右
条件 ?: 从右到左
赋值 = += -= *= /= %=>>= <<= &= ^= |= 从右到左
逗号 , 从左到右

请看下面的实例,了解 C++ 中运算符的优先级。

复制并黏贴下面的 C++ 程序到 test.cpp 文件中,编译并运行程序。

对比有括号和没有括号时的区别,这将产生不同的结果。因为 ()、 /、 * 和 + 有不同的优先级,高优先级的操作符将优先计算。

#include <iostream>
using namespace std;
 
int main()
{
    int a = 20;
    int b = 10;
    int c = 15;
    int d = 5;
    int e;
 
    e = (a + b) * c / d;      // ( 30 * 15 ) / 5
    cout << "(a + b) * c / d 的值是 " << e << endl ;

    e = ((a + b) * c) / d;    // (30 * 15 ) / 5
    cout << "((a + b) * c) / d 的值是 " << e << endl ;

    e = (a + b) * (c / d);   // (30) * (15/5)
    cout << "(a + b) * (c / d) 的值是 " << e << endl ;

    e = a + (b * c) / d;     //  20 + (150/5)
    cout << "a + (b * c) / d 的值是 " << e << endl ;
  
    return 0;
}

尝试一下

当上面的代码被编译和执行时,它会产生下列结果:

(a + b) * c / d 的值是 90
((a + b) * c) / d 的值是 90
(a + b) * (c / d) 的值是 90
a + (b * c) / d 的值是 50

# 【运算逻辑】

# 运算:原码、反码、补码

计算机是二进制计算,严格说没有减法的说法,只有加法,都是采用补码进行运算

1、数据类型

数据操作前提,首先明确一点是数据类型, 不同类型数据内存空间大小不一样

2、高位为符号位

第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

[1111 1111 , 0111 1111]

也就是[-127,127];

第一位是1代表负数,第一位0代表正数

3、负数

原码、反码、补码 是相对于负数来说的,正数都是相同的

# 运算:正、负

正数:原码=反码=补码

int a = 5;

原码:0000 0101 
反码:0000 0101 
补码:0000 0101

三者相同

负数:

原码=正数原码最高位变1

反码=原码(除符号位)都取反,

补码=反码+1

int a = -5;

原码:1000 0101  // 正数5原码最高位变1
反码:1111 1010  // 原码(除符号位)都取反
补码:1111 1011  // 反码+1

# 运算:加、减

运算:

【补码 + 补码 】的形式进行的

1、加法

5 + 5 = 10;

5补码:0000 0101
  +
5补码:0000 0101
  =
 结果:0000 1010

2、减法

5 - 5 
  = 5 + (-5) 
  = 0;

 5补码:0000 0101
  +
-5补码:1111 1011
  =
  结果:1000 0000 
   = -0 = 0
   (-0 也就是0, 虽然二进制不一样,但是数据一样)
C语法Day8-编译
C++基础概念(下)

← C语法Day8-编译 C++基础概念(下)→

Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式