【从0开始跟Chat老师学嵌入式 04】C语言入门 - 运算符和表达式

小白:C语言有哪些运算符和表达式

Chat老师:

C语言中有多种运算符和表达式,用于实现各种操作。以下是C语言中常见的运算符及其分类:

1. 算术运算符

这些运算符用于执行基本的数学运算。

  • + 加法
  • - 减法
  • * 乘法
  • / 除法
  • % 取模(取余数)

2. 赋值运算符

这些运算符用于将值赋给变量。

  • = 简单赋值
  • += 加且赋值
  • -= 减且赋值
  • *= 乘且赋值
  • /= 除且赋值
  • %= 取模且赋值

3. 关系运算符

这些运算符用于比较两个值,返回布尔值(真或假)。

  • == 等于
  • != 不等于
  • > 大于
  • < 小于
  • >= 大于等于
  • <= 小于等于

4. 逻辑运算符

这些运算符用于逻辑运算,返回布尔值。

  • && 逻辑与
  • || 逻辑或
  • ! 逻辑非

5. 位运算符

这些运算符用于按位操作。

  • & 按位与
  • | 按位或
  • ^ 按位异或
  • ~ 按位取反
  • << 左移
  • >> 右移

6. 自增和自减运算符

这些运算符用于增加或减少变量的值。

  • ++ 自增
  • -- 自减

7. 条件运算符(三元运算符)

用于根据条件表达式返回不同的值。

  • ? : 条件表达式

8. 逗号运算符

用于在一条语句中包含多个表达式。

  • , 逗号

9. 指针运算符

用于指针操作。

  • * 间接访问(解引用)
  • & 取地址

10. 其他运算符

包括一些特殊的运算符。

  • sizeof 用于返回数据类型或变量的大小
  • . 结构体成员访问
  • -> 结构体指针成员访问
  • () 函数调用
  • [] 数组下标

表达式

表达式是由运算符和操作数组成的代码片段,可以计算一个值。常见的表达式类型包括:

  • 算术表达式:如 a + ba * (b + c)
  • 关系表达式:如 a > ba == b
  • 逻辑表达式:如 a && b!a
  • 赋值表达式:如 a = 5b += a
  • 复合表达式:如 a = b + (c * d)

这些运算符和表达式是C语言的基础,通过它们可以实现各种复杂的操作和逻辑。

=========================================================================

小白:请帮我详细讲解一下位运算符

Chat老师:

位运算符用于对整数类型的位进行操作。这些运算符主要用于底层编程,如操作硬件、优化性能和实现一些特殊算法。以下是C语言中的位运算符及其详细讲解:

1. 按位与(&)

按位与运算符逐位地对两个操作数进行与操作,只有当两个相应位都为1时,结果位才为1,否则为0。例子:

int a = 12; // 二进制表示为 1100
int b = 10; // 二进制表示为 1010
int result = a & b; // 结果为 8 (二进制表示为 1000)

2. 按位或(|)

按位或运算符逐位地对两个操作数进行或操作,只要两个相应位中有一个为1,结果位就为1。

例子:

 
int a = 12; // 二进制表示为 1100
int b = 10; // 二进制表示为 1010
int result = a | b; // 结果为 14 (二进制表示为 1110)

3. 按位异或(^)

按位异或运算符逐位地对两个操作数进行异或操作,当两个相应位不同,结果位为1,相同时结果位为0。

例子:

 
int a = 12; // 二进制表示为 1100
int b = 10; // 二进制表示为 1010
int result = a ^ b; // 结果为 6 (二进制表示为 0110)

4. 按位取反(~)

按位取反运算符对操作数的每一位进行取反操作,即0变为1,1变为0。

例子:

 
int a = 12; // 二进制表示为 1100
int result = ~a; // 结果为 -13 (二进制表示为 1111 1111 1111 1111 1111 1111 1111 0011)

注意:取反运算会涉及到补码表示,所以结果是-13。

5. 左移运算符(<<)

左移运算符将一个数的各二进制位全部左移若干位,由右边补0。左移一位相当于乘以2。

例子:

 
int a = 12; // 二进制表示为 1100
int result = a << 2; // 结果为 48 (二进制表示为 110000)

6. 右移运算符(>>)

右移运算符将一个数的各二进制位全部右移若干位,左边用符号位补齐(对有符号整数)。右移一位相当于除以2。

例子:

 
int a = 12; // 二进制表示为 1100
int result = a >> 2; // 结果为 3 (二进制表示为 0011)

位运算的常见应用

1. 掩码操作

掩码用于从一个数中提取或设置特定位。例如,从一个数中提取最低的4位:

