C语言操作符详解一(操作符详解及代码示例)

一. 操作符分类:

1.算术操作符(+、-、*、/、%)
2.移位操作符(<<、>>)
3.位操作符(&、|、^)
4.赋值操作符(=、+=、-=、&=、*=……)
5.单目操作符(!、-、+、&、*、sizeof、~、--、++)
6.关系操作符(==、<、>)
7.逻辑操作符(&&、||)
8.条件操作符(?~:~)唯一的三目操作符
9.逗号表达式(,)
10下标引用、函数调用和结构成员([ ]、()、访问结构成员(.)、->)

二. 操作符介绍:

一.算术操作符(+、-、*、/、%)

                          加 减  乘  除  取余

1. 除了 % (取余) 操作符之外,其他的几个操作符可以作用于整数和浮点数。
2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
//代码示例
#include <stdio.h>

int main() {
    int a = 10, b = 5;
    printf("a + b = %d\n", a + b); // 输出: 15
    printf("a - b = %d\n", a - b); // 输出: 5
    printf("a * b = %d\n", a * b); // 输出: 50
    printf("a / b = %d\n", a / b); // 输出: 2
    printf("a %% b = %d\n", a % b); // 输出: 0
    return 0;
}

二.移位操作符(<<、>>)

                   左移操作符  右移操作符

注:移位操作符的操作数只能是整数!

以下介绍一下整数的二进制表示形式:

首先,整数的二进制表示形式有三种:原码,反码,补码。

  1. 原码:原码表示整数时,最高位(符号位)用于表示正负,0表示正数,1表示负数。其余位表示数值的绝对值。例如,8位原码中,正数+5的表示为00000101,负数-5的表示为10000101。

  2. 反码:反码是在原码的基础上,对负数的每一位取反,正数的反码与原码相同。例如,+5的反码是00000101,-5的反码是11111010(在原码基础上取反)。

  3. 补码:补码是在反码的基础上加1,用于解决计算中的一些问题,如零的唯一表示和简化加减运算。+5的补码是00000101,-5的补码是11111011(反码11111010加1)。

整数在内存中存储的都是补码的二进制序列,整数在计算的时候也是用补码

对于一个整数 4个字节(byte)=32个bit位

二进制序列:32个bit位   由32个1/0的二进制空组成(对于有符号的整数来说,最高位的1位为符号位)

符号位正或负数
1正数
0负数

对于正的整数,原码,反码,补码相同无需计算

对于负的整数,原码,反码,补码相同需计算

2.1 移位操作符(<<)左移操作符
移位规则:
左边抛弃、右边补 0

eg:

1.10的原码,反码,补码(正数,无需计算)

00000000000000000000000000001010 

 原码

00000000000000000000000000001010   

反码

00000000000000000000000000001010 

 补码

2.-10的原码,反码,补码(负数,需要计算)

10000000000000000000000000001010   

原码

111111111111111111111111111111110101   

反码(在原码基础上除符号位,其他位取反)

111111111111111111111111111111110110 

 补码(在反码基础上加一)

10左移后   a=10<<1  得a的值应为20    

00000000000000000000000000001010 
00000000000000000000000000010100(整体左移后右端补0)
2.1 移位操作符(>>)右移操作符

移位规则:
首先右移运算分两种:
1. 逻辑移位
左边用 0 填充,右边丢弃
2. 算术移位
左边用原该值的符号位填充,右边丢弃
*两种移位与编译器有关,算术移位较为普遍
//代码示例
#include <stdio.h>

int main() {
    unsigned int a = 5;  // 二进制: 00000101
    unsigned int b = 3;  // 二进制: 00000011

  
    printf("a << 1 = %u\n", a << 1); // 输出: 10 (00001010)
    printf("a >> 1 = %u\n", a >> 1); // 输出: 2  (00000010)
    return 0;
}

三.位操作符(&、|、^)

                      与  或  异或(操作数必须为整数)

计算之前需要转化为二进制 ,再分别按照每位进行对照计算

“&”\\按位与:两个位都为1时,结果才为1

“|”\\按位或:两个位都为0时,结果才为0

“^”\\按位异或:两个位相同为0,相异为1

//代码示例
#include <stdio.h>

int main() {
    unsigned int a = 5;  // 二进制: 00000101
    unsigned int b = 3;  // 二进制: 00000011

    printf("a & b = %u\n", a & b); // 输出: 1  (00000001)
    printf("a | b = %u\n", a | b); // 输出: 7  (00000111)
    printf("a ^ b = %u\n", a ^ b); // 输出: 6  (00000110

用途:

例:不能创建临时变量(第三个变量),实现两个数的交换(一道变态的面试题)

        对于这个问题要对于操作符有着强烈的印象和理解。在C语言中,可以通过使用异或(XOR)操作来实现两个变量的值交换,而不需要借用中间变量。这种方法利用了异或操作的性质:

1. **异或操作性质**:
   - `a ^ a = 0`:任何数和自己异或的结果是0。
   - `a ^ 0 = a`:任何数和0异或的结果是其本身。
   - 异或操作具有交换律和结合律。

2. **交换原理**:
   - 假设有两个变量 `a` 和 `b`,我们希望交换它们的值。
   - 可以通过如下方式实现:

3. **执行步骤解析**:
   - `a = a ^ b`:此时 `a` 存储了 `a` 和 `b` 的异或结果。
   - `b = a ^ b`:由于 `a` 已经是 `a ^ b`,因此此操作将 `b` 更新为原始的 `a` 的值(即 `a ^ b ^ b = a`)。
   - `a = a ^ b`:此时 `a` 存储了原始的 `b` 的值(即 `a ^ b ^ a = b`)。

通过以上三步操作,就完成了 `a` 和 `b` 的值交换,而不需要额外的中间变量。

#include <stdio.h>

void swap(int *a, int *b) 
{
    *a = *a ^ *b;
    *b = *a ^ *b;
    *a = *a ^ *b;
}

int main() 
{
    int x = 5, y = 10;
   
    printf("Before swap: x = %d, y = %d\n", x, y);
    swap(&x, &y);
    printf("After swap: x = %d, y = %d\n", x, y);
    
    return 0;
}

输出结果为:
Before swap: x = 5, y = 10

After swap: x = 10, y = 5

这样就成功地通过异或操作实现了变量 `x` 和 `y` 的值交换,而不借助中间变量。

四.赋值操作符(=、+=、-=、&=、*=……)

注意区分赋值(=)与关系操作符(==)

\\代码示例
#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 %= 4;  // 等同于 a = a % 4
    printf("a %%= 4: %d\n", a); // 输出: 2
    return 0;
}

