C语言处理数据的工具------操作符

●🧑个人主页:你帅你先说.

●📃如果文章有帮助,欢迎点赞👍关注💡收藏💖

📖既选择了远方,便只顾风雨兼程。

🤟欢迎大家有问题随时私信我!

●🧐版权:本文由[你帅你先说.]原创,CSDN首发,侵权必究。

目录

1.算术操作符

2.移位操作符

3.位操作符

3.1 &(按位与)

3.2 |(按位或)

3.3 ^(按位异或)

4.赋值操作符

5.复合赋值符

6.单目操作符

6.1!(逻辑反操作) 

6.2 sizeof

6.3 ~(按位取反)

6.4 &取地址

6.5 *解引用操作符

6.6 ++、-- 操作符

7.关系操作符

8.逻辑操作符

9.条件操作符

10.逗号表达式

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

11.1[ ] 下标引用操作符

11.2( ) 函数调用操作符

12.结构成员

13.表达式求值

13.1隐式类型转换

13.2算术转换

13.3操作符的属性


1.算术操作符

+                -                *                /                 %
1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除
法。
3. % 操作符的两个操作数必须为 整数 。返回的是整除之后的 余数
针对于/,要特别提一点
int ret = 9/2;
double ret = 9/2;

大家可能会认为9/2算出来是4是因为int整型,实际上不是,当你以double类型打印时结果是4.0,所以说这是‘/’自身的特点,并不是int类型造成的。

那要怎么算出4.5呢?

上面第二点提到了,只要有浮点数就执行浮点数除法,所以可以改成9.0/2或者9/2.0就能算出4.5了。

2.移位操作符

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

移位操作符,移动的是二进制

对于整数的二进制有3中表示形式:原码、反码、补码

正整数 - 原码、反码、补码相同

负整数

原码 - 直接按照数字的正负写出的二进制序列

反码 - 原码的符号位不变,其他位按位取反得到的

补码 - 反码+1

二进制的第一位为符号位,负数为1,正数为0

整数在内存中存储的是二进制的补码

那移位操作符是怎么对二进制进行移位的呢?

int a = 5;
int b = a << 1;

以32bit系统为例

算出来结果是10

 注意:此时a的值还是5,b的值是10,移位操作符并不对自身进行改变。

 刚刚上面是以左移操作符为例,实际上右移操作符遵循的规则和左移略有不同。

首先右移运算分两种:
1. 逻辑移位
  左边用0填充,右边丢弃  
2. 算术移位
左边用原符号位填充,右边丢弃

大部分编译器采用的是算术移位。

int a = -1;
int b = a >> 1;

图解

因为-1的原符号位是1,所以补1。

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

3.位操作符

&  按位与

|   按位或

^   按位异或
注:他们的操作数必须是整数。

3.1 &(按位与)

int a=3 b=5;
c=a&b;

a的二进制 00000000000000000000000000000011

b的二进制 00000000000000000000000000000101

结果为       00000000000000000000000000000001

即只要有0即为0,其余不变(1向左移位按位与这个数可以找二进制里有几个1)

3.2 |(按位或)

a的二进制 00000000000000000000000000000011

b的二进制 00000000000000000000000000000101

结果为       00000000000000000000000000000111

即只要有1即为1,其余不变

3.3 ^(按位异或)

a的二进制 00000000000000000000000000000011

b的二进制 00000000000000000000000000000101

结果为       00000000000000000000000000000110

相同为0,相异为1

异或是支持交换律的!
在这里有一道非常经典的变态面试题

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

法一:
int a = 3,b = 5;
a = a + b;
b = a - b;
a = a - b; 

但这种方法有个局限,因为整型变量有上限,如果数据过大可能会导致溢出。

法二:

int a = 3;
int b = 5;

a = a^b;
b = a^b;
a = a^b;

图解

这个解法只是就题解题,平时我们在写代码时避免写出这种可读性差的代码。 

4.赋值操作符

赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值。
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//连续赋值

这个表达式是从右向左依次赋值的。但平时我们不建议这种写法。

最好写成以下这样

x = y + 1;
a = x;

5.复合赋值符

+=   例如a+=5就相当于a = a +5,下面的以此类推。

-=

*=

/=

%=

>>=

<<=

&=

|=

^=

6.单目操作符

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

6.1!(逻辑反操作) 

C语言是如何表示真假的?

0位假,非0为真,C语言规定真所对应的值为1。所以 0为假 !0 为真。

6.2sizeof

这边强调一点大家容易误解的,sizeof是操作符不是函数!

int a = 5;
short s = 10;
printf("%d\n", sizeof(s = a + 2));//结果为2
printf("%d\n", s);                //结果为10

 sizeof()最终算的类型是表达式最终的类型,当把int类型赋给short int 类型时会发生截断。

6.3~(按位取反)

00000000000000000000000000001111

11111111111111111111111111111110000  

即0和1互换


6.4&取地址

int a = 10;

int * p = &a;

