完全自学C(干货) —— 操作符(一)

目录

一,基本操作符

二,移位操作符(二进制位)

三,位操作符(二进制位)

四,赋值操作符

五,单目操作符

六,关系操作符

七,逻辑操作符

八,条件操作符

九,逗号表达式

十,下标引用操作符

十一,函数调用操作符

十二,结构成员


一,基本操作符

加 、减 、乘 、除 、求余 %

注:

  • 除了 % 操作符之外,其他的操作符都可以作用于整数和浮点数;
  • 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除 法。
  • % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
int main()
{
	int a = 1;
	int b = 2;
	a + b; 
	a - b;
	a * b;
	a / b; //结果为0,两整数相除结果仍为整数,只要其中有浮点数即可得出小数
	a % b; //左右边操作数需均为整数
	return 0; 
}

二,移位操作符(二进制位)

右移 >> ,左移 <<

1,>>,右移操作符(除2效果),右移有两种情况:

  • 算数右移,右边丢弃,左边补原符号位(可能是0,也可能是1);
  • 逻辑右移,右边丢弃,左边补0;
int main()
{
	int a = 3;
	printf("%d\n", a >> 1);
	//0000 0000 0000 0000 0000 0000 0000 0011 - 3的内存二进制形式(正整数原反补相同)
	//0000 0000 0000 0000 0000 0000 0000 0001 - 向右移一位,最左边补零
	//结果为:1
	return 0;
}

2,<<,左移操作符(乘2效果)

  • 左边丢弃,右边补0;
//正整数
int main()
{
	int a = 3;
	printf("%d\n", a << 1);
	//0000 0000 0000 0000 0000 0000 0000 0011 - 3的内存二进制形式(正整数原反补相同)
	//0000 0000 0000 0000 0000 0000 0000 0110 - 向左移一位,最右边补零
	return 0;
}
//结果为:6


//负整数
int main()
{
	int a = -3;
	printf("%d\n", a << 1);
	//1000 0000 0000 0000 0000 0000 0000 0011 - 原码
	//1111 1111 1111 1111 1111 1111 1111 1100 - 反码(符号位不变,其余取反)
	//1111 1111 1111 1111 1111 1111 1111 1101 - 补码(反码+1),即内存中的二进制形式  
	//1111 1111 1111 1111 1111 1111 1111 1010 - 向左移一位,最右边补零
	//1111 1111 1111 1111 1111 1111 1111 1001 - -1得到补码 
	//1000 0000 0000 0000 0000 0000 0000 0110 - 符号位不变,其余取反,得到原码
	return 0;
}
//结果为:-6

注:

  • 不要移负位数;
  • 整数的二进制表示由原码、反码、补码;(-1的补码全为1);

三,位操作符(二进制位)

按位与 &,按位或 |,按位异或^

  • & 按位与,有0即为0,都为1才为1;
  • | 按位或,有1即为1,都为0才为0;
  • ^ 按位异或,相同为0,相异为1;

注:操作数必须为整数;

int main()
{
	int a = 0; //0000 0000 0000 0000 0000 0000 0000 0000
	int b = 1; //1000 0000 0000 0000 0000 0000 0000 0001
	printf("%d %d %d\n", a & a, b & b, a & b); //结果:0 1 0
	printf("%d %d %d\n", a | a, b | b, a | b); //结果:0 1 1
	printf("%d %d %d\n", a ^ a, b ^ b, a ^ b); //结果:0 0 1
}

例:点击链接

四,赋值操作符

赋值操作符 =

复合赋值操作符 +=-=*=/=%=, &=|=^=, >>=<<=

注:赋值,即是修改调整变量的值;

int main()
{
	int a = 0;
	int b = 0;
	a = b = 1; //可连续赋值(不推荐)
	
	a += 1; //等同于 a = a + 1;
	a -= 1; //等同于 a = a - 1;
	a *= 1; //等同于 a = a * 1;
	a /= 1; //等同于 a = a / 1;
	a %= 1; //等同于 a = a % 1;

	a &= 1; //等同于 a = a & 1;
	a |= 1; //等同于 a = a | 1;
	a ^= 1; //等同于 a = a ^ 1;

	a >>= 1; //等同于 a = a >> 1;
	a <<= 1; //等同于 a = a << 1;

	return 0;
}

五,单目操作符

  • 逻辑反 !
  • 负值 - 、正值 + 
  • 类型长度 sizeof
  • 按位取反 ~
  • 前置 ++a 、后置 a++ 
  • 强制类型转换 (类型)
  • 取地址 & 、解引用 *(NULL空指针不可解引用)

注:

  • 单目操作符,即只有一个操作数;
  • 双目操作符,即有两个操作数;
  • 三目操作符,即有三个操作数;