五.单目操作符(!、-、+、&、*、sizeof、~、--、++)

!              逻辑反操作
-              负值
+            正值
&             取地址
sizeof     操作数的类型长度(以字节为单位)
~            对一个数的二进制按位取反
--             前置、后置 --
++           前置、后置 ++
*              间接访问操作符 ( 解引用操作符 )
( 类型 )      强制类型转换

注意:-- 和 ++ :他们都分为前置++(--)和后置++(--);

前置++(--)是先++,再赋值;

后置++(--) 是先赋值,再++(--);

\\++的代码示例
#include <stdio.h>

int main() 
{
    int a = 10;
    printf("a++ = %d\n", a++); // 输出: 10
    printf("a = %d\n", a);     // 输出: 11

    printf("++a = %d\n", ++a); // 输出: 12
    printf("a = %d\n", a);     // 输出: 12

    return 0;
}

六.关系操作符(==、<、>)

>
>=
<
<=
!=        用于测试 不相等
==       用于测试 相等
警告:
在编程的过程中 == = 不小心写错,导致的错误。
\\代码示例
#include <stdio.h>

int main() 
{
    int a = 10, b = 20;
    printf("a == b: %d\n", a == b); // 输出: 0 (false)
    printf("a != b: %d\n", a != b); // 输出: 1 (true)
    printf("a > b: %d\n", a > b);   // 输出: 0 (false)
    printf("a < b: %d\n", a < b);   // 输出: 1 (true)
    printf("a >= b: %d\n", a >= b); // 输出: 0 (false)
    printf("a <= b: %d\n", a <= b); // 输出: 1 (true)
    return 0;
}

七.逻辑操作符(&&、||)

逻辑操作符有哪些:
1.&&(左边操作数若为假,右边无需计算)
逻辑与
2.||   (左边操作数若为真,右边无需计算)
逻辑或

区分逻辑与和按位与
区分逻辑或和按位或

1&2----->0
1&&2---->1
1|2----->3
1||2---->1

例 :请问以下程序输出的结果是什么?

#include <stdio.h>
int main()
{
    int i = 0,a=0,b=2,c =3,d=4;
    i = a++ && ++b && d++;
    //i = a++||++b||d++;
    printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
    return 0;
}
//程序输出的结果是什么?

在这段程序中,运算符 && 是逻辑与运算符,而 || 是逻辑或运算符。我们来看第一个 i = a++ && ++b && d++; 的情况:

  1. a++ 是后缀递增,值为 0,但 a 会变为 1。
  2. ++b 是前缀递增,b 会先变为 3,然后使用这个值。
  3. d++ 是后缀递增,值为 4,但 d 会变为 5。

由于逻辑与运算符 && 的短路特性,整个表达式的值取决于第一个表达式的结果。具体来说:

  • a++ 的结果是 0,a++ 被计算为 false
  • 由于 a++ 是 false,逻辑与运算符的短路规则会使得 ++b 和 d++ 不再被计算。

因此,最终的值 i 是 0。

printf 语句中,a 已经变成 1,b 变成了 3(因为 ++b 被跳过),d 变成了 5(因为 d++ 被跳过),c 没有变化,仍然是 3。

最终输出为:

a = 1 b = 3 c = 3 d = 5

八.条件操作符(?~:~)唯一的三目操作符

三目操作符: 

exp1?exp2:exp3

  真     计算  计算

  假     不算  计算      

\\代码示例
#include <stdio.h>

int main() 
{
    int a = 10, b = 20;
    int max = (a > b) ? a : b; // 如果 a > b,max = a,否则 max = b
    printf("max = %d\n", max); // 输出: 20
    return 0;
}

九.逗号表达式(,)

exp1 , exp2 , exp3 , …… expn
逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
\\代码示例
#include <stdio.h>

int main() 
{
    int a = 1, b = 2;
    int c = (a++, b++);
    printf("a = %d, b = %d, c = %d\n", a, b, c); // 输出: a = 2, b = 3, c = 3
    return 0;
}

十.下标引用、函数调用和结构成员([ ]、()、访问结构成员(.)、->)

1. [ ] 下标引用操作符
操作数:一个数组名 + 一个索引值
int arr [ 10 ]; // 创建数组
arr [ 9 ] = 10 ; // 实用下标引用操作符。
[ ] 的两个操作数是 arr 9
2. ( ) 函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
3. 访问一个结构的成员
. 结构体 . 成员名
-> 结构体指针 -> 成员名

三.结尾

       对于C语言的学习来说,操作符属于基础知识,需要大家反复实操在练习中了解真正的操作符用法,以解决各种难题,如本文中提到的各种面试题,或许很难想到,但我相信在大家的反复练习和学习中一定可以解决这种复杂的难题,提升自己。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值