int a = 29; // 二进制表示为 0001 1101
int mask = 15; // 二进制表示为 0000 1111
int result = a & mask; // 结果为 13 (二进制表示为 1101)

2. 置位和清位

置位(将某一位置1)和清位(将某一位置0)可以通过位运算实现。

 
int a = 29; // 二进制表示为 0001 1101
int bit_position = 3; // 第3位
int set_bit = a | (1 << bit_position); // 将第3位置1
int clear_bit = a & ~(1 << bit_position); // 将第3位置0

3. 判断某一位是否为1

可以通过与操作结合左移运算来判断某一位是否为1。

 
int a = 29; // 二进制表示为 0001 1101
int bit_position = 3; // 第3位
int is_set = a & (1 << bit_position); // 如果结果不为0,则第3位为1

位运算符在C语言中非常强大,通过合理使用可以高效地进行低层次操作。

=========================================================================

小白:14>>2结果如何

Chat老师:

在C语言中,右移运算符(>>)将一个数的各二进制位全部右移指定的位数,并用符号位(对于有符号数)或零(对于无符号数)填充左边的空位。我们来看看 14 >> 2 的结果。

首先,我们将14转换为二进制:

 
14 = 0000 1110

右移2位:

 
0000 1110 >> 2 = 0000 0011

然后将结果转换回十进制:

 
0000 0011 = 3

所以,14 >> 2 的结果是 3

=========================================================================

小白:sizeof 用于返回数据类型或变量的大小举个例子

Chat老师:

sizeof 运算符在C语言中用于返回数据类型或变量的大小(以字节为单位)。这是一个编译时运算符,编译器在编译时就能确定其结果。以下是一些使用 sizeof 的例子:

1. 获取基本数据类型的大小

 
#include <stdio.h>

int main() {
    printf("Size of char: %zu bytes\n", sizeof(char));
    printf("Size of int: %zu bytes\n", sizeof(int));
    printf("Size of float: %zu bytes\n", sizeof(float));
    printf("Size of double: %zu bytes\n", sizeof(double));
    return 0;
}

2. 获取变量的大小

 
#include <stdio.h>

int main() {
    char a;
    int b;
    float c;
    double d;

    printf("Size of variable a: %zu bytes\n", sizeof(a));
    printf("Size of variable b: %zu bytes\n", sizeof(b));
    printf("Size of variable c: %zu bytes\n", sizeof(c));
    printf("Size of variable d: %zu bytes\n", sizeof(d));
    return 0;
}

3. 获取数组的大小

 
#include <stdio.h>

int main() {
    int arr[10];

    printf("Size of array arr: %zu bytes\n", sizeof(arr));
    printf("Number of elements in array arr: %zu\n", sizeof(arr) / sizeof(arr[0]));
    return 0;
}

4. 获取结构体的大小

 
#include <stdio.h>

struct Person {
    char name[50];
    int age;
    float height;
};

int main() {
    struct Person person;

    printf("Size of struct Person: %zu bytes\n", sizeof(struct Person));
    printf("Size of variable person: %zu bytes\n", sizeof(person));
    return 0;
}

解释

  1. 基本数据类型的大小

    • sizeof(char) 返回 char 类型的大小,通常是1字节。
    • sizeof(int) 返回 int 类型的大小,通常是4字节(具体大小取决于系统和编译器)。
    • sizeof(float) 返回 float 类型的大小,通常是4字节。
    • sizeof(double) 返回 double 类型的大小,通常是8字节。
  2. 变量的大小

    • sizeof(a) 返回变量 a 的大小,其类型为 char
    • sizeof(b) 返回变量 b 的大小,其类型为 int
    • sizeof(c) 返回变量 c 的大小,其类型为 float
    • sizeof(d) 返回变量 d 的大小,其类型为 double
  3. 数组的大小

    • sizeof(arr) 返回整个数组 arr 的大小,数组包含10个 int 类型的元素。
    • sizeof(arr) / sizeof(arr[0]) 计算数组中元素的个数。
  4. 结构体的大小

    • sizeof(struct Person) 返回结构体 Person 的大小,包含一个 char 数组(50字节)、一个 int 和一个 float

在这些例子中,%zu 用于打印 size_t 类型的值,这是 sizeof 返回的类型。使用 sizeof 可以帮助我们了解数据类型和变量在内存中占用的确切字节数,这在编写与内存相关的代码时尤为重要。

=========================================================================

小白:. 结构体成员访问 举个例子

Chat老师:

结构体是一种用户自定义的数据类型,可以存储不同类型的数据项。在C语言中,使用点运算符(.)来访问结构体的成员。下面我会举一个简单的例子来说明如何定义和访问结构体成员。

