栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言运算符详解

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言运算符详解

C语言运算符详解
  • 1.运算符:
  • 2.算子:
  • 3.算术运算符:
  • 4.赋值运算符:
  • 5.复合赋值运算符:
  • 6.单目运算符:
  • 7.关系运算符:
  • 8.位运算符
  • 9.逻辑运算符:
  • 10.条件运算符:
  • 11.逗号运算符:
  • 12.移位运算符:
    • (1)<<:左移操作符
    • (2)>> :右移操作符
  • 13.数组,指针常用运算符
    • (1)下标引用运算符:[]
    • (2)取地址运算符:&
    • (3)解引用运算符:*
  • 14.函数调用和结构成员运算符:
  • 15.sizeof运算符
  • 16.常用运算符的优先级总结

1.运算符:

是指进行运算的动作,也就是操作符,比如加法运算符“+”,减法运算符“-”。

2.算子:

算子(operand)是指参与运算的值,这个值可能是常数,也可能是变量,还可能是一个方法的返回值。

3.算术运算符:

分别是+ - * / %

注:

  • % 取余操作符只能作用于整型,除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
  • %操作符常用于取随机数之中:
random()%5//获得一个0-4的随机数
  • 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
4.赋值运算符:
int a = 12;//这里的=即为赋值运算符,把右边的值赋值给左边的值

嵌入式赋值:

int a = 6;
int b;
int c = 1+(b=a);

int result;
result = a = b = 3 + c;
result = 2;
result = (result = result * 2) * 6 * (result = 3 + result);

5.复合赋值运算符:

如+=,-=,*=,/=,%=,&= , ^= , |= , >>= , <<=(两个运算符之间不能有空格)。

6.单目运算符:

只有⼀个算子的运算符

  • +: 取正
  • -: 取负
  • ++ --: 自增和自减运算符:

++和- -是两个很特殊的运算符,它们是单目运算符,这个算子还必须是变量。它们的作用就是给这个变量+1或者-1,这两个运算符可以放在变量的前面,叫做前缀形式,也可以放在变量的后面,叫做后缀形式。a++代表把它拿出来之后再加1,而++a是指先加1,再把它拿出来进行运算。

  • !: 逻辑取反

  • ~: 按位取反,因为内存中存储的是二进制的补码,所以按位取反是对存在内存中的补码进行取反的。

  • &: 32位操作系统,地址占据4字节空间,&表示取出地址4字节空间中第一个字节的地址,即取出首地址。

  • *: 间接访问操作符(解引用操作符),用于获取指针所指向的变量的值:

int a = 10;
int *p = &a;
*p = 20;
printf("%dn",a);//20
  • sizeof: 获取变量,类型所占据内存的大小,单位为字节:
sizeof(int);
sizeof(i);
  • (类型): 强制类型转换
int a = (int)3.14;
7.关系运算符:

== 相等,!= 不相等,> 大于, >= 大于或等于,< 小于, <= 小于或等于,在所有的关系运算符中,用于判断是否相等的==和!=的优先级比其他的关系运算符要低。连续的关系运算是从左到右进行的

8.位运算符

与:&,按位与,对应的二进制位有0,则为0,全1才为1
或:|,按位或,对应的二进制位有1,则为1,全0才为0
异或:^,按位异或,相同为0,相异为1

注:

  • 它们的操作数必须是整数。
  • 它们都是用补码进行运算

一道变态的面试题,不能创建临时变量,来交换a和b的值:

9.逻辑运算符:


短路:
逻辑运算是自左向右进行的,如果左边的结果已经能够决定整个表达式的结果了,就不会做右边的计算。对于&&,左边是false就不做右边了,对于||,左边是true就不做右边了。

注: 不要跟按位与,按位或搞混淆了。

10.条件运算符:

其主要作用就是简化if-else语句

m 
11.逗号运算符: 

逗号运算符比其他所有运算符的优先级都要低,逗号表达式会从左向右依次计算,整个逗号表达式的结果是最后一个表达式的结果。

int d = (a + 2, b = a - 3, c = b + 4);
//b=0        c = 0+4
printf("%dn", d);//4

