🎬 HoRain 云小助手个人主页

⛺️生活的理想,就是为了理想的生活!


⛳️ 推荐

前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。

目录

⛳️ 推荐

C语言:操作符、进制与数据表示通俗讲解

📊 核心概念一览

🔢 一、操作符:C语言的"工具箱"

1. 算术操作符 - 基础数学工具

2. 关系操作符 - 比较大小

3. 逻辑操作符 - 组合条件

4. 赋值操作符 - 给变量赋值

5. 自增自减操作符 - 加1减1

6. 条件操作符(三目运算符) - 简化的if-else

🔢 二、进制:数的不同"方言"

1. 进制概念通俗解释

2. C语言中的进制表示

3. 进制转换实战

⚡ 三、位运算:直接操作二进制位

1. 位运算基础

2. 位运算实际应用

💾 四、数据表示:内存中的数字

1. 原码、反码、补码

2. 浮点数表示

🎯 五、综合实战:学生成绩管理系统

💡 学习要点总结

1. 操作符优先级(从高到低)

2. 常见易错点

3. 进制转换速查表

4. 实用技巧


C语言:操作符、进制与数据表示通俗讲解

我将用最通俗易懂的方式,结合丰富示例,讲解C语言中看似复杂但非常重要的基础知识。

📊 核心概念一览

概念

通俗比喻

作用

示例

操作符

数学运算符的升级版

对数据进行运算

+ - * / %

进制

数的不同"方言"

表示数的不同方式

十进制、二进制、十六进制

数据类型

不同大小的容器

规定数据的大小和类型

int, float, char

位运算

电子开关操作

直接操作二进制位