示例

#include <stdio.h>

// 定义一个结构体类型
struct Person {
    char name[50];
    int age;
    float height;
};

int main() {
    // 声明一个结构体变量
    struct Person person1;

    // 向结构体变量的成员赋值
    strcpy(person1.name, "Alice");
    person1.age = 25;
    person1.height = 1.75;

    // 访问结构体变量的成员并打印输出
    printf("Person's name: %s\n", person1.name);
    printf("Person's age: %d\n", person1.age);
    printf("Person's height: %.2f meters\n", person1.height);

    return 0;
}

解释

  1. 定义结构体

     
    struct Person {
        char name[50];
        int age;
        float height;
    };
    

  2. 声明结构体变量

    struct Person person1;
    

    这行代码声明了一个名为 person1 的结构体变量,类型为 struct Person

  3. 访问结构体成员: 使用点运算符(.)来访问结构体变量的成员:

    • person1.name 访问结构体 person1name 成员。
    • person1.age 访问结构体 person1age 成员。
    • person1.height 访问结构体 person1height 成员。
  4. 赋值和输出

    • strcpy(person1.name, "Alice"); 使用 strcpy 函数将字符串 "Alice" 复制到 person1.name 成员中。
    • person1.age = 25;person1.age 赋值为 25
    • person1.height = 1.75;person1.height 赋值为 1.75
  5. 打印输出: 使用 printf 函数将结构体 person1 的成员值打印出来。

结构体允许我们将不同类型的数据组织在一起,使得程序更加模块化和可读性更强。通过点运算符,我们可以方便地访问和操作结构体的各个成员。

=========================================================================

小白:-> 结构体指针成员访问 举个例子

Chat老师:

在C语言中,结构体指针成员访问使用箭头运算符 ->,它用于通过指向结构体的指针来访问结构体的成员。下面我会举一个简单的例子来说明如何使用箭头运算符访问结构体指针的成员。

示例

#include <stdio.h>
#include <stdlib.h> // 包含 malloc 函数的头文件

// 定义一个结构体类型
struct Person {
    char name[50];
    int age;
    float height;
};

int main() {
    // 声明一个结构体指针
    struct Person *personPtr;

    // 使用 malloc 函数动态分配结构体内存
    personPtr = (struct Person *) malloc(sizeof(struct Person));

    // 检查内存分配是否成功
    if (personPtr == NULL) {
        fprintf(stderr, "Memory allocation failed!\n");
        return 1;
    }

    // 向结构体成员赋值
    strcpy(personPtr->name, "Bob");
    personPtr->age = 30;
    personPtr->height = 1.80;

    // 访问结构体指针的成员并打印输出
    printf("Person's name: %s\n", personPtr->name);
    printf("Person's age: %d\n", personPtr->age);
    printf("Person's height: %.2f meters\n", personPtr->height);

    // 释放动态分配的内存
    free(personPtr);

    return 0;
}

解释

  1. 定义结构体

    struct Person {
        char name[50];
        int age;
        float height;
    };
    

    这里定义了一个名为 Person 的结构体,它有三个成员:name(一个包含50个字符的数组)、age(一个整数)和 height(一个浮点数)。

  2. 声明结构体指针

    struct Person *personPtr;
    

    这行代码声明了一个名为 personPtr 的结构体指针,类型为 struct Person *

  3. 动态分配内存: 使用 malloc 函数动态分配结构体 Person 的内存:

    personPtr = (struct Person *) malloc(sizeof(struct Person));
    

    malloc 函数返回一个指向分配的内存块的指针,需要将其类型转换为 struct Person *

  4. 检查内存分配: 使用 if (personPtr == NULL) 来检查内存分配是否成功。如果 malloc 返回 NULL,表示内存分配失败。

  5. 通过结构体指针赋值: 使用箭头运算符 -> 来访问结构体指针的成员并赋值:

    • strcpy(personPtr->name, "Bob"); 使用 strcpy 函数将字符串 "Bob" 复制到 personPtr 指向的结构体的 name 成员中。
    • personPtr->age = 30;personPtr 指向的结构体的 age 成员赋值为 30
    • personPtr->height = 1.80;personPtr 指向的结构体的 height 成员赋值为 1.80
  6. 打印输出: 使用 printf 函数将结构体指针 personPtr 指向的结构体成员值打印出来。

  7. 释放内存: 使用 free(personPtr); 函数释放动态分配的内存,避免内存泄漏。

结构体指针允许我们动态地分配和管理内存,特别是在需要在函数之间传递复杂数据结构时非常有用。箭头运算符 -> 是访问结构体指针成员的关键操作符。

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值