C语言操作符大全和详解(1)

简介: C语言操作符大全和详解(1)
🌹作者:云小逸
📝个人主页: 云小逸的主页
📝码云: 云小逸 (YunXiaoYi003) - Gitee.com
🤟motto:要敢于一个人默默的面对自己, ==强大自己才是核心==。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前,其次就是现在!学会自己和解,与过去和解,努力爱自己。==希望春天来之前,我们一起面朝大海,春暖花开!==🤟
👏专栏:C++👏 👏专栏:刷题👏
👏专栏:C语言初阶👏👏专栏:数据结构👏

@TOC


前言

本篇文章是C语言操作符大全以及详解
——————————————————————————————
首先先写上几句话:献给坚持创作的我和点开这篇文章希望进步的你

1.有些人的一生,要耗费许多时间,来和自己的性格、童年的阴影,或者原生家庭、某段深刻的影响抗衡。所以他们的路,会比其他人走得==更慢==。

2.世界本来就是这样的,你会认识形形色色的人,会感到失望,会遇到不能理解的恶意。其实熬过去了,就会知道,这都是在提醒你不要成为==那样的人。==

1. 操作符分类:

**算术操作符
==移位操作符
位操作符==
赋值操作符
单目操作符
==关系操作符
逻辑操作符==
条件操作符
逗号表达式
==下标引用、函数调用和结构成员==**

2.算术操作符

 +    -   *   /   %
 要点:
 1.除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
 2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。
 而只要有浮点数执行的就是浮点数除法。
 4.  % 操作符的两个操作数必须为整数。返回的是整除之后的余数。

3.移位操作符

在学习移位操作符之前,我们要知道整数有==二进制,八进制,十进制,十六进制==。

整数的原码,反码,补码:

而整数的二进制有三种表示形式:原码,反码,补码。
正整数的原码、反码、补码相同
==负整数==的原码、反码、补码是要计算的:
1、原码符号位==1不变==,整数的每一位二进制数位==求反==,得到反码
2、反码符号位1不变,反码数值位==最低位加1==,得到补码
例子:
在这里插入图片描述
整数在内存中的存储的是==补码==

好,现在我们来说一说,移位操作符:移动的都是==二进制==

左操作符:

移位规则:==左边舍弃,右边补0==

正整数:
在这里插入图片描述
负整数:
在这里插入图片描述

右操作符:

移位规则:右移运算分两种:

1. 逻辑移位:左边用0填充,右边丢弃

2. ==算术移位==:左边用原该值的符号位填充,右边丢弃

大多数编译器使用的是==算术移位==
正整数:
在这里插入图片描述
负整数:
在这里插入图片描述

注意事项:

移位操作符不可以作用于==浮点数==。
对于移位运算符,不要移动负数位,这个是标准==未定义==的(编译器也不知道怎么处理)

int num = 10;
num>>-1;//error

注意事项

4.位操作符

位操作符有:
// & - 按(2进制)位与,两个同时为1,才为真(1)
// | - 按(2进制)位或
// ^ - 按(2进制)位异或 - 相同为0,相异以1
//注:他们的操作数必须是整数。

==按位与&==,两个数字均为1,才为真(1)

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

// & - 按(2进制)位与,两个数字均为1,才为真(1)
//| - 按(2进制)位或,只要有1,则为真(1)
// ^ - 按(2进制)位异或 - 相同为0,相异以1


int main()
{
    int a = 3;
    int b = -5;
    int c = a & b;
    //00000000000000000000000000000011   3的原,反,补码
    // 
    //10000000000000000000000000000101  -5的原码
    //11111111111111111111111111111010  -5的反码
    //11111111111111111111111111111011  -5的补码
    // 
    //11111111111111111111111111111011  -5的补码
    //00000000000000000000000000000011   3的补码
    //00000000000000000000000000000011  3&-5补码
    // 第一个数字为0,结果为真,所以原码、反码、补码相同
    //00000000000000000000000000000011  3&-5原码、反码、补码
    // ---->>>>c=3
    //%d 意味着打印一个有符号的整数
    //
    printf("c=%d\n", c);//

    return 0;
}

在这里插入图片描述

==按位或|==,只要有1,则为真(1)

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

// & 按(2进制)位与
//| 按(2进制)位或
// ^ 按(2进制)位异或 - 相同为0,相异以1