`&

内存表示

仓库的货架编号

数据在内存中的存放

地址、字节序

🔢 一、操作符:C语言的"工具箱"

1. 算术操作符 - 基础数学工具

#include <stdio.h>

int main() {
    int a = 10, b = 3;
    
    // 1. 加法 (+)
    printf("加法: %d + %d = %d\n", a, b, a + b);  // 13
    
    // 2. 减法 (-)
    printf("减法: %d - %d = %d\n", a, b, a - b);  // 7
    
    // 3. 乘法 (*)
    printf("乘法: %d * %d = %d\n", a, b, a * b);  // 30
    
    // 4. 除法 (/)
    printf("整数除法: %d / %d = %d\n", a, b, a / b);  // 3(注意:不是3.333)
    
    // 5. 取模/求余 (%)
    printf("取余: %d %% %d = %d\n", a, b, a % b);  // 1
    
    // 浮点数除法
    float x = 10.0, y = 3.0;
    printf("浮点数除法: %.2f / %.2f = %.2f\n", x, y, x / y);  // 3.33
    
    return 0;
}

2. 关系操作符 - 比较大小

#include <stdio.h>

int main() {
    int age = 18;
    int score = 85;
    
    printf("age >= 18? %s\n", age >= 18 ? "是" : "否");  // 是
    printf("score < 60? %s\n", score < 60 ? "是" : "否");  // 否
    printf("age == 18? %s\n", age == 18 ? "是" : "否");  // 是
    printf("age != 20? %s\n", age != 20 ? "是" : "否");  // 是
    
    // 实际应用:判断成绩等级
    if (score >= 90) {
        printf("优秀\n");
    } else if (score >= 60) {
        printf("及格\n");
    } else {
        printf("不及格\n");
    }
    
    return 0;
}

3. 逻辑操作符 - 组合条件

#include <stdio.h>

int main() {
    int age = 20;
    int hasLicense = 1;  // 1表示有驾照,0表示没有
    
    // 逻辑与 (&&) - 两个条件都满足
    if (age >= 18 && hasLicense == 1) {
        printf("可以开车上路\n");
    } else {
        printf("不能开车上路\n");
    }
    
    // 逻辑或 (||) - 至少满足一个条件
    int isWeekend = 0;
    int isHoliday = 1;
    
    if (isWeekend || isHoliday) {
        printf("今天休息\n");
    } else {
        printf("今天上班\n");
    }
    
    // 逻辑非 (!) - 取反
    int isRaining = 0;
    
    if (!isRaining) {
        printf("天气不错,可以出门\n");
    } else {
        printf("下雨了,带把伞\n");
    }
    
    return 0;
}

4. 赋值操作符 - 给变量赋值

#include <stdio.h>

int main() {
    int a = 10;  // 基本赋值
    
    // 复合赋值操作符(快捷方式)
    a += 5;      // 等价于 a = a + 5
    printf("a += 5 后: %d\n", a);  // 15
    
    a -= 3;      // 等价于 a = a - 3
    printf("a -= 3 后: %d\n", a);  // 12
    
    a *= 2;      // 等价于 a = a * 2
    printf("a *= 2 后: %d\n", a);  // 24
    
    a /= 4;      // 等价于 a = a / 4
    printf("a /= 4 后: %d\n", a);  // 6
    
    a %= 5;      // 等价于 a = a % 5
    printf("a %%= 5 后: %d\n", a);  // 1
    
    return 0;
}

5. 自增自减操作符 - 加1减1

#include <stdio.h>

int main() {
    int a = 5;
    
    // 前缀自增 (++在前)
    int b = ++a;  // 先a加1变为6,然后赋值给b
    printf("前缀自增: a=%d, b=%d\n", a, b);  // a=6, b=6
    
    // 后缀自增 (++在后)
    int c = a++;  // 先把a的值6赋给c,然后a加1变为7
    printf("后缀自增: a=%d, c=%d\n", a, c);  // a=7, c=6
    
    // 实际应用:数组遍历
    int arr[3] = {10, 20, 30};
    int i = 0;
    
    printf("数组元素: ");
    while (i < 3) {
        printf("%d ", arr[i++]);  // 先输出arr[i],然后i自增
    }
    printf("\n");
    
    return 0;
}

6. 条件操作符(三目运算符) - 简化的if-else

#include <stdio.h>

int main() {
    int score = 85;
    
    // 语法:条件 ? 值1 : 值2
    // 如果条件为真,结果为值1,否则为值2
    
    char grade = (score >= 90) ? 'A' : 
                 (score >= 60) ? 'B' : 'C';
    
    printf("分数: %d, 等级: %c\n", score, grade);
    
    // 等价于:
    if (score >= 90) {
        grade = 'A';
    } else if (score >= 60) {
        grade = 'B';
    } else {
        grade = 'C';
    }
    
    return 0;
}

🔢 二、进制:数的不同"方言"

1. 进制概念通俗解释

十进制(我们常用的):0,1,2,3,4,5,6,7,8,9 (满10进1)
二进制(计算机用的):0,1 (满2进1)
八进制:0,1,2,3,4,5,6,7 (满8进1)
十六进制:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F (满16进1)

2. C语言中的进制表示

#include <stdio.h>

int main() {
    // 十进制(默认)
    int dec = 100;      // 十进制100
    printf("十进制 100 = %d\n", dec);
    
    // 八进制(以0开头)
    int oct = 0144;     // 八进制144 = 1 * 8^2 + 4 * 8 + 4 = 100
    printf("八进制 0144 = %d\n", oct);
    
    // 十六进制(以0x或0X开头)
    int hex = 0x64;     // 十六进制64 = 6 * 16 + 4 = 100
    printf("十六进制 0x64 = %d\n", hex);
    
    // 二进制(C语言不直接支持,但可以用其他方法)
    
    // 不同进制输出
    int num = 255;
    printf("十进制输出: %d\n", num);    // 255
    printf("八进制输出: %o\n", num);    // 377
    printf("十六进制输出: %x\n", num);  // ff (小写)
    printf("十六进制输出: %X\n", num);  // FF (大写)
    printf("带前缀的十六进制: %#x\n", num);  // 0xff
    
    return 0;
}

3. 进制转换实战

#include <stdio.h>

void printBinary(unsigned int n) {
    // 打印整数的二进制表示
    printf("二进制: ");
    
    // 从最高位开始打印(假设32位整数)
    for (int i = 31; i >= 0; i--) {
        printf("%d", (n >> i) & 1);
        if (i % 8 == 0 && i != 0) {
            printf(" ");  // 每8位加空格
        }
    }
    printf("\n");
}

int main() {
    int num = 42;  // 十进制42
    
    printf("数字: %d\n", num);
    printf("八进制: %o\n", num);    // 52
    printf("十六进制: %x\n", num);  // 2a
    
    // 手动计算进制转换
    printf("\n手动转换验证:\n");
    printf("42 转换为八进制:\n");
    printf("  42 ÷ 8 = 5 余 2\n");
    printf("  5  ÷ 8 = 0 余 5\n");
    printf("  结果: 52 (从下往上读)\n");
    
    printf("\n42 转换为十六进制:\n");
    printf("  42 ÷ 16 = 2 余 10 (A)\n");
    printf("  2  ÷ 16 = 0 余 2\n");
    printf("  结果: 2A\n");
    
    // 查看二进制
    printBinary(num);
    
    return 0;
}

⚡ 三、位运算:直接操作二进制位

1. 位运算基础

#include <stdio.h>

void printBits(unsigned int n, const char* label) {
    printf("%s: ", label);
    for (int i = 7; i >= 0; i--) {
        printf("%d", (n >> i) & 1);
    }
    printf("\n");
}

int main() {
    unsigned char a = 0b01010101;  // 二进制85
    unsigned char b = 0b00001111;  // 二进制15
    
    printBits(a, "a          ");
    printBits(b, "b          ");
    printf("十进制: a=%d, b=%d\n\n", a, b);
    
    // 1. 按位与 (&) - 都为1才为1
    unsigned char and_result = a & b;
    printBits(and_result, "a & b      ");
    printf("结果: %d\n\n", and_result);
    
    // 2. 按位或 (|) - 有一个为1就为1
    unsigned char or_result = a | b;
    printBits(or_result, "a | b      ");
    printf("结果: %d\n\n", or_result);
    
    // 3. 按位异或 (^) - 不同为1,相同为0
    unsigned char xor_result = a ^ b;
    printBits(xor_result, "a ^ b      ");
    printf("结果: %d\n\n", xor_result);
    
    // 4. 按位取反 (~) - 0变1,1变0
    unsigned char not_result = ~a;
    printBits(not_result, "~a         ");
    printf("结果: %u\n\n", not_result);
    
    // 5. 左移 (<<) - 相当于乘以2的n次方
    unsigned char left_shift = a << 2;
    printBits(left_shift, "a << 2     ");
    printf("结果: %d (85 * 4 = 340, 但char只有8位,所以是84)\n\n", left_shift);
    
    // 6. 右移 (>>) - 相当于除以2的n次方
    unsigned char right_shift = a >> 2;
    printBits(right_shift, "a >> 2     ");
    printf("结果: %d (85 / 4 = 21.25, 整数除法得21)\n", right_shift);
    
    return 0;
}

2. 位运算实际应用

#include <stdio.h>

// 权限管理系统示例
#define READ_PERMISSION   0b00000100  // 1 << 2
#define WRITE_PERMISSION  0b00000010  // 1 << 1
#define EXECUTE_PERMISSION 0b00000001 // 1 << 0

void checkPermissions(unsigned char permissions) {
    printf("权限检查:\n");
    
    if (permissions & READ_PERMISSION) {
        printf("  ✓ 读取权限\n");
    } else {
        printf("  ✗ 无读取权限\n");
    }
    
    if (permissions & WRITE_PERMISSION) {
        printf("  ✓ 写入权限\n");
    } else {
        printf("  ✗ 无写入权限\n");
    }
    
    if (permissions & EXECUTE_PERMISSION) {
        printf("  ✓ 执行权限\n");
    } else {
        printf("  ✗ 无执行权限\n");
    }
    printf("\n");
}

int main() {
    // 应用1:权限管理
    unsigned char user1_perms = READ_PERMISSION | WRITE_PERMISSION;  // 有读写权限
    unsigned char user2_perms = READ_PERMISSION;  // 只有读权限
    unsigned char user3_perms = READ_PERMISSION | WRITE_PERMISSION | EXECUTE_PERMISSION;  // 全部权限
    
    printf("用户1: ");
    checkPermissions(user1_perms);
    
    printf("用户2: ");
    checkPermissions(user2_perms);
    
    printf("用户3: ");
    checkPermissions(user3_perms);
    
    // 应用2:位操作优化计算
    printf("位运算优化计算:\n");
    int num = 13;
    
    // 判断奇偶(比 num % 2 快)
    if (num & 1) {
        printf("%d 是奇数\n", num);
    } else {
        printf("%d 是偶数\n", num);
    }
    
    // 乘以2的n次方
    printf("%d * 8 = %d (使用左移: %d << 3)\n", num, num * 8, num << 3);
    
    // 除以2的n次方
    printf("%d / 4 = %d (使用右移: %d >> 2)\n", num, num / 4, num >> 2);
    
    return 0;
}

💾 四、数据表示:内存中的数字

1. 原码、反码、补码

#include <stdio.h>

void printBinary(int n, int bits) {
    printf("二进制: ");
    
    // 处理负数
    if (n < 0) {
        // 对于负数,我们需要处理补码
        unsigned int mask = 1 << (bits - 1);
        for (int i = bits - 1; i >= 0; i--) {
            printf("%d", (n & mask) ? 1 : 0);
            mask >>= 1;
        }
    } else {
        // 正数
        for (int i = bits - 1; i >= 0; i--) {
            printf("%d", (n >> i) & 1);
        }
    }
    printf("\n");
}

int main() {
    printf("========== 原码、反码、补码 ==========\n\n");
    
    // 以8位有符号数为例
    int num = 5;
    int neg_num = -5;
    
    printf("数字: +5\n");
    printf("原码: 00000101 (最高位0表示正数)\n");
    printf("反码: 00000101 (正数的反码=原码)\n");
    printf("补码: 00000101 (正数的补码=原码)\n\n");
    
    printf("数字: -5\n");
    printf("原码: 10000101 (最高位1表示负数)\n");
    printf("反码: 11111010 (符号位不变,其他位取反)\n");
    printf("补码: 11111011 (反码+1)\n\n");
    
    // 验证补码运算
    printf("验证: (+5) + (-5) 应该等于 0\n");
    printf("5的补码:  ");
    printBinary(5, 8);
    printf("-5的补码: ");
    printBinary(-5, 8);
    printf("相加结果: ");
    printBinary(5 + (-5), 8);
    printf("十进制: %d\n\n", 5 + (-5));
    
    // 补码的特殊情况
    printf("补码的范围(8位有符号整数):\n");
    printf("最小值: -128 (10000000)\n");
    printf("最大值: 127  (01111111)\n");
    printf("注意: 10000000 是 -128,不是 -0\n");
    
    return 0;
}

2. 浮点数表示

#include <stdio.h>

int main() {
    printf("========== 浮点数表示 ==========\n\n");
    
    float f = 3.14159;
    
    printf("浮点数: %f\n", f);
    printf("科学计数法: %e\n", f);
    
    // IEEE 754 单精度浮点数格式
    printf("\nIEEE 754 单精度浮点数格式:\n");
    printf("| 符号位(1位) | 指数位(8位) | 尾数位(23位) |\n");
    printf("|------------|------------|------------|\n");
    printf("| 表示正负    | 表示指数    | 表示小数部分 |\n");
    
    // 特殊值
    printf("\n特殊浮点数值:\n");
    
    float pos_inf = 1.0 / 0.0;  // 正无穷大
    float neg_inf = -1.0 / 0.0; // 负无穷大
    float nan_val = 0.0 / 0.0;  // 非数字
    
    printf("正无穷大: %f\n", pos_inf);
    printf("负无穷大: %f\n", neg_inf);
    printf("非数字(NaN): %f\n", nan_val);
    
    // 浮点数精度问题
    printf("\n浮点数精度问题:\n");
    float a = 0.1;
    float b = 0.2;
    float c = a + b;
    
    printf("0.1 + 0.2 = %.20f\n", c);
    printf("是否等于0.3? %s\n", c == 0.3 ? "是" : "否");
    
    // 正确的比较方式
    float epsilon = 0.000001;
    if (c - 0.3 < epsilon && 0.3 - c < epsilon) {
        printf("在误差范围内相等\n");
    }
    
    return 0;
}

🎯 五、综合实战:学生成绩管理系统

#include <stdio.h>
#include <stdint.h>

// 使用位域压缩存储学生信息
struct StudentInfo {
    unsigned int gender : 1;      // 性别: 0=女, 1=男 (1位)
    unsigned int grade : 3;       // 年级: 1-8 (3位)
    unsigned int class_num : 5;   // 班级: 1-31 (5位)
    unsigned int score : 7;       // 分数: 0-127 (7位)
    unsigned int reserved : 16;   // 保留位
};

void printStudentInfo(struct StudentInfo stu) {
    printf("学生信息:\n");
    printf("  性别: %s\n", stu.gender ? "男" : "女");
    printf("  年级: %d\n", stu.grade);
    printf("  班级: %d\n", stu.class_num);
    printf("  分数: %d\n", stu.score);
    
    // 判断等级
    char level;
    if (stu.score >= 90) level = 'A';
    else if (stu.score >= 80) level = 'B';
    else if (stu.score >= 70) level = 'C';
    else if (stu.score >= 60) level = 'D';
    else level = 'F';
    
    printf("  等级: %c\n\n", level);
}

int main() {
    printf("========== 学生成绩管理系统 ==========\n\n");
    
    // 1. 位运算实现快速计算
    printf("1. 位运算计算:\n");
    int student_count = 45;
    
    // 计算需要的组数(每组8人)
    int groups = (student_count + 7) >> 3;  // 等价于 (student_count + 7) / 8
    printf("   学生数: %d, 需要组数: %d\n", student_count, groups);
    
    // 2. 使用位域存储学生信息
    printf("\n2. 学生信息存储:\n");
    struct StudentInfo student1 = {1, 3, 5, 85};
    struct StudentInfo student2 = {0, 2, 7, 92};
    
    printStudentInfo(student1);
    printStudentInfo(student2);
    
    // 3. 成绩统计分析
    printf("3. 成绩统计分析:\n");
    int scores[] = {85, 92, 78, 45, 100, 67, 88, 91, 76, 82};
    int count = sizeof(scores) / sizeof(scores[0]);
    
    int sum = 0;
    int max = scores[0];
    int min = scores[0];
    
    for (int i = 0; i < count; i++) {
        sum += scores[i];
        if (scores[i] > max) max = scores[i];
        if (scores[i] < min) min = scores[i];
    }
    
    float average = (float)sum / count;
    
    printf("   平均分: %.2f\n", average);
    printf("   最高分: %d\n", max);
    printf("   最低分: %d\n", min);
    
    // 4. 使用位运算判断奇偶、计算倍数
    printf("\n4. 位运算应用:\n");
    for (int i = 0; i < count; i++) {
        printf("   分数%d: ", scores[i]);
        
        // 判断是否为4的倍数
        if ((scores[i] & 3) == 0) {  // 相当于 scores[i] % 4 == 0
            printf("是4的倍数, ");
        } else {
            printf("不是4的倍数, ");
        }
        
        // 判断奇偶
        if (scores[i] & 1) {
            printf("奇数\n");
        } else {
            printf("偶数\n");
        }
    }
    
    return 0;
}

💡 学习要点总结

1. 操作符优先级(从高到低)

1. 括号: () []
2. 自增自减: ++ --
3. 乘除取余: * / %
4. 加减: + -
5. 移位: << >>
6. 关系: < <= > >=
7. 相等: == !=
8. 位与: &
9. 位异或: ^
10. 位或: |
11. 逻辑与: &&
12. 逻辑或: ||
13. 条件: ?:
14. 赋值: = += -= 等

记忆口诀:括号成员第一,全体单目第二,乘除余三加减四,移位五,关系六,等与不等排第七,位与异或和位或,逻辑与或九十,条件赋值逗号底。

2. 常见易错点

// 1. 整数除法
int a = 5, b = 2;
float c = a / b;  // 错误!结果是2.0,不是2.5
float d = (float)a / b;  // 正确!2.5

// 2. 自增自减优先级
int x = 5;
int y = ++x * 2;  // x先加1变6,然后6 * 2=12
int z = x++ * 2;  // 先6 * 2=12,然后x加1变7

// 3. 浮点数比较
float f1 = 0.1 + 0.2;
float f2 = 0.3;
if (f1 == f2) {  // 错误!可能不相等
    printf("相等\n");
}
// 应该用
if (fabs(f1 - f2) < 0.00001) {
    printf("相等\n");
}

3. 进制转换速查表

十进制

二进制

八进制

十六进制

记忆技巧

0

0

0

0

都是0

1

1

1

1

都是1

2

10

2

2

二进制满2进1

8

1000

10

8

2³=8

10

1010

12

A

十进制10

15

1111

17

F

二进制4个1

16

10000

20

10

2⁴=16

255

11111111

377

FF

8位全1

4. 实用技巧

  1. 判断奇偶n & 1n % 2

  2. 乘以2的n次方x << n

  3. 除以2的n次方x >> n

  4. 交换两个数a ^= b; b ^= a; a ^= b;

  5. 取绝对值(x ^ (x >> 31)) - (x >> 31)

记住:理解原理比记忆更重要。多写代码,多调试,才能真正掌握这些概念!

❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍

🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