int main()
{
	int a = 0;
	int arr[5] = { 0 };

    //结果:20(5*4),相对于sizeof(int[5]),只统计类型所在空间字节大小
	printf("%d %d ", sizeof(arr), sizeof(int[5]));

    //结果:20,4
    printf("%d %d ", sizeof arr, sizeof arr[5]);

    //结果:4,因为sizeof括号内表达式不参与计算,只要识别a的类型即可
    //sizeof在编译时已计算,a += 1在运行时才计算的
	printf("%d ", sizeof(a += 1)); //a += 1并没有参与计算
	printf("%d ", a); //结果:0
    return 0;
}
//注:sizeof(变量)、sizeof(类型),变量时可省略括号;
//也因为sizeof(变量),括号可省略,证明sizeof是操作符不是函数;
//sizeof arr 和 &arr ,此两数组名表示整个数组;
int main()
{
	int a = 0;
	int b = ~a; //按位取反
	//0000 0000 0000 0000 0000 0000 0000 0000 - a内存二进制形式
	//1111 1111 1111 1111 1111 1111 1111 1111 - b内存二进制形式(补码,需还原为原码)
	//1111 1111 1111 1111 1111 1111 1111 1110 - 反码(补码-1)
	//1000 0000 0000 0000 0000 0000 0000 0001 - 原码(符号位不变,其余位取反)
	printf("%d ", b); //结果:-1,
    return 0;
}
//注:-1的内存补码形式全为1;
int main()
{
	int a = 10;
	int b = 10;
	int a1 = a++; //后置++,是先使用,在本身+1
	int b1 = ++b; //后置++,是先在本身+1,使用
	printf("a=%d a1=%d\n", a, a1); //结果:a=11, a1=10;
	printf("b=%d b1=%d\n", b, b1); //结果:b=11, b1=11;
    return 0;
}
//注:int b = (++a)+(++a)+(++a),此代码没有意义,在window和Linux结果是不一样的;
int main()
{
	int a = (int)3.14;
	printf("%a ", a); //结果:3;
	return 0;
}
int main()
{
	int a = 1;
	int* p = &a; //将变量a在内存中地址赋予给p(int*位指针类型)
	int b = *p; //对指针变量p的解引用可找到变量a
	printf("p=%p ", p); //结果:006FFD94 (此位十六进制格式,一个数表示4个位如f(1111))
	printf("b=%d ", b); //结果:1;
	return 0;
}

六,关系操作符

><>=<=!===

注:==、=,不要写错,一个是关系操作符,一个是赋值操作符;

int main()
{
	int a = 1;
	if (1 == a) //注意书写形式
		printf("判断a是否等于1");
	return 0;
}

七,逻辑操作符

&&||

注:

  • && 逻辑且,左右操作数均为真时,才为真;如第一个操作符为假,第二个操作数将不在参与计算;
  • || 逻辑或,左右操作数只要有一个为真时,即为真;如第一个操作符为真,第二个操作数将不在参与计算;
  • !逻辑非;
  • 注意与按位与&、取地址&,及按位或|的区别
int main()
{
	int a = 0;
	int b = 0;
	if (!(a && ++b))
		printf("a=%d,b=%d\n",a,b); // a=0,b=0 因为++b并未参与计算
	if (++a || ++b)
		printf("a=%d,b=%d\n", a, b); // a=1,b=0 因为++b并未参与计算
	return 0;
}

八,条件操作符

exp1? exp2: exp3

注:

  • 条件操作符,也是三目操作符;
  • exp1表达式为真执行exp2,假exp3;
  • exp2,exp3只会执行其中一个;
int main()
{
	int a = 0;
	int b = 0;
	a = (0 == a) ? ++a : ++b;
	printf("a=%d,b=%d\n", a, b); //a=1,b=0 因为++b并未参与计算
	return 0;
}

九,逗号表达式

(exp1,exp2,...,expN)

注:

  • 逗号表达式,就是用逗号隔开的多个表达式。
  • 逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
int main()
{
	int a = 0;
	int b = 0;
	printf("%d", (a++, b++, a + b)); //结果:2
	return 0;
}
a = get();
count(a);

while (a > 0)
{
    //... 业务处理
    a = get();
    count(a);
}

//如果使用逗号表达式,可改写:
while (a = get(), count(a), a > 0)
{
//... 业务处理
}

十,下标引用操作符

[ ]

注:

  • 是针对数组的,即获取数组指定下标的元素值(下标从0开始);
  • 操作数:一个数组名 + 一个索引值,如arr[5],操作数为arr和5;
int main()
{
	int arr[6] = { 1,2,3,4,5,6 };
	printf("%d", arr[5]); //结果:6
	return 0;
}

十一,函数调用操作符

()

注:

  • 是函数的,即调用指定的函数;
  • 操作数可以一个或多个;第一个操作数是函数名,剩余的操作数就是传递给函数参数;
#include <stdio.h>

void print1()
{
	printf("hehe\n");
}

void print2(char* str)
{
	printf("%s\n", str);
}

int add(int x, int y)
{
	return x + y;
}

int main()
{
	print1(); //只有一个操作数print1
	print2("C"); //有两个操作数print1和"C"
	printf("%d\n", add(2, 3)); //有三个操作数add、2和3
	return 0;
}

十二,结构成员

.  、->

. 注:

  • 均是访问结构体成员的,结构体.成员名 、 结构体指针->成员名;
int main()
{
	struct stu s = { "zhangsan",20,90.5 }; //初始化结构体变量s
	struct stu* p = &s; //取地址
	printf("%s\n", s.name); //结果:zhangsan
	printf("%s\n", p->name); //结果:zhangsan
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值