int main()
{
    int a = 3;
    int b = -5;
    int c = a | b;
    //00000000000000000000000000000011   3的补码
    // 
    //10000000000000000000000000000101  -5的原码
    //11111111111111111111111111111010  -5的反码
    //11111111111111111111111111111011  -5的补码
    // 
    //11111111111111111111111111111011  -5的补码
    //00000000000000000000000000000011   3的补码
    //11111111111111111111111111111011   3|-5的补码,只要有1,则为真(1)
    // 第一个数字为1,为负数
    //11111111111111111111111111111010     3|-5的补码-1得反码
    //10000000000000000000000000000101     3|-5的原码
    //--->>>c=-5
    //%d 意味着打印一个有符号的整数
    //
    printf("c=%d\n", c);

    return 0;
}

在这里插入图片描述

==按位异或^==, 相同为0,相异以1

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

// & - 按(2进制)位与
//| - 按(2进制)位或
// ^ - 按(2进制)位异或 - 相同为0,相异以1

int main()
{
    int a = 3;
    int b = -5;
    int c = a ^ b;
    //00000000000000000000000000000011   3的补码
    // 
    //10000000000000000000000000000101  -5的原码
    //11111111111111111111111111111010  -5的反码
    //11111111111111111111111111111011  -5的补码
    // 
    //11111111111111111111111111111011  -5的补码
    //00000000000000000000000000000011   3的补码
    //11111111111111111111111111111000  3^-5的补码
    // 第一个数字是0,为负数
    //11111111111111111111111111110111  3^-5的反码
    //10000000000000000000000000001000  3^-5的原码
    //----》》》》c=-8
    //%d 意味着打印一个有符号的整数
    //
    printf("c=%d\n", c);

    return 0;
}

在这里插入图片描述

一道变态的==面试题==

不能创建临时变量(==第三个变量==),实现两个数的==交换==。

用临时变量

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

// & - 按(2进制)位与
//| - 按(2进制)位或
// ^ - 按(2进制)位异或 - 相同为0,相异以1

int main()
{
    int a = 3;
    int b = 5;
    int c = 0;//空瓶

    printf("交换前:a=%d b=%d\n", a, b);
    c = a;
    a = b;
    b = c;
    printf("交换后:a=%d b=%d\n", a, b);

    return 0;
}

在这里插入图片描述

用加法,有BUG,会==溢出==(int)

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

// & - 按(2进制)位与
//| - 按(2进制)位或
// ^ - 按(2进制)位异或 - 相同为0,相异以1

int main()
{
    int a = 3;
    int b = 5;
  //这种方法会有溢出的问题
    printf("交换前:a=%d b=%d\n", a, b);
    a = a + b;
    b = a - b;
    a = a - b;
    printf("交换后:a=%d b=%d\n", a, b);

    return 0;
}

在这里插入图片描述

用位异或,比较==靠谱==

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>

// & - 按(2进制)位与
//| - 按(2进制)位或
// ^ - 按(2进制)位异或 - 相同为0,相异以1

 int main()
{
    int a = 3;
    int b = 5;

    printf("交换前:a=%d b=%d\n", a, b);
    a = a ^ b;//a=3^5
    b = a ^ b;//3^5^5 --> b=3
    a = a ^ b;//3^5^3 --> a=5

    printf("交换后:a=%d b=%d\n", a, b);

    return 0;
}

在这里插入图片描述

练习:编写代码实现:求一个整数存储在内存中的二进制中==1的个数==

参考代码:
//方法1
#include <stdio.h>
int main()
{
 int num  = 10;
 int count=  0;//计数
 while(num)
 {
 if(num%2 == 1)
 count++;
 num = num/2;
 }
 printf("二进制中1的个数 = %d\n", count);
 return 0;
}
//思考这样的实现方式有没有问题?
//方法2:
#include <stdio.h>
int main()
{
 int num = -1;
 int i = 0;
 int count = 0;//计数
 for(i=0; i<32; i++)
 {
 if( num & (1 << i) )
 count++; 
 }
 printf("二进制中1的个数 = %d\n",count);
 return 0;
}
//思考还能不能更加优化,这里必须循环32次的。
//方法3:
#include <stdio.h>
int main()
{
 int num = -1;
 int i = 0;
 int count = 0;//计数
 while(num)
 {
 count++;
 num = num&(num-1);
 }
 printf("二进制中1的个数 = %d\n",count);
 return 0;
}
//这种方式是不是很好?达到了优化的效果,但是难以想到。

5. 赋值操作符

赋值操作符是一个==很棒==的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值。

int weight = 120;//体重
weight = 89;//不满意就赋值
double salary = 10000.0;
salary = 20000.0;//使用赋值操作符赋值
赋值操作符可以连续使用,比如:
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//连续赋值
这样的代码感觉怎么样?
那同样的语义,你看看:
x = y+1;
a = x;
这样的写法是不是更加清晰爽朗而且易于调试。

复合赋值符:

+=

*=
/=
%=

        >>=向右移动一位