i = 3+4,5+6;//i = 3+4会先执行,执行完后会算5+6,但是5+6的结果没有用到,最终i的结果是7
i = (3+4,5+6);// (3+4,5+6)最终的结果是逗号后面的结果,3+4的结果没有用到,i=11
for(i=0,j=10;i 
a = get_val();
count_val(a);
while (a > 0)
{
    //业务处理
    a = get_val();
    count_val(a);
}
//如果使用逗号表达式,改写:
while (a = get_val(), count_val(a), a>0)
{
    //业务处理
}
12.移位运算符: (1)<<:左移操作符

移位规则: 左边舍弃,右边补零
由上图可以判断num左移1位后的结果应该是 20,下图是代码运行后的结果:

(2)>> :右移操作符

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


由上图所示:-1算术右移的结果仍是-1,逻辑右移的结果是1,下图是代码运行的结果:

常见编译器一般都是默认采用算术右移。

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

int num = 10;
printf("%dn",num>>-1);//error
13.数组,指针常用运算符 (1)下标引用运算符:[]

[]:它有数组名和索引两个操作数

int arr[10];//创建数组
arr[7] = 10;//实用下标引用操作符。

[]的操作数是arr和7。arr[7]–> *(arr+7) --> *(7+arr)–>7[arr],因此把[]的操作数互换位置也可以:

printf("%dn", arr[7]);
printf("%dn", 7[arr]);
(2)取地址运算符:&

f(“%d”,&i)里的& 获得变量的地址,它的操作数必须是变量,地址的类型是否与int相同取决于编译器,所以我们通常输出地址需要用下面的输出格式

int i;
int *p = &i;//指针p保存i的地址
printf("%p,&i);
int a[];
printf("%pn",a);//0xbff8dd44
printf("%pn",&a[0]);//0xbff8dd44
printf("%pn",&a[1]);//0xbff8dd48

a==&a[0]//它们都表示数组中第一个元素的地址
(3)解引用运算符:*

*是一个单目运算符,用来访问指针变量保存的地址所对应的变量,即访问指针变量所指向的变量,可以作右值,也可以作左值

int k = *p//访问指针变量p保存的地址所对应的变量,即访问指针p所指向的变量

*p = k+1;//将k+1的值赋值给指针变量p保存的地址所对应的变量,即赋值给指针变量p所指向的变量
void f(int *p);
void g(int k);

int main(void)
{
	int i =6;
	f(&i);
	//p=0x234353
	/
	g(i);//k=26
	
	return 0;
}
void f(int *p)
{
	printf("p=%pn",p);
	printf("*p=%dn",*p);
	*p =26;
	
}
void g(int k)
{
	printf("k=%dn",k);
}

14.函数调用和结构成员运算符:

函数调用: (),它有函数名和参数等若干个操作数

结构成员: ->
. : 结构体变量.成员名
->: 结构体指针->成员名

int main()
{
	typedef struct Student
	[
	int age;
	char name[20];
	}Stu;

	Stu stu;

	Stu *ps = stu;

	stu.age = 18;
	ps->age = 20;
}
15.sizeof运算符

sizeof是一个运算符,是用来计算变量或者类型所占内存空间大小的,返回的单位是字节,当计算数组变量的大小时,会把数组变量的所有元素都算进去:

#include 

int main()
{
	char arr1[] = "abc";

	printf("%dn", sizeof(arr1));

	return 0;
}

显然数组arr1中存储的是{‘a’,‘b’,‘c’,‘’},而sizeof计算数组大小会把所有元素都算进去,其中有4个字符类型的元素,故返回4,单位是字节。

注: sizeof的返回值类型为无符号整型

对于一个变量,想要用sizeof求出该变量所占内存大小,sizeof的参数既可以是变量名,也可以是类型:

int a = 10;
printf("%dn",sizeof(a));//4
printf("%dn",sizeof(int));//4

对于数组变量也是一样:

int arr[10] = {1,2,3,4,5,};
printf("%dn",sizeof(arr));//40
printf("%dn",sizeof(int [10]));//40

对于数组arr,它的类型就是int [10]

当sizeof后面接的是变量名时,括号可以省略:

int arr[] = {1,2};
int a = 10;
printf("%dn",sizeof a);//4
printf("%dn",sizeof arr);//40

sizeof内部的表达式是不会进行真实计算的:

int main()
{
	short s = 20;
	int a = 5;
	printf("%dn",sizeof(s = a + 20));//2
	printf("%dn",s);//20
}

表达式的计算是在运行阶段进行的,而在编译阶段就把sizeof的结果算出为2了,sizeof已经算出结果了,故在运行阶段不会算sizeof内部的表达式。

16.常用运算符的优先级总结

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/982678.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号