取地址时取出的是4个字节中的第一个字节,且是低地址。

 6.5*解引用操作符

int a = 10;

int * p = &a;

*p = 20; //解引用操作符

*p表示通过p找到a的地址从而改变a的内容。

int b = *p;//右值
*p = 20;//左值

当*p在等号左右两边所表达的意义不同。

左值代表空间,右值代表空间的内容。

6.6 ++、-- 操作符

这里以++为例

前置++

int a = 10;
int b = a++;
//最终结果为 a为11 b为10,后置++,先赋值,后++
后置++
int a = 10;
int b = ++a;
//最终结果为 a为11 b为11,前置++,先++,后赋值

7.关系操作符

>
>=
<
<=
!=        用于测试 不相等
==       用于测试 相等
这边只提一点,在编程的过程中切记==和=的区别,==是判断两个数是否相等,=是赋值操作符。

8.逻辑操作符

&&        逻辑与
 ||         逻辑或
逻辑与 &&
一假既假
逻辑或||
一真既真
这里的与和或和高中数学逻辑用语里的且和或是一样的。
#include <stdio.h>
int main()
{
    int i = 0,a=0,b=2,c =3,d=4;
    i = a++ && ++b && d++;
    printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
    return 0;
}

此题输出结果为1234。首先,a++,是先使用后++,a是0,0是假,所以不管后面的表达式是什么,最终结果都是假,后面的表达式没有参与运算,故结果为1234。

9.条件操作符

exp1 ? exp2 : exp3
b = a > 5 ? 3 : -3;

这段代码等价于下面这段代码

if (a > 5)
        b = 3;
else
        b = -3;

10.逗号表达式

exp1 , exp2 , exp3.....expn

从左向右依次计算,整个表达式的结果是最后一个表达式的结果。

int a=3,b=5,c=6;
int d=(a=a-2,b=a+c,c=a-b);//逗号表达式的结果即为c=a-b的结果
printf("%d",d);//输出结果为-6

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

11.1[ ] 下标引用操作符

操作数:一个数组名 + 一个索引值
int arr[10];//创建数组
arr[9] = 10;//实用下标引用操作符。
//[ ]的两个操作数是arr和9。

所以arr[10]也可以写成10[arr],因为arr和10就是两个操作数,可以交换顺序。只是平时我们习惯写arr[10]。

11.2( ) 函数调用操作符

#include <stdio.h>
 void test1()
 {
     printf("hehe\n");
 }
 void test2(const char *str)
 {
     printf("%s\n", str);
 }
 int main()
 {
     test1();              //使用()作为函数调用操作符。
     test2("hello world.");//使用()作为函数调用操作符。
     return 0;
 }

12.结构成员

. 结构体.成员名

-> 结构体指针->成员名
#include <string.h>

struct Book
{
	char name[20];
	float price;
	char id[10];
};


void print1(struct Book b)
{
	printf("书名: %s\n", b.name);
	printf("价格: %f\n", b.price);
	printf("书号: %s\n", b.id);

	
}

void print2(struct Book* pb)
{
	

	printf("书名: %s\n", pb->name);
	printf("价格: %f\n", pb->price);
	printf("书号: %s\n", pb->id);
}

int main()
{
	struct Book b = {"C语言程序设计", 55.5f, "C20190201"};
	print2(&b);
	return 0;
}

在这里强调一点,如果要对结构体里的内容进行改变,不可直接改,要用strcpy函数进行更改,例如strcpy(b.name, "数据结构"),因为b.name中name是数组名,是首元素的地址,如果直接对b.name进行更改相当于是对地址进行更改,而你要改的是内容,这种做法肯定是错的。

13.表达式求值

表达式求值的顺序一部分是由操作符的优先级结合性决定。

同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型

13.1隐式类型转换

C 的整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符短整型操作数在使用之前被转换为普通整型,这种转换称为 整型 提升

看完这段话,你一定是这样的 

举个栗子

int main()
{	char a = 3;//a是1byte - 8bit
    //发生整型提升的过程
	//00000000000000000000000000000011
	//00000011 - a 发生截断
	char b = 127;//b是1byte - 8bit
	//00000000000000000000000001111111
	//01111111 - b	
	//a和b都是char类型,自身大小的都是1byte,所以这里计算的时候要进行整型提升
	//整形提升是按照变量的数据类型的符号位来提升的,正数补0,负数补1,无符号数补0
    //例如a是00000011最高位为0,所以前面补0若a是-1则11111111最高位是1,前面补1
	//00000000000000000000000000000011 a
	//00000000000000000000000001111111 b
	//00000000000000000000000010000010 a+b
	//
	char c = a + b;
	//10000010 - c	发生截断
    printf("%d\n",c);
    //11111111111111111111111110000010 最高位为1,前面补1,内存中存的是补码
	//11111111111111111111111110000001 反码  补码-1就是反码
	//10000000000000000000000001111110 原码  反码按位取反就是原码
	//-126
	

	return 0;
}

整型提升的具体例子