<<= 向左移动一位

        &=

|=
^=

int x = 10;
x = x+10;
x += 10;//复合赋值
//其他运算符一样的道理。这样写更加简洁。

6. 单目操作符

只有一个操作数
在这里插入图片描述

a.逻辑反操作!

C语言中==0表示假,非0表示真==

//单目操作符!
int main()
{
    int flag = 3;
    //flag为真,进入if
    if (flag)
    {}
    
    //flag为假,进入if
    if(!flag)
    {}

    return 0;

b.负值-


//单目操作符-,&,*
int main()
{
    //int a = -10;
    //int b = -a;
    //printf("%d\n", a); 
    //printf("%d\n", b);

    int a = 10;
    printf("%p\n",  &a);
    int* p = &a;//p就是指针变量

    return 0;
}

c. 操作数的类型长度(以字节为单位)sizeof

int main()
{
    int arr[5] = {0};
    printf("%d\n", sizeof(arr));

    int a = 10;
    int n = sizeof(a);//计算的是a所占内存的大小,单位是字节
    int n = sizeof(int);
    sizeof是一个操作符
    //计算的是变量所占内存空间的大小,单位是字节
    //计算类型所创建的变量占据空间的大小,单位是字节
    printf("n=%d\n", n);

    return 0;
}

一道习题

#include <stdio.h>
void test1(int arr[])
{
 printf("%d\n", sizeof(arr));//(2)
}
void test2(char ch[])
{
 printf("%d\n", sizeof(ch));//(4)
}
int main()
{
 int arr[10] = {0};
 char ch[10] = {0};
 printf("%d\n", sizeof(arr));//(1)
 printf("%d\n", sizeof(ch));//(3)
 test1(arr);
 test2(ch);
 return 0;
}

在这里插入图片描述

40是因为是整形数组4*10
10是因为是字符数组1*10
8 是因为运行环境是x64,故电脑运行的最大内存是==8G==,函数传参传的是int*,后面有提到
8是因为运行环境是x64,故电脑运行的最大内存是==8G==,函数传参传的是==char*==,后面有提到

d.对一个数的二进制按位==取反~==

int main()
{
    int a = 0;
    //~ 是按二进制位取反
    //00000000000000000000000000000000 - 补码
 
    //11111111111111111111111111111111 -> ~a补码
    //11111111111111111111111111111110    ~a反码
    //10000000000000000000000000000001    ~a原码
    //---->>>>>>~a=-1
    printf("%d\n", ~a);//-1

    int a1 = 3;
    //00000000000000000000000000000011   3的补码
    //11111111111111111111111111111100  ~3的补码
    //11111111111111111111111111111011  -3的反码 
    //10000000000000000000000000000100  -3的原码
    //----->>>>>>>~a1=-4
    printf("%d\n", ~a1);

e.如何在(二进制)指定位置上==加减1==

int main()
{
    int a = 13;
    a |= (1 << 4);
    printf("%d\n", a);//a=29

    //在指定位置(二进制)加1
    //00000000000000000000000000001101  13的原码,反码,补码
    //00000000000000000000000000010000        //1<<4相当于1向左移动四位
    //00000000000000000000000000011101  两者按位或|可以得到在指定的位置上加1
    // ————>>>>>>>a=29;
    //从上面我们不难总结出:想在二进制某个位置上加1,可以与(1向左移动n-1位)进行按位或|


    a &= (~(1 << 4));
    printf("%d\n", a);//a=13
    //在指定位置(二进制)减1
    //00000000000000000000000000011101   29的原码,反码,补码
    //11111111111111111111111111101111   取反~(1<<4)
    //00000000000000000000000000001101   两者按位与&可以得到在指定位置减1
    // ----->>>>>a=13;
    // 
    //11111111111111111111111111101111   取反~(1<<4)
    //00000000000000000000000000010000   1<<4相当于1向左移动四位
    //
    
    return 0;
}

在这里插入图片描述

g.前置、后置++,前置、后置- -


int main()
{
    int a1 = 3;
    int b1= ++a1;//前置++,先++,后使用
    //等价于a=a+1,b=a;
    int b2 = a1++;//后置++,先使用,再++
    //等价于b=a, a=a+1
    printf("%d\n", a1);
    printf("%d\n", b1);
    printf("%d\n", b2);

    int a2 = 3;
    int b3 = a2--;
    //等价于b3=a2,a2=a2-1
    //int b3 = --a2;//前置--,先--,后使用
    //等价于a2=a2-1,b3=a2
    printf("%d\n", a2);//2
    printf("%d\n", b3);//3

    int a3 = 10;
    printf("%d\n", a3--);//?
    printf("%d\n", a3);//?

    int a = 10;
    test(a--);

    return 0;
}

在这里插入图片描述

h. 间接访问操作符(解引用操作符)*,取地址符&

int main()
{
    int a = 10;
    int* p = &a;
    *p = 20;
    printf("%d\n", a);

    return 0;
}

在这里插入图片描述

i.强制类型转换()

int main()
{
    //time_t;//long long
    srand((unsigned int)time(NULL));//强制类型转换
    int a = (int)3.14;//将浮点数3.14强制转换为整形
    printf("%d\n", a);
    return 0;
}

在这里插入图片描述在这里插入图片描述

最后

十分感谢你可以耐着性子把它读完和我可以坚持写到这里,送几句话,对你,也对我:

3.赚钱最大的作用,就是能够把自己从生活的琐碎中解放出来,花钱让别人把你生活中的琐碎打理干净,然后让你自己投身到那些值得专注的事业中去。否则的话,赚钱就毫无意义。

4.想要拥有良好的==人际社交关系==,那就不要跟任何人分享成功的喜悦。人生的高光时刻,往往是平凡的一天。没有几个人期望听到你的好消息。只有自己,在心中默默响起了掌声。

  1. 月薪1万与月薪5万差距不只5倍。假设月薪1万,一个月能攒下4000元;月薪5万 ,一个月能攒下4万元。从收入看,差距只是5倍。从结余看,==差距就是10倍。==

6.很多不成熟的底层巨婴都会有一个幻想:一个人奋斗太难,如果有个人能在我身边理解我、包容我、关心我、陪伴我,支持我就好了。这是==白日做梦。==

现实中底层的伴侣,脑子都非常不清醒,只会像电视里演的那样跟你作、闹、争吵、给你拖后腿。 如果你生活无法安定且有比较大的目标,那么暂时最好保持单身比较好。

==成长,永远都是一场孤独的旅行==,没有人会知道你都经历了什么。

最后如果觉得我写的还不错,请不要忘记==点赞==✌,==收藏==✌,加==关注==✌哦(。・ω・。)

愿我们一起加油,奔向更美好的未来,愿我们从懵懵懂懂的一枚==菜鸟==逐渐成为==大佬==。加油,为自己点赞!

目录
相关文章
|
3月前
|
存储 C语言 索引
【C语言篇】操作符详解(下篇)
如果某个操作数的类型在上⾯这个列表中排名靠后,那么⾸先要转换为另外⼀个操作数的类型后执⾏运算。
74 0
|
3月前
|
程序员 编译器 C语言
【C语言篇】操作符详解(上篇)
这是合法表达式,不会报错,但是通常达不到想要的结果, 即不是保证变量 j 的值在 i 和 k 之间。因为关系运算符是从左到右计算,所以实际执⾏的是下⾯的表达式。
257 0
|
27天前
|
存储 缓存 C语言
【c语言】简单的算术操作符、输入输出函数
本文介绍了C语言中的算术操作符、赋值操作符、单目操作符以及输入输出函数 `printf` 和 `scanf` 的基本用法。算术操作符包括加、减、乘、除和求余,其中除法和求余运算有特殊规则。赋值操作符用于给变量赋值,并支持复合赋值。单目操作符包括自增自减、正负号和强制类型转换。输入输出函数 `printf` 和 `scanf` 用于格式化输入和输出,支持多种占位符和格式控制。通过示例代码详细解释了这些操作符和函数的使用方法。
34 10
|
1月前
|
存储 编译器 C语言
【C语言】简单介绍进制和操作符
【C语言】简单介绍进制和操作符
160 1
|
1月前
|
存储 编译器 C语言
初识C语言5——操作符详解
初识C语言5——操作符详解
173 0
|
3月前
|
C语言
C语言操作符(补充+面试)
C语言操作符(补充+面试)
45 6
|
3月前
|
存储 编译器 C语言
十一:《初学C语言》— 操作符详解(上)
【8月更文挑战第12天】本篇文章讲解了二进制与非二进制的转换;原码反码和补码;移位操作符及位操作符,并附上多个教学代码及代码练习示例
59 0
十一:《初学C语言》—  操作符详解(上)
|
4月前
|
C语言
五:《初学C语言》— 操作符
本篇文章主要讲解了关系操作符和逻辑操作符并附上了多个代码示例
44 1
五:《初学C语言》—  操作符
|
5月前
|
C语言
C语言逻辑操作符的短路问题
C语言逻辑操作符的短路问题
|
5月前
|
编译器 C语言
【C语言】:中移位操作符,位操作符详运算规则详解
【C语言】:中移位操作符,位操作符详运算规则详解
44 1