目录
1.操作符分类
算术操作符
移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号操作符
下标引用、函数调用和结构成员
2.算术操作符
+ - * / %
#include<stdio.h>
int main()
{
int num1 = 10 / 3;
double num2 = 10.0 / 3;
printf("%d\n", num1);//3
printf("%lf\n", num2);//3.333333
printf("%.1lf\n", num2);//3.3
return 0;
}
1.除了 %操作符之外,其他的的几个操作符可以作用于整数和浮点数
2.对于/操作符如果两个操作符都为整数,则执行整数除法,而只要有浮点数执行的就是浮点数除法
3.%操作符的两个操作数必须为整数,返回的是整数之后的余数
3.移位操作符
<<左移操作符
>>右移操作符
int main()
{
//原码:按照一个数的正负直接写出它的二进制表示形式
//反码:原码符号位不变,其他位按位取反
//补码:反码+1
//内存中存放的是补码
//正数的原码反码补码相同
//负数的补码要进行运算
int a = 10;
//00000000000000000000000000001010原码
//00000000000000000000000000001010反码
//00000000000000000000000000001010补码
int b = -10;
//10000000000000000000000000001010原码
//11111111111111111111111111110101反码
//11111111111111111111111111110110补码
return 0;
}
3.1左移操作符
移位规则:
左边抛弃,右边补0
int main()
{
int a = 10;
int num = a << 1;
printf("%d\n", a);//10
printf("%d\n", num);//20,左移一位有乘以2的效果,a值不变
return 0;
}
3.2右移操作符
移位规则:
1.逻辑移位
左边补0,右边丢弃
2.算术移位(大部分编译器采用)
左边用原码值的符号位填充,右边丢弃
4.位操作符
& //按位与(对应的二进制位有 0则为0;两个同时位1则为1)
| //按位或(对应的二进制位有 1则为1;两个同时位0则为0)
^ //按位异或(对应的二进制位相同则为0;不同则为1)
例题分析
#include <stdio.h>
int main()
{
int num1 = 1;
int num2 = 2;
num1 & num2;
num1 | num2;
num1 ^ num2;
return 0;
}
//num1 00000000000000000000000000000001补码
//num2 00000000000000000000000000000010补码
//num1&num2 00000000000000000000000000000000------等于0
//num1|num2 00000000000000000000000000000011------等于3
//num1^num2 00000000000000000000000000000011------等于3
通过位操作运算可以把变量二进制中的某位数值改变
int a=9;
a|=(1<<4);
printf("%d",a);
5.赋值操作符
连续赋值
int a=10;
int b=20;
int c=a=b+1;//从右到左赋值,等价于a=b+1;c=a
复合赋值符
+=
-=
*=
/=
%=
<<=
>>=
&=
|=
^=
int a=10;
a=a+10;//等价于a+=10;把先前的a的值进行算术运算再赋值给他本身
6单目操作符
6.1单目操作符成员
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(单位为字节)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 解引用操作符
() 强制类型转换
int main()
{
int flag = 0;//c语言中0表示假,非0表示真
if(flag)//如果为真则打印5201314
{
printf("5201314\n");
}
else
{
printf("54088\n");
}
//打印54088
printf("%d\n", !flag);//1
printf("%d\n", !2);//0
printf("%d\n", sizeof(flag));//4
printf("%d\n", sizeof(int ));//4
printf("%d\n", sizeof flag);//4 当括号里是变量名称可以省略括号
//函数调用时候要写(),但是sizeof后面括号可以省略说明sizeof不是函数
// printf("%d\n", sizeof int);//写法错误
int arr2[10] = { 0 };
printf("%d\n", sizeof(arr2));//40
printf("%d\n", sizeof arr2);//40
printf("%d\n", sizeof(int[10]));//40
//printf("%d\n", sizeof int[10]);//写法错误,int[10]表示类型
char ch = 'w';
char* pc = &ch;
char arr[10] = { 0 };
char* p1 = arr;
char* p2 = &arr[0];
char* p = "abcdef";
printf("%p\n", p);//数组首元素地址
printf("%c\n", *p);//a
return 0;
}
//后置++和--
#include <stdio.h>
int main()
{
int a = 10;
int x = a++;
//先对a先使用,再增加,这样x的值是10;之后a变成11;
int y = a--;
//先对a先使用,再自减,这样y的值是11;之后a变成10;
return 0;
}
//前置相反
//++ --带有副作用改变自身的值
6.2sizeof和数组
int main()
{
int a = 10;
short b = 5;
printf("%d\n", sizeof(b = a + 3));//2,sizeof内部的表达式是不计算的,但是最终结果取决于b的类型
printf("%d\n", b);//5
return 0;
}
#include <stdio.h>
void test1(int arr[])//本质上是一个指针,指针所占空间取决于是多少位操作系统
{
printf("%d\n", sizeof(arr));//32位平台下为4个字节大小,64位平台下为8个字节大小
}
void test2(char ch[])
{
printf("%d\n", sizeof(ch));//4或者8
}
int main()
{
int arr[10] = {0};
char ch[10] = {0};
printf("%d\n", sizeof(arr));//40数组所占空间大小,一个元素4个字节,10个元素占40个字节
printf("%d\n", sizeof(ch));//10
test1(arr);
test2(ch);
return 0;
}
7.关系操作符
>>=<<=!= 用于测试“不相等”== 用于测试相等
8.逻辑操作符
&& 逻辑与(相当于并且)有假则为假,两者为真才为真|| 逻辑或(相当于或者)有真则为真,两者为假才为假只关注真假,与位操作符区别
#include <stdio.h>
int main()
{
int i = 0,a=0,b=2,c =3,d=4;
i = a++ && ++b && d++;//a++先使用a值0,&&一旦为假后面无需计算,a自增为1
printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
return 0;
}//a = 1 b = 2 c = 3 d = 4
#include <stdio.h>
int main()
{
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++||++b||d++;//a++先使用a值0,a自增,表达式值为0为假,继续往后计算先自增b值为3,再使用,表达式结果为真,||一旦为真后面无需计算
printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
return 0;
}//a = 1 b = 3 c = 3 d = 4
9.条件操作符
exp1 ? exp2 : exp3exp1成立?成立表达式执行exp2,不成立执行exp3当求两个数中最大值与最小值用此语句简便
int main()
{
int a = 10;
int b = 20;
int max = (a < b ? b : a);
/*if (a < b)
{
max = b;
}
else
{
max = a;
}*/
printf("%d", max);//20
return 0;
}//最小值类似
10.逗号表达式
exp1 , exp2 , exp3,...expn从左向右依次执行,变了中间值,整个表达式的结果是最后一个表达式的结果。
#include<stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("%d\n", a);//12
printf("%d\n", b);//13
printf("%d\n", c);//13
return 0;
}
11.下标引用、函数调用和结构成员
1. [ ] 下标引用操作符操作数:一个数组名 + 一个索引值int arr[10];//创建数组arr[9] = 10;//等价于*(arr+9)[ ]的两个操作数是arr和9。
2. ( ) 函数调用操作符接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。int len=strlen("abcdef");操作数为strlen,"abcdef"
3. 访问一个结构的成员. 结构体.成员名-> 结构体指针->成员名
struct pig
{
char name[20];
int age;
char sex[5];
double change;
};
void print(struct pig* pa)
{
printf("%s %d %s %lf\n", (*pa).name, (*pa).age, (*pa).sex, (*pa).change);
printf("%s %d %s %lf\n", pa->name, pa->age, pa->sex, pa->change);
}
int main()
{
struct pig p = { "快乐猪",18,"女",6.66 };
printf("%s %d %s %lf\n", p.name, p.age, p.sex, p.change);
print(&p);
return 0;
}