int main()
{
     char a = 0xb6;
     short b = 0xb600;
     int c = 0xb6000000;
     if(a==0xb6)
     printf("a");
     if(b==0xb600)
     printf("b");
     if(c==0xb6000000)
     printf("c");
     return 0; 
}

打印结果为c,因为c是int不用整型提升,而char和short都需要整型提升。

int main()
{
     char c = 1;
     printf("%u\n", sizeof(c));//1byte
     printf("%u\n", sizeof(+c));//4byte
     printf("%u\n", sizeof(-c));//4byte
     return 0;
}

第一个因为c是char类型所以是1个字节,而第二第三个因为+-号所以c参与了运算,要进行整型提升,所以是4个字节。

13.2算术转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换
long double
double
float
unsigned long int
long int
unsigned int
int

转换优先级自下而上,例如

float a = 3.7
double b = 3.14
//则a*b结果的类型是double

13.3操作符的属性

复杂表达式的求值有三个影响的因素。
1. 操作符的优先级
2. 操作符的结合性
3. 是否控制求值顺序
优先级和结合性

 那什么是结合性呢?

举个栗子

比如a+b+c到底是先a+b 再加c还是先b+c再加a呢?表中也写了方向是从左向右,所以是先a+b再加c。 

优先级的作用对象是相邻操作符

a*b+c*d+e*f

这个式子的计算路径有两种

一是:

a * b
c * d
a * b + c * d
e * f
a * b + c * d + e * f
二是:
a * b
c * d
e * f
a * b + c * d
a * b + c * d + e * f

第二种计算路径说明了优先级作用的对象是相邻操作符。

这段代码实际上是问题代码,因为计算路径不唯一,平时写程序时一定要确保计算路径的唯一性。

看完这些,此刻的你

 

这样的文章你还不赶紧 点赞收藏+关注作者 

  • 26
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
### 回答1: pcre-devel-8.45-5是一个软件包版本号,常用于Linux操作系统中。PCRE是一个用于处理正则表达式C语言库,pcre-devel是PCRE开发包的一部分,提供了开发PCRE的工具和头文件。在Linux系统中,如果需要编译包含正则表达式的代码,就需要安装pcre-devel。版本号中的8.45代表PCRE库的主版本号和次版本号,5表示修复问题的次数。 安装pcre-devel可以让开发者使用PCRE的函数和数据结构来编写程序,以识别、匹配、解析和转换字符串。正则表达式是一种强大的字符串匹配工具,用于从文件或输入流中提取有用信息,或者过滤掉不需要的信息。因此,PCRE具有广泛的应用场景,例如验证用户输入、搜索和替换文本、提取日志数据等等。 总之,pcre-devel-8.45-5是一个用于开发PCRE程序的开发包版本号,如果要使用PCRE库,需要安装这个开发包。 ### 回答2: pcre-devel-8.45-5指的是一个软件包,它是PCRE(Perl Compatible Regular Expressions)的开发包,其中包含了开发和编译需要的头文件、静态库和动态库等文件。 在Linux系统中,PCRE是一个广泛使用的正则表达式库,它能够解析并匹配正则表达式,是大多数编程语言中常用的正则表达式库之一。pcre-devel-8.45-5作为PCRE的开发包,为开发者提供了PCRE库的开发接口和编译工具,包含了需要的开发文件和库文件。 pcre-devel-8.45-5可以用于在Linux系统下进行C/C++程序的编写和开发,使用PCRE库提供的正则表达式匹配功能,方便开发者进行字符串的解析和处理。而PCRE库的使用方法相对简单,只需要包含相应的头文件,并调用相应的函数即可完成正则表达式匹配功能。 总之,pcre-devel-8.45-5是一个Linux系统下的软件包,提供了PCRE正则表达式库的开发接口和编译工具,帮助开发人员进行字符串解析和处理。 ### 回答3: pcre-devel-8.45-5是一款基于Perl的正则表达式库的开发版本。正则表达式是一种简单却强大的文本匹配工具。使用正则表达式可以在一段文本中进行高效的搜索和处理,这使得正则表达式在很多领域得到了广泛应用,如文本编辑器、搜索引擎、数据处理等。 pcre-devel-8.45-5提供了正则表达式库的开发版本,允许开发者在不同的编程语言中使用正则表达式。该库已经被广泛应用于C、C++、Java、Python等编程语言中,为开发者提供了对文本进行高效处理的能力。 在pcre-devel-8.45-5版本中,改进了正则表达式的效率和性能,例如支持UTF-8编码、优化内存使用等。此外,该版本还增加了一些新特性,如支持新的正则表达式语法和操作符、增强了回溯控制等。 对于需要使用正则表达式进行文本处理的开发者而言,pcre-devel-8.45-5是一款非常实用的库。它提供了丰富的正则表达式功能,能够解决文本处理中的各种问题。此外,该库的稳定性和可靠性也得到了广泛认可,使得开发者可以安心地使用它来进行文本处理

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

你帅你先说.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值