Skip to content

重拾 C 语言 - 第一天

Published: at 02:11 AMSuggest Changes

进制转换

十进制转二进制

十进制转二进制的方法是:除 2 取余,直到商为 0 为止,然后把余数倒过来就是二进制数。

比如:十进制数 10 转二进制数

10 / 2 = 5 0
5 / 2 = 2 1
2 / 2 = 1 0
1 / 2 = 0 1

所以 10 的二进制数为 1010

二进制转十进制

二进制转十进制的方法是:把二进制数从右往左排列,然后从 0 开始,每个数乘以 2 的 n 次方,n 从 0 开始,然后把结果相加。

比如:二进制数 1010 转十进制数

0 * 2^0 = 0
1 * 2^1 = 2
0 * 2^2 = 0
1 * 2^3 = 8

所以 1010 的十进制数为 10

十进制转十六进制

十进制转十六进制的方法是:除 16 取余,直到商为 0 为止,然后把余数倒过来就是十六进制数。

比如:十进制数 10 转十六进制数

10 / 16 = 0 10

所以 10 的十六进制数为 A

十六进制转十进制

十六进制转十进制的方法是:把十六进制数从右往左排列,然后从 0 开始,每个数乘以 16 的 n 次方,n 从 0 开始,然后把结果相加。

比如:十六进制数 A 转十进制数

10 * 16^0 = 10

所以 A 的十进制数为 10

二进制转十六进制

二进制转十六进制的方法是:先把二进制数每 4 位分成一组,然后把每组转成十六进制数,最后把结果拼接起来。

比如:二进制数 1010 转十六进制数

1010 -> 0000 1010 -> 0A

所以 1010 的十六进制数为 A

十六进制转二进制

十六进制转二进制的方法是:先把十六进制数转成十进制数,然后把十进制数转成二进制数。

比如:十六进制数 A 转二进制数

A -> 10 -> 1010

所以 A 的二进制数为 1010

设置文件夹

我在代码文件夹新建了 main.cpp第一天/a.cpp

main.cpp

#include <iostream>
#include '第一天/a.cpp'

using namespace std;

int main() {
	cout << "Hello World!" << endl;
	return 0;
}

a.cpp

// 打印二进制
#include <iostream>
using namespace std;

void  binaryTest() {
    unsigned char binaryNumber = 0b0011;
    cout << binaryNumber << endl;
    // 位操作符
    // unsigned char binaryNumber2 = (1 << 7) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 0);
    unsigned int binaryNumber2 = (1 << 1) | (1 << 0); // 二进制数 0011
    cout << binaryNumber2 << endl;
}

然后光荣报错

duplicate symbol 'binaryTest()' in:
    CMakeFiles/cpp_study.dir/main.cpp.o
    CMakeFiles/cpp_study.dir/第一天/a.cpp.o
duplicate symbol 'printBinary(int)' in:
    CMakeFiles/cpp_study.dir/main.cpp.o
    CMakeFiles/cpp_study.dir/第一天/a.cpp.o
ld: 2 duplicate symbols for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

解决方法

新建头文件 a.h

#ifndef CPP_STUDY_A_H
#define CPP_STUDY_A_H

void binaryTest();
void printBinary(int number);

#endif //CPP_STUDY_A_H

然后在 main.cppa.cpp 中引入头文件

main.cpp

#include <iostream>
#include '第一天/a.h'

....

a.cpp

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

....

写一个进制字面量

unsigned char binaryNumber = 0b11001111;
cout << binaryNumber << endl;
// 位操作符
unsigned char binaryNumber2 = (1 << 7) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 0);
cout << binaryNumber2 << endl;

竟然打印出了两个乱码

问群友

Rex 大佬直出 0b11001111 也就是 207,标准 ASCII 没有对应的字符吧

我一看还真是,改成 1100

unsigned char binaryNumber = 0b1100;
cout << binaryNumber << endl;
// 位操作符
unsigned int binaryNumber2 = (1 << 1) | (1 << 0); // 二进制数 0011
cout << binaryNumber2 << endl;

这次控制台打印的

(你们可能看不到,是 ext)
3

在 ASCII 编码中,字符 (ETX,End of Text)对应的是一个控制字符,它的十进制值是 3。而二进制数 0011 表示的是十进制数 3。

重温八进制和十六进制

// 定义八进制字面量
unsigned int octalNumber = 0123;
// 1 * 8^2 + 2 * 8^1 + 3 * 8^0 = 64 + 16 + 3 = 83
cout << octalNumber << endl;

// 定义十六进制字面量
unsigned int hexadecimalNumber = 0x123;
// 1 * 16^2 + 2 * 16^1 + 3 * 16^0 = 256 + 32 + 3 = 291
cout << hexadecimalNumber << endl;

反码和补码

反码和补码是计算机中用于表示负数的两种常见方式。它们的存在是为了解决在计算机系统中处理负数运算和表示的问题。

反码(One’s Complement)

反码是一种表示负数的方法,其中正数保持不变,而负数则通过对其二进制表示的每一位取反(0 变为 1,1 变为 0)来表示。例如,正数 5 的二进制是 0101,负数 -5 的反码是 1010。这样,计算机可以使用相同的加法和减法操作来处理正数和负数。

但是,反码有一个问题,就是有两个表示零的值,分别是正零和负零,即 0000 和 1111 都表示零。这会引入一些运算上的复杂性。

补码(Two’s Complement)

为了克服反码的零的问题,并且能够更方便地进行负数运算,补码被引入。补码也是一种表示负数的方式,其中负数是其对应正数的反码加 1。例如,正数 5 的二进制是 0101,负数 -5 的补码是 1011。

补码的一个重要特性是,通过对补码进行加法和减法运算,可以在不考虑正负的情况下,得到正确的结果。而且,补码只有一个表示零的值,即 0000,没有正零和负零的区分。

在现代计算机中,大多数都使用补码来表示负数。这是因为补码在进行运算时更加方便,而且只有一个零的表示。补码也有助于简化硬件电路的设计和实现。


Previous Post
C 语言学习笔记:浮点数类型详解
Next Post
Sequelize 打印 SQL 语句及参数详解