import{_ as s,c as i,o as a,a6 as n}from"./chunks/framework.hMCIpNYY.js";const l="/c/assets/1.CXNJqOOc.png",e="/c/assets/2.E0LS08Y5.png",t="/c/assets/3.6recRAvz.jpeg",p="/c/assets/4.DcyDw4rB.jpg",h="/c/assets/5.q20QOAIA.png",d="/c/assets/6.CmrWpBzQ.png",k="/c/assets/7.CocAjZjO.png",c="/c/assets/8.CHZSlb-7.png",r="/c/assets/9.RD2M_pYn.png",o="/c/assets/10.CmNKK_Ug.png",u="/c/assets/11.CbGZ55Dj.png",E="/c/assets/12.DpTBR420.png",g="/c/assets/13.XcPl7d9s.png",b="/c/assets/14.Oc1zdsE_.svg",y="/c/assets/15.Dr67r_Ws.png",F="/c/assets/16.C5XiXNVN.png",m="/c/assets/17.DO8XxSV6.jpg",C="/c/assets/18.CUXrdefp.jpeg",v="/c/assets/19.BHR3Faxy.svg",B="/c/assets/20.BPvPBGLi.svg",A="/c/assets/21.96eXHKhR.svg",D="/c/assets/22.DU0JSGBx.svg",_="/c/assets/23.DjDYOeB4.svg",q="/c/assets/24.CSyqvmqg.svg",f="/c/assets/25.uqLiL_yu.png",x="/c/assets/26.CVy9jq-k.svg",P="/c/assets/27.D0s35-Np.svg",T="/c/assets/28.CGctd5l_.svg",N="/c/assets/29.DQIGB6FY.svg",O="/c/assets/30.DBiJDp82.svg",z="/c/assets/31.r0a7UWIb.svg",M="/c/assets/32.-KoNS5D_.svg",w="/c/assets/33.9LAsi3gH.svg",I="/c/assets/34.CbxjdJlI.svg",S="/c/assets/35.DouEaZ2q.svg",U="/c/assets/36.BAASpiz6.svg",R="/c/assets/37.0G4aKrVO.svg",L="/c/assets/38.CSLcq3FJ.svg",j="/c/assets/39.8wVUSUxs.svg",X="/c/assets/40.B8T792CZ.svg",V="/c/assets/41.D7XSVA_S.svg",G="/c/assets/42.BeI_-jpB.svg",J="/c/assets/43.BnCPdx_j.svg",K="/c/assets/44.2VEmYYnq.svg",es=JSON.parse('{"title":"第一章:变量(⭐)","description":"","frontmatter":{},"headers":[],"relativePath":"notes/01_c-basic/02_xdx/index.md","filePath":"notes/01_c-basic/02_xdx/index.md","lastUpdated":1724651019000}'),Z={name:"notes/01_c-basic/02_xdx/index.md"},H=n('

第一章:变量(⭐)

1.1 程序中变化的数据

1.2 变量

NOTE

NOTE

1.3 变量的声明和使用

IMPORTANT

c
#include <stdio.h>

int main() {

    // 声明一个整型变量,取名为 a
    int a;

    // 给变量赋值
    a = 10;

    printf("a = %d\\n", a);

    return 0;
}
c
#include <stdio.h>

int main() {

    // 声明一个整型变量,取名为 b ,并直接赋值(初始化,实际开发中最为常用)
    int b = 200;

    // 修改变量 b 的值,将变量 a 的值赋值给变量 b
    b = 300;

    printf("b= %d\\n", b);

    return 0;
}
c
#include <stdio.h>

int main() {

    // 同时声明多个整型的变量并赋值
    int c1 = 10, c2 = 20, c3 = 30;
    printf("c1 = %d\\n", c1);
    printf("c2 = %d\\n", c2);
    printf("c3 = %d\\n", c3);

    return 0;
}

1.4 浅谈变量周边概念

1.4.1 数据类型

NOTE

总结:

1.4.2 连续定义多个变量

c
int a,b,c;
c
float m=3.14,n=4.14;

NOTE

1.4.3 数据的长度

NOTE

总结:在 C 语言中,每一种数据类型所占用的字节数都是固定的,知道了数据类型,也就知道了数据的长度。

数据类型长度(字节)
char1
short2
int4
long4
long long8
float4
double8
long double8
pointer(指针)4

NOTE

C 语言有多少种数据类型,每种数据类型长度是多少、该如何使用,这是每一位 C 程序员都必须要掌握的。当然,不必担心,后续还会一一讲解的。

IMPORTANT

数据类型只需要在定义变量时指明,而且必须指明;使用变量时无需再指明,因为此时的数据类型已经确定了。

1.5 从计算机底层看变量

1.5.1 内存条的内部结构

NOTE

NOTE

NOTE

组成双通道配置的内存条需要遵循一些基本要求来确保它们能够正常以双通道模式运行:

NOTE

上图中的内存条有 8 个内存颗粒;但是,高端服务器上的内存条通常会存在 9 个内存颗粒,最后 1 个内存颗粒专门用来做 ECC 校验。

NOTE

img

1.5.2 变量的作用

txt
0000,0000,000000010000 代表 LOAD A, 16
0000,0001,000000000001 代表 LOAD B, 1
0001,0001,000000010000 代表 STORE B, 16
txt
LOAD A, 16   -- 编译 -->   0000,0000,000000010000
LOAD B, 1    -- 编译 -->   0000,0001,000000000001
STORE B, 16  -- 编译 -->   0001,0001,000000010000
c
int num = 10;
txt
00011001 00100110 00100110 00100110 00100110 ...

NOTE

计算机中存储单位的换算,如下所示:

NOTE

变量就是保存程序运行过程中临时产生的值。

txt
数据类型 变量名 = 值;

IMPORTANT

变量名(标识符)需要符合命名规则和命名规范!!!

c
// int 数据类型,4 个字节
// num 变量名 -- 关联内存中的一块存储空间
// = 10 将 10 存储到 num 所代表的 4 个字节的存储空间中
int num = 10;

1.7 变量的重要操作

1.7.1 变量的输出

NOTE

c
int printf (const char *__format, ...) {
    ...
}

NOTE

IMPORTANT

c
#include <stdio.h>

int main() {

    // 声明变量并赋值
    int num = 18;

    // 使用输出语句,将变量 num 的值输出,其中 %d 表示输出的是整数
    printf("我今年%d\\n", num);

    return 0;
}

1.7.2 计算变量的大小

c
#include <stdio.h>

int main() {

    int num = 10;

    printf("变量所占内存空间的大小:%zd字节\\n", sizeof(num));

    // 数据类型所占内存空间的大小
    printf("数据类型所占内存空间的大小:%zd字节\\n", sizeof(int));

    return 0;
}

1.7.3 获取变量的地址

c
#include <stdio.h>

int main() {

    int num = 10;

    printf("变量 num 的值是:%d\\n", num);
    printf("变量 num 的地址(指针)是:%#p\\n", &num);

    return 0;
}

1.7.4 变量的输入

c
int scanf(const char *__format, ...) {
    ...
}

NOTE

&age&num 中的 &是寻址操作符,&age 表示变量 age 在内存中的地址。

CAUTION

c
#include <stdio.h>

int main() {

    // 禁用 stdout 缓冲区
    // CLion debug 独有,后文不再提及,如果 debug 有问题,就添加如下代码
    setbuf(stdout, NULL);
    
    float radius;

    printf("请输入一个半径:");
    scanf("%f", &radius);

    double area = 3.1415926 * radius * radius;

    printf("半径是%f的圆的面积是%.2lf", radius, area);

    return 0;
}
c
#include <stdio.h>

int main() {

    int num;

    printf("请输入一个整数:");
    scanf("%d", &num);

    int absNum;

    if (num < 0) {
        absNum = -num;
    } else {
        absNum = num;
    }

    printf("%d的绝对值是:%d", num, absNum);

    return 0;
}
c
#include <stdio.h>

int main() {

    int a, b, c;
    printf("请输入整数 a 、b 和 c 的值:");
    scanf("%d %d %d", &a, &b, &c);

    int result = a * b * c;

    printf("%d × %d × %d = %d", a, b, c, result);

    return 0;
}

1.8 标识符

1.8.1 概述

NOTE

1.8.2 标识符的命名规范

txt
a、BOOK_sun、MAX_SIZE、Mouse、student23、
Football、FOOTBALL、max、_add、num_1、sum_of_numbers
txt
$zj、3sum、ab#cd、23student、Foot-baii、
s.com、b&c、j**p、book-1、tax rate、don't

1.8.3 关键字

类型(功能)具体关键字
数据类型关键字chardoublefloatintlongshortsignedunsignedvoid
存储类说明符关键字autoexternregisterstatictypedefvolatileconst
控制语句关键字breakcasecontinuedefaultdoelseforgotoifreturnswitchwhile
结构体、联合体和枚举关键字enumstructunion
其他关键字sizeof
类型(功能)具体关键字
数据类型关键字_Bool_Complex_Imaginary
存储类说明符关键字inlinerestrict
其他关键字_Complex_Imaginary
类型(功能)具体关键字
存储类说明符关键字_Atomic
其他关键字_Alignas_Alignof_Generic_Noreturn_Static_assert_Thread_local

IMPORTANT

第二章:常量(⭐)

2.1 概述

NOTE

2.2 常量的分类

NOTE

c
#include <stdio.h>

int main() {

    1;
    'A';
    12.3;
    "你好";

    return 0;
}
c
#include <stdio.h>

int main() {

    printf("整数常量 =》%d\\n", 1);
    printf("字符常量 =》%c\\n", 'A');
    printf("浮点数常量 =》%f\\n", 12.3);
    printf("字符串常量 =》%s\\n", "你好");

    return 0;
}

2.3 使用 #define 定义常量

c
#define 常量名 常量值

IMPORTANT

c
#include <stdio.h>

#define PI 3.1415926

int main() {

    double radius = 2.5;

    double area = PI * radius * radius;

    printf("半径为%lf的圆的面积是%.2lf", radius, area);

    return 0;
}

2.4 const 关键字

c
const 数据类型 常量名 = 常量值;
c
#include <stdio.h>

const int PI = 3.1415926;

int main() {

    double radius = 2.5;

    double area = PI * radius * radius;

    printf("半径为%lf的圆的面积是%.2lf", radius, area);

    return 0;
}

2.5 枚举常量

c
enum 枚举常量 {
    xxx = 1;
    yyy;
    ...
}

NOTE

c
#include <stdio.h>

enum sex {
    MALE = 1,
    FEMALE = 2,
};

int main() {

    printf("%d\\n", MALE);
    printf("%d\\n", FEMALE);

    return 0;
}
c
#include <stdio.h>

enum Sex {
    MALE = 1,
    FEMALE = 2,
};

int main() {
    enum Sex sex;

    printf("请输入性别(1 表示男性, 2 表示女性):");
    scanf("%d", &sex);
    printf("您的性别是:%d\\n", sex);

    return 0;
}

2.6 #defind 定义常量 VS const 定义常量

第三章:进制

3.1 概述

3.2 进制

3.2.1 常见的进制

NOTE

在十六进制中,除了 09 这十个数字之外,还引入了字母,以便表示超过 9 的值。其中,字母 A 对应十进制的 10 ,字母 B 对应十进制的 11 ,字母 C 对应十进制的 12,字母 D 对应十进制的 13,字母 E 对应十进制的 14,字母 F 对应十进制的 15

十进制二进制八进制十六进制
0000
1111
21022
31133
410044
510155
611066
711177
81000108
91001119
10101012a 或 A
11101113b 或 B
12110014c 或 C
13110115d 或 D
14111016e 或 E
15111117f 或 F
16100002010
............

NOTE

十六进制的范围是:0 ~ F (0 ~ 15)对应的二进制数的范围是:0000 ~ 1111 (0 ~ 15)。

十六进制二进制
00000
10001
20010
30011
40100
50101
60110
70111
81000
91001
A1010
B1011
C1100
D1101
E1110
F1111

NOTE

由此可见,每个十六进制数字确实由 4 位二进制数表示。

NOTE

八进制的范围是:0 ~ 7 对应的二进制数的范围是:000 ~ 111。

八进制二进制
0000
1001
2010
3011
4100
5101
6110
7111

NOTE

由此可见,每个八进制数字确实由 3 位二进制数表示。

3.2.2 C 语言中如何表示不同进制的整数?

c
#include <stdio.h>

int main() {

    int num1 = 0b10100110; // 二进制
    int num2 = 0717563; // 八进制
    int num3 = 1000; // 十进制
    int num4 = 0xaf72; // 十六进制

    printf("num1 = %d\\n", num1); // num1 = 166
    printf("num2 = %d\\n", num2); // num2 = 237427
    printf("num3 = %d\\n", num3); // num3 = 1000
    printf("num4 = %d\\n", num4); // num4 = 44914

    return 0;
}

3.2.3 输出格式

CAUTION

C 语言中没有输出二进制数的格式占位符!!!

c
#include <stdio.h>

int main() {

    int num = 100;

    printf("%d 的十进制整数: %d\\n", num, num); // 100 的十进制整数: 100
    printf("%d 的八进制整数: %o\\n", num, num); // 100 的八进制整数: 144
    printf("%d 的十六进制整数: %x\\n", num, num); // 100 的十六进制整数: 64
    printf("%d 的八进制(前缀)整数: %#o\\n", num, num); // 100 的八进制(前缀)整数: 0144
    printf("%d 的十六进制(前缀)整数: %#x\\n", num, num); // 100 的十六进制(前缀)整数: 0x64
    printf("%d 的十六进制(前缀)整数: %#X\\n", num, num); // 100 的十六进制(前缀)整数: 0X64

    return 0;
}

3.3 进制的运算规则

3.3.1 概述

3.3.2 二进制的运算

3.3.3 八进制的运算

3.3.4 十六进制的运算

3.4 进制的转换

3.4.1 概述

3.4.2 二进制和十进制的转换

3.4.2.1 二进制转换为十进制

NOTE

3.4.2.2 十进制转换二进制

NOTE

3.4.3 二进制转八进制

3.4.4 二进制转十六进制

3.5 原码、反码和补码

3.5.1 概述

IMPORTANT

IMPORTANT

3.5.2 原码

十进制数原码(16位二进制数)
+10000 0000 0000 0001
十进制数原码(16位二进制数)
-11000 0000 0000 0001

IMPORTANT

3.5.3 反码

十进制数原码(16位二进制数)反码(16位二进制数)
+10000 0000 0000 00010000 0000 0000 0001
十进制数原码(16位二进制数)反码(16位二进制数)
-11000 0000 0000 00011111 1111 1111 1110

IMPORTANT

3.5.4 补码

十进制数原码(16位二进制数)反码(16位二进制数)补码(16位二进制数)
+10000 0000 0000 00010000 0000 0000 00010000 0000 0000 0001
十进制数原码(16位二进制数)反码(16位二进制数)补码(16位二进制数)
-11000 0000 0000 00011111 1111 1111 11101111 1111 1111 1111

IMPORTANT

3.5.5 总结

3.6 计算机底层为什么使用补码?

3.7 补码到底是如何简化硬件电路的?

NOTE

直接使用原码表示整数,让符号位也参与运算,那么对于减法来说,结果显然是不正确的。

NOTE

直接使用反码表示整数,让符号位也参与运算,对于 6 +(-18)来说,结果貌似正确。

NOTE

IMPORTANT

总结:采用补码的形式正好将相差的 1纠正过来,也没有影响到小数减大数,这个“补丁”非常巧妙。

补码这种天才般的设计,一举达成了之前加法运算和减法运算提到的两个目标,简化了硬件电路。

3.8 问题抛出

c
int a = 10;
int b = -10;

c
unsigned int a = 10;
unsigned int b = -10;

c
#include <stdio.h>

char *getBinary(int num) {
    static char binaryString[33];
    int         i, j;

    for (i = sizeof(num) * 8 - 1, j = 0; i >= 0; i--, j++) {
        const int bit   = (num >> i) & 1;
        binaryString[j] = bit + '0';
    }

    binaryString[j] = '\\0';
    return binaryString;
}

int main() {

    // 禁用 stdout 缓冲区
    setbuf(stdout, NULL);

    int num = -10;
    printf("b=%s\\n", getBinary(num)); // b=11111111111111111111111111110110
    printf("b=%d\\n", num);            // b=-10
    printf("b=%u\\n", num);            // b=4294967286

    return 0;
}

IMPORTANT

`,305),Y=[H];function Q($,W,ss,is,as,ns){return a(),i("div",null,Y)}const ts=s(Z,[["render",Q]]);export{es as __pageData,ts as default};