C语言——操作符和表达式

操作符


算术操作符

+

-
*
/
% 取余(操作数必须为整数)

算数转换:

char -> int -> float -> double

移位操作符

数据存储:二进制补码

<< 左移(左边抛弃,右边补零)
>>

右移

(1.逻辑移位:左边补零,右边抛弃

  2.算数移位:左边补符号位,右边抛弃)

 循环移位:

超过32位,对32位取模

>>33   ->   >>1

不能移动负数位,此行为标准未定义!(编译器中)

负数位绝对值加移动实际值=32

>>-1   ->  >>31

>>-5   ->   >>27

void shift(int ls,int rs)
{
	printf("左移——%d\n", ls << 1);
	printf("左移未赋值——%d\n", ls);
	ls = ls << 1;
	printf("左移后赋值——%d\n", ls);

	printf("右移后——%d\n", rs >> 1);
	printf("右移未赋值——%d\n", rs);
	rs = rs >> 1;
	printf("右移后赋值——%d\n", rs);
}

位操作符

操作数必须为整数

& 按位与(同为1则为1)
| 按位或(同为0则为0)
^ 按位异或(相同为0,不同为1)
void Anoperator(int a, int b) // a--1 b--2
{
	printf("按位与——%d\n", a & b);  //0
	printf("按位或——%d\n", a | b);  //3
	printf("按位异或——%d\n", a ^ b); //3
}

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

//不能创建临时变量(第三个变量),实现两个数的交换。
//改变实参可用传址调用,此函数为传值
void swap(int a, int b)         
{
	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);
}

 计算数字二进制中一的个数

int count_One(int n)   //计算数字二进制中一的个数
    int count;
    while(n)
    {
        n&=(n-1);
        count++;
    }
    return count;
}

赋值操作符

= 赋值

复合赋值符

+= 加等
-= 减等
*= 乘等
/= 除等
%= 取余等
>>= 右移等
<<= 左移等
&= 按位与等
|= 按位或等
^= 按位异或等
int x=2;
//等价
x+=10;
x=x+10;

单目操作符

逻辑反
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(字节为单位,返回无符号整型)
~ 对一个数的二进制按位取反
--

前置,后置--

++ 前置,后置++
* 简介访问操作符(引用操作符)
(类型) 强制类型转换

++,-- 

前置 操作数先自增(减),后使用
后置 操作数先使用,后自增(减)

~ 按位取反

-10,按位取反 值为-11

负数在计算机中以补码存储。

-10的原码: 10000000 00000000 00000000 00001010

取反后     : 11111111 11111111 11111111 11110101       符号位不变、其位取反

计算机认为为补码,打印时将其返还为原码(负数的补码:原码->反码+1=补码)

打印值     :  10000000  00000000 00000000 00001011 

关系操作符

> 大于
>= 大于等于
< 小于
<= 小于等于
!= 不等
== 相等

注:

        ==为相等测试

        =为赋值 

逻辑操作符

&& 逻辑与
|| 逻辑或

 短路表达:

        &&:左边为false时,右边不执行

        ||:左边为true时,右边不执行

#include 
int main()
{
    int i = 0,a=0,b=2,c =3,d=4;
    i = a++ && ++b && d++;
    //i = a++||++b||d++;
    printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
    return 0;
}

        i = a++ && ++b && d++;C语言——操作符和表达式_第1张图片

    i = a++||++b||d++;

C语言——操作符和表达式_第2张图片

条件操作符

exp1? exp2:exp3 exp1为真,执行exp2,否则exp3

int max(int a, int b)  // a--1  b--2
{
	return a > b ? a : b;
}

C语言——操作符和表达式_第3张图片

逗号表达式

exp1, exp2, exp3, …expN

逗号隔开多个表达式,从左到右依次执行,整个表达式结果为最后一个表达式的值。

 进行多个操作符运算时,活用()来确定运算顺序,避免在不同编译器中结果不同!

下标引用,函数调用和结构成员

下标引用[]

数组名+下标

(数组篇:数组篇)

函数调用()

函数名+参数

(函数篇:函数篇)

结构成员

结构体.成员名

结构体指针->成员名

表达式求值

隐式转换

C的整型算术运算总是至少以缺省整型类型的精度来进行的。

为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型 提升。

整型提升的意义:

表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度 一般就是int的字节长度,同时也是CPU的通用寄存器的长度。

因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长 度。 通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。

所以,表达式中各种长度可能小于int长度的整型值,都必须先转 换为int或unsigned int,然后才能送入CPU去执行运算。

//负数的整形提升,符号位不变,高位补一;

char c1 = -1;

变量c1的二进制位(补码)中只有8个比特位: 1 1111111

提升之后的结果是: 1 1111111  11111111  11111111  11111111

//正数的整形提升

char c2 = 1;

变量c2的二进制位(补码)中只有8个比特位: 00000001

提升之后的结果是: 0 0000000  00000000  00000000  00000001

//无符号整形提升,高位补0

void intImprove()
{
	char a = 182;//(Oxb6200)  超出char表数范围  整型提升后为负数;
	short b = 46592;
	int c = 10000000;
	if (a == 100)
		printf("a\n");
	if (b == 46592)
		printf("b\n");
	if (c == 10000000)
		printf("c\n");
}

void intImprove2()
{
	char c = 10;
	printf("%u\n", sizeof(c));
	printf("%u\n", sizeof(+c));
	printf("%u\n", sizeof(!c));
	printf("%u\n", sizeof(c));
}

1

4

1

1

c 只要参加表达式运算,就整型提升。

算数转换

操作符所操作的操作数类型不同,低类型转高类型;

转换要合理

        高类型转低类型时,会发生精度丢失

float f=1.23;
int i=f;   //i=1;

最难不过坚持!

你可能感兴趣的:(C语言基础,笔记,c语言,开发语言,后端,visualstudio,1024程序员节)