C语言操作符详解(上)

C语言操作符详解 C语言操作符详解,位运算,运算符,sizeof和数组,访问结构体成员 阅读详情

前言

在C语言中,C标准提供了丰富的操作符,被用来对数据进行操作和计算,常用数学计算、比较、逻辑运算等操作。操作符是编程语言中非常重要的一部分,它们可以使程序更加简洁、高效,同时也可以增强代码的可读性和可维护性。本文将详细系统介绍C语言操作符,希望能帮读者全面理解C语言操作符!

1. 算术操作符

算术操作符分为以下5种,虽然简单,但还是有一些细节需要注意。

(+)、(-)、(*)、(/)、(%)

  • 除了%(取余)操作符之外,其他几个操作符可以作用于整数和浮点数。
  • 对于/操作符,如果两个操作数都为整数,执行整数除法。而只要有一个浮点数就执行浮点数除法。
  • %操作符的两个操作数必须为整数。返回的是整除之后的余数。

2. 移位操作符

在C语言中,移位操作符分为以下两种

  • <<左移操作符
  • >>右移操作符

相关知识补充:

#include <stdio.h>
int main()
{
	int a = 15;
	//00000000000000000000000000001111 - 原码
	//00000000000000000000000000001111 - 反码
	//00000000000000000000000000001111 - 补码

	int b = -15;
	//10000000000000000000000000001111 - 原码
	//11111111111111111111111111110000 - 反码
	//11111111111111111111111111110001 - 补码
	return 0;
}

Tips:

  • 位移操作符的操作数只能是整数。
  • 计算机能处理的是二进制的信息。而整数的二进制表示形式分为三种:原码、反码、补码。
  • 正整数的原码、反码、补码是相同的。负整数的反码是原码符号位不变,其他未按位取反、反码在加1就得到补码。

2.1 左移操作符(<<)

移位规则:

左边抛弃、右边补0

例子:

#include <stdio.h>
int main()
{
	int a = 15;
	//00000000000000000000000000001111 - (a)补码

	int b = a << 1;
	//对a的补码右移一位得到b的补码,左边抛弃,右边补0
	//00000000000000000000000000011110 - (b)补码
	//00000000000000000000000000011110 - (b)反码
	//00000000000000000000000000011110 - (b)原码
	
	printf("b=%d\n", b); //b得值为:30
	return 0;
}

2.2 右移操作符(>>)

移位规则:

C语言中,右移运算分为两种:

  1. 逻辑右移:左边用0填充,右边丢弃。
    2. 算术右移:左边用原该值的符号位填充,右边丢弃。

上述两种运算方式,C语言没有明确规定到底是算术右移还是逻辑右移。但一般编译器上采用的是算术右移。
例子:

int main()
{
	int a = -15;
	//10000000000000000000000000001111 - 原码
	//11111111111111111111111111110000 - 反码
	//11111111111111111111111111110001 - 补码

	int b = a >> 1;
	//左边用原该值的符号位填充,右边丢弃
	//11111111111111111111111111111000 - 补码
	//11111111111111111111111111110111 - 反码
	//10000000000000000000000000001000 - 原码
	
	printf("b=%d\n", b); //b的值为:-8
	return 0;
}

警告:
对于移位运算符,不要移动负位数,这个行为C标准未定义的。

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

3. 位操作符

在C语言中,位操作符有以下三种:&(按位与)、|(按位或)、^(按位异或)。
Tips:位操作符的操作数必须是整数,同时也是操作二进制位的。

3.1 按位与(&)

& — 补码对应的二进制位有0则为0,两个同时为1才是1.

例子:

int main()
{
	int a = 3;
	//00000000000000000000000000000011 - 补码
	int b = -5;
	//10000000000000000000000000000101 - 原码
	//11111111111111111111111111111010 - 反码
	//11111111111111111111111111111011 - 补码

	int c = a & b;
	//&补码对应的二进制位有0则为0,两个同时为1才是1.
	//00000000000000000000000000000011 - 补码(a)
	//11111111111111111111111111111011 - 补码(b)
	//00000000000000000000000000000011 - 补码(c)

	printf("c=%d\n", c); //c的值为:3
	return 0;
}

3.2 按位或(|)

| — 补码对应的二进制位有1则为1,两个同时为0才是0.

例子:

int main()
{
	int a = 3;
	//00000000000000000000000000000011 - 补码
	int b = -5;
	//10000000000000000000000000000101 - 原码
	//11111111111111111111111111111010 - 反码
	//11111111111111111111111111111011 - 补码

	int c = a | b;
	//&补码对应的二进制位有1则w为1,两个同时为0才是0.
	//00000000000000000000000000000011 - 补码(a)
	//11111111111111111111111111111011 - 补码(b)
	//11111111111111111111111111111011 - 补码(c)

	//11111111111111111111111111111010 - 反码(c)
	//10000000000000000000000000000101 - 原码(c)

	printf("c=%d\n", c);//c的值为:-5
	return 0;
}

3.4 按位异或(^)

|^— 补码对应的二进制位不相同则为1,两个相同则为0.

int main()
{
	int a = 3;
	//00000000000000000000000000000011 - 补码
	int b = -5;
	//10000000000000000000000000000101 - 原码
	//11111111111111111111111111111010 - 反码
	//11111111111111111111111111111011 - 补码

	int c = a ^ b;
	//^ 补码对应的二进制位不相同则为1,两个同时为1或0时才是0.

	//00000000000000000000000000000011 - 补码(a)
	//11111111111111111111111111111011 - 补码(b)
	//11111111111111111111111111111000 - 补码(c)

	//11111111111111111111111111110111 - 反码(c)
	//10000000000000000000000000001000 - 原码(c)

	printf("c=%d\n", c);//c的值为:-8
	return 0;
}

3.5 一道变态的面试题

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

int main()
{
	int a = 10;
	int b = 20;
	//交换,按位异或是支持交换律的
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("a=%d b=%d\n", a, b);
	return 0;
}
  • 按位异或是支持交换律的。

4. 关系操作符

在这里插入图片描述
这些关系运算符比较简单,没什么可介绍的。

5. 单目操作符

单目操作符介绍:

在这里插入图片描述

5.1 单目操作符(!)

(!)逻辑反操作,顾名思义就是把真变成假,把假变成真。

int main()
{
	int flag = 0;//下面两种判断flag为0就执行语句的方法,效果一样
	//方法1:
	if (flag == 0)
	{
		//语句;
	}

	//方法2:flag为0,则为假。!flag则为真,执行语句
	if (!flag)
	{
		//语句;
	}
	return 0;
}

5.2 单目操作符(~)

单目操作符(~)是按补码二进制位全部取反.(包括符号位)

例子:

int main()
{
	int a = 0;
	//00000000000000000000000000000000 - 补码

	int b = ~a;
	//~a--对a的补码全部取反
	//11111111111111111111111111111111 - 补码
	//11111111111111111111111111111110 - 补码
	//10000000000000000000000000000001 - 原码

	printf("%d\n", b); //b的值位:-1
	return 0;
}

5.3 单目操作符(&、*)

单目操作符(&、*)都运用于指针。

int main()
{
	int a = 0;
	//pa是指针变量
	int* pa = &a; //&—取地址操作符—取出a的地址
	
	//解引用操作符(间接访问操作符)—通过pa中存放的地址,找到指向的空间(内容)
	*pa = 20;
	return 0;
}

5.4 单目操作符(++、–)

单目单目操作符++(- -),分为前置++(- -)和后置++(–)
前置++(–): 先++(- -),在使用。
后置++(–): 先使用,在++(- -)。

例子1:

int main()
{

	int a = 2;
	int b = --a; //前置--,先--,在使用
	//a=a-1,b=a
	printf("a=%d b=%d\n", a, b);//a,b的值都为:1	
	return 0;
}

例子2:

int main()
{
	int a = 2;
	int b = a--; //后置--,先使用,在--
	//b=a,a=a-1
	printf("a=%d b=%d\n", a, b);//a的值为1,b的值为2
	return 0;
}

前置++和后置++同理。

5.5 单目操作符(sizeof)和数组

单目操作符(sizrof)用于计算操作数的类型长度。(单位字节)

#include <stdio.h>
void test1(int arr[])
{
	printf("%d\n", sizeof(arr));
}

void test2(char ch[])
{
	printf("%d\n", sizeof(ch));
}
int main()
{
	int arr[10] = { 0 };
	char ch[10] = { 0 };
	printf("%d\n", sizeof(arr));//10X4
	printf("%d\n", sizeof(ch)); //10X1
	test1(arr);
	test2(ch);
	return 0;
}

运行结果(x64环境下):
在这里插入图片描述
上述前两个结果毋庸置疑,但为什么后两个都是8byte呢?
上面调用函数test1()和test2(),传过去的是指针。C语言中,在64位机器上(x64),指针大小为8byte;在32位机器上(x86)上,指针大小为4byte.

6. 逻辑操作符

C语言中,逻辑操作符分为以下两种:

&&—逻辑与
||—逻辑或

简单来说:逻辑与(&&)就是两个同时城里时为真,否则为假;逻辑或(||)则是只要有一个成立则为真,否则为假。
Tips:

  • &&操作符,左边为假,右边就不计算了。
  • ||操作符,左边为真,右边就不用计算了。

例子1:

#include <stdio.h>
int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	//后置++,先使用a,后再执行++
	//&&操作符,左边为假,右边就不计算了
	//a先使用,为0,则为假。所以&&后面所有运算都不执行
	i = a++ && ++b && d++;
	//结果:a=1 b=2 c=3 d=4
	printf("a=%d b=%d c=%d d=%d\n", a, b, c, d);
	return 0;
}

例子:

#include <stdio.h>
int main()
{
	int i = 0, a = 0, b = 2, c = 3, d = 4;
	//||操作符,左边为真,右边就不用计算了。
	//使用b时,b先++后使用,别的值为3,非0为真。所以后面所有运算都不进行
	i = a++ || ++b || d++;
	//结果:a=1 b=3 c=3 d=4
	printf("a=%d b=%d c=%d d=%d\n", a, b, c, d);
	return 0;
}

7. 条件操作符

C语言中,条件操作符如下:表达式exp1为真,则执行表达式exp2,否则执行表达式exp3.

exp1 ? exp2 : exp3

例子:

int main()
{
	int a = 0;
	int b = 0;
	//a为0小于5,执行表达式xep3。所以b=-3
	b = (a > 5) ? 3 : -3;
	return 0;
}

8. 逗号表达式

C语言中,逗号表达式就是:用逗号隔开的多个表达式。

exp1, exp2, exp3, …expN

例子:

int main()
{
	int a = 1;
	int b = 2;
	int c = (a > b, a = b + 10, a, b = a + 1);//逗号表达式
	printf("c=%d\n", c);//结果为:c=13
	return 0;
}

那在上述代码中,为什么c的值最终为13呢?

  • 逗号表达式中,从左到右依次计算。整个表达式的结果为最后一个表达式的结果。

例子:

int d=1;
if(a=a+1,c=a/2,d>0)//d大于0,结果为真,执行if后的语句块
{
	…
}

9. 下标引用、函数调用和结构成员

9.1 [ ] 下标引用操作符

在C语言中,下标引用的操作数为:一个数组名 + 一个索引值(两个操作数满足交换律)

例子:

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };//数组的起始是有下标的,下标从0开始
	//			    0 1 2 3 4 5 6 7 8 8 9
	printf("%d\n", arr[2]);// [] 下标引用操作符,arr和2是两个操作数
	printf("%d\n", 2[arr]);
	return 0;
}
  • 上述代码中2[arr]虽然看起来奇怪,但却是成立的,和arr[2]等价。[ ]和+一样,都是操作数,和两个操作数的前后顺序无关。

9.2 ( ) 函数调用操作符

( ) 函数调用操作符可以接受一个或多个操作数:第一个操作数是函数名,剩余操作数就是传递给函数的参数。

例子:

#include <stdio.h>
#include <string.h>
int Add(int x, int y)
{
	return x + y;
}

int main()
{
	int len = strlen("abc");//( )函数调用操作符
	//()的操作数是:strlrn 和 "abc
	printf("%d\n", len);

	int c = Add(3, 5);//( ) 函数调用操作符
	//()的操作数是:Add 和3 5
	//对于函数调用操作符来说,至少有一个操作数

	printf("%d\n", c);
	return 0;
}

9.3 访问一个结构的成员

在C语言中,访问一个结构的成员有两种方式:

. — 结构体 . 成员名
-> — 结构体 -> 成员名

例子1:

#include <stdio.h>
//定义一个struct Book类型
struct Book
{
	char name[30];
	char author[20];
	float price;
};

int main()
{
	struct Book b= { "C primer Plus","Stephen Prate",47.8f };//创建一个变量b
	//结构体.成员名,答应相关信息
	printf("%s %s %.1f\n", b.name, b.author, b.price);
	return 0;
}

例子2:

struct Book
{
	char name[30];
	char author[20];
	float price;
};
//定义过程
void print(struct Book* b)
{
	//结构指针->成员名,访问成员
	printf("%s %s %.1f\n", b->name, b->author, b->price);
}

int main()
{
	struct Book b= { "C primer Plus","Stephen Prate",47.8f };//创建一个变量b
	//封装print()函数,打印信息
	print(&b);
	return 0;
}

10. 结尾

本篇文章到此就结束了!在C语言操作符详解(上)已经将C语言中所有操作全部详细系统的介绍完了,接下来将在C语言操作符详解(下)中详细介绍编译器执行这些代码背后所做的事情、操作符优先级、结合性以及求值顺序!
创作不易,如果对你有帮助,记得点赞加关注哦!感谢您的支持,同时也欢迎读者发表自己的见解!
C语言操作符详解(下)

Adversarial Texture for Fooling Person Detectors in the Physical World 本文提出了对抗纹理的想法(AdvTexture),与基本补丁攻击不同对抗纹理可以生成任意大小,可以覆盖任意大小的不了,并且纹理的任何局部都有对抗性的效果。当衣服被对抗纹理覆盖是,摄像头捕捉到的每一个局部区域都可以攻击探测器,这成功解决了片段缺失的问题。提出了一种两阶段生成方法:基于环形收割的可扩展生成攻击(TC-EGA)来制作广告纹理。第一阶段,训练一个全卷积网络FCN作为生成器,通过采样随机潜变量作为输入来产生纹理(不同于GAN中传统的生成器架构,每一层都使用卷积运算)...... 阅读详情

相关推荐

HCIP-Cloud Service DevOps Engineer V2.0 华为认证云服务 DevOps高级工程师 章节测试题+结课测试题(模拟考试题)汇总

本文为HCIP-Cloud Service DevOps Engineer V2.0 华为认证云服务DevOps高级工程师 在线课程中所有章节测试以及结课测试(HCIP-Cloud Service DevOps Engineer模拟考试)习题和答案

gaogao0305的博客 2267

C语言的一些基本的操作

本文主要讨论一些C语言基本的操作符和一些小例题;对于一个优秀的程序员来说,添加必要的注释是必不可少的,这有利于后期代码的维护;也方便别人能够更加流畅的阅读你的代码; 而在C语言中呢,主要有两种注释风格: 1、 像这种注释风格,是C语言本身的,它采用 /*这里是需要被注释的内容 */ 这种注释方式; 这种注释方式的优点呢,在于自由的注释掉一段代码块,能大量注释掉不想要的; 缺点就是“ / * ” 总是与 与之最近的 “ * / ”相匹配,不支持嵌套使用; 2、 这种注释风格,并不是C语言自带的,而是来源于C

南猿北者博客 2335

【Linux】U盘配置Ubuntu系统 ——(Win10+Ubuntu20.04)双系统安装教程

Ubuntu系统安装

WS_Change的博客 4334

超详细C语言文件操作,学完对文件了解更进一步

什么是文件,文件指针,文件操作函数等等

fight_p的博客 1189

Ruoyi-Cloud-Plus新手必看:Gateway启动失败的两种解决方案(Nacos配置空间问题)

本文详细解析了Ruoyi-Cloud-Plus框架中Gateway启动失败的常见原因及解决方案,重点围绕Nacos配置空间问题展开。针对新手开发者,提供了两种实用方案:快速切换到public空间或规范创建dev空间并迁移配置,帮助开发者高效解决网关启动故障,确保微服务项目顺利运行。

weixin_30872499的博客 492

CST实战:变容二极管电容曲线提取全流程(附S参数设置技巧)

本文详细介绍了在CST Studio Suite中提取变容二极管电容-电压(C-V)曲线的完整实战流程。重点解析了S参数仿真的核心原理、DCFEED模块的正确配置、参数扫描的设置技巧,并探讨了集成SPICE模型进行精确仿真的方法,帮助射频工程师高效、准确地获取器件关键特性。

weixin_29237635的博客 529

C语言相关操作

根目录(\):linux文件系统的顶层目录,所以一切都在它之下,也从他开始用户目录(家目录):(~ or 工作目录 or HOME)总结:Windouws目录像是一片森林Linux目录像一个倒置的树Linux系统之下,一切皆文件注意:1.家目录以上的目录,普通用户没有操作权限,想要操作就要在命令前面加一个sodu2.HOME才是家目录,而home不是家目录,在home下的wym才是家目录。

Light_G_的博客 2207

Python+whisper/vosk实现语音识别

Whisper 是一个由 OpenAI 开发的人工智能语音识别模型,它能够将语音转换为文本。Whisper 模型特别之处在于它的设计目标是能够理解和转录多种语言的语音,包括但不限于英语。Whisper 模型在训练时使用了大量不同语言的语音数据,这使得它具有很好的跨语言能力。Vosk 是一个开源的语音识别库,它可以在离线环境下工作,不依赖于任何外部服务。Vosk 基于Kaldi语音识别框架,支持多种语言,包括中文。Vosk提供了多种预训练模型,可以根据需求选择适合的模型进行语音识别。

weixin_44458771的博客 5941

c语言从入门到实战——操作符详解

C语言操作符指的是程序中用来进行各种计算、逻辑和条件操作的符号或符号组合。//代码1:变量的定义int x;int y;}p1;//声明类型的同时定义变量p1//定义结构体变量p2//代码2:初始化。struct Stu //类型声明//名字int age;//年龄//初始化//指定顺序初始化//代码3int data;//结构体嵌套初始化//结构体嵌套初始化。

qq_74013365的博客 612

通过TMS320F28335学习DSP的开发流程——28335的基础知识(1)

1、TMS320F28335内核的主要特点 ①F28335 DSP集成了DSP和微控制器的长处,如DSP的主要特征、单周期乘法运算,F28335能够在一个周期内完成32x32位的乘法累加运算,或者两个16x16位乘法累加运算,而同样32位的普通单片机则需要4个周期以上才能完成 ②快速的中断响应 ③可在任何内存位置进行单周期读、修改、写操作 ④可采用C/C++编程软件,效率非常高 2、处理器的主要资源 ①32位浮点DSP,主频是150MHz,方便电机控制、电力设备控制及工业控制等。 ②片上存储器:FLASH–

Kayboy的博客 2万+

Android 9.0 SystemUI禁用长按recent键的分屏功能

​ 在9.0的系统产品开发中,系统对于多窗口模式默认会有分屏功能的,但是在某些产品中,需要禁用分屏模式,所以需要在导航栏中 禁用长按recent的分屏模式功能,接下来分析下相关分屏模式的实现 ​

安卓兼职framework和app工程师的博客 449

C语言的文件与操作

C语言文件概念以及相关操作函数

2301_80001281的博客 1127

UCIE Specification详解(三)

Protocol Layer(协议层)以及Die-to-Die Adapter

Crazzy_M的博客 1764

【C语言】操作符详解

【C语言】操作符详解

XJ2536877903的博客 1504

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【C语言】操作符详解(下)

文章摘要: 本文是C语言操作符讲解的续集,主要介绍单目操作符、逗号表达式及结构体相关操作,希望可以帮助到你。

LSRISME的博客 1404

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C语言——操作符详解

目录 操作符分类: 1、算术操作符 2、位操作符 3、赋值操作符 4、单目操作符 5、关系操作符 6、逻辑操作符 7、条件操作符 8、逗号操作符 9、下标引用、函数调用和结构成员 1、算术操作符 + - * / % % 是取模操作符,意思就是 求余数。 int ret = 10 % 3; //求10 % 3的余数,得出的余数是1 printf("%d\n", ret); 注意的是:% .........

weixin_57525369的博客 7553

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C语言操作符——详解

这么快与大家又见面了,今天给大家推出一期关于操作符相关的作品,希望能够带大家真正大了解操作符中的坑和小技巧😎😎😎 文章目录一、操作符的分类二、算术操作符三、移位操作符四、位操作符1、小试牛刀2、练习题13、练习题24、练习题3五、赋值操作符 一、操作符的分类 算术操作符 移位操作符 位操作符 赋值操作符 单目操作符 关系操作符 逻辑操作符 条件操作符 逗号表达式 下标引用、函数调用和结构成员 二、算术操作符 + - * / % 相信大家对+,-,*没有什么疑问,那么就针对/

buhuisuanfa的博客 3004

详解操作符【C语言】

操作符详解【C语言】

Man9o 3476
上一篇: 人机大战?——带你玩转三子棋(C语言)
下一篇: C语言操作符详解(下)
小白debug~
小白debug~ 新星创作者: C/C++技术领域 新星创作者: C/C++技术领域
博客等级 码龄4年 3510粉丝 128原创
评论 12
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白debug~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值