1)除了%操作符之外,其他的几个操作符可以用于整数和浮点数。
2)对于/操作符,如果两个操作数都是整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
3)%操作符的两个操作符必须为整数。返回的是整数之后的余数。
#include<stdio.h>
int main()
{
double a = 5%2;//商2余1
printf("a=%lf\n", a);
return 0;
}
1. >>是右移操作符,移动的是二进制位
移动规则:如果是算术移位 ,右边丢弃,左边补原符号位;如果是逻辑移位 ,右边丢弃,左边补0
#include<stdio.h>
int main()
{
int a = 16;
//a >> 1; 00000000000000000000000000010000
int b = a >> 2;
printf("%d\n", b);
return 0;
}
#include<stdio.h>
int main()
{
int a = -1;
//
//整数的二进制表示有;原码、补码、反码
//存储到内存的是补码
//10000000000000000000000000000001 -原码
//11111111111111111111111111111110 -反码 符号位(首位)不变
//11111111111111111111111111111111 -补码(反码+1)
int b = a >> 1;
printf("%d\n", b);
return 0;
}
2. <<是左移操作符
移动规则:左边丢弃,右边补0
对于移位操作符,不要移动负数位,这个是标准未定义的
#include<stdio.h>
int main()
{
int a = 5;
int b = a << 1;
//00000000000000000000000000000101;8—>10
printf("%d\n", b);
return 0;
}
3. 按二进制位与&(两个二进制序列同一位上都是1则为1,其余为0)
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = a & b;
//00000000000000000000000000000011 3
//00000000000000000000000000000101 5
//00000000000000000000000000000001 1
printf("%d", c);
return 0;
}
4. 按位或 |(两个二进制序列同一位上有1则为1,其余为0)
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = a | b;
//000000000000000000000000000000011
//000000000000000000000000000000101
//000000000000000000000000000000111
printf("%d", c);
return 0;
}
5. 按位异或^ ( 对应二进制位,如果两数二进制位相同为0,相异则为1)
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = a^b;
//000000000000000000000000000000011
//000000000000000000000000000000101
//000000000000000000000000000000110
}
异或练习题:不使用第三个变量,将两个变量进行调换
#include<stdio.h>
int main()
{
int tmp = 0;
a = tmp;
a = b;
b = tmp;
int a = 3;
int b = 2;
printf("%d", a);
printf("%d\n", b);
a = a + b;
b = a - b;
a = a - b;
printf("%d", a);
printf("%d", b);
return 0;
}
上面加减法可能会溢出,所以我们试试异或的方法
#include<stdio.h>
int main()
{
int a = 3;
int b = 2;
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
6. 逻辑运算符 逻辑与
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = a && b;
printf("%d\n", c);
return 0;
}
逻辑与练习题
#include<stdio.h>
int main()
{
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf(" a=%d\n b=%d\n c=%d\n d=%d\n", a, b, c, d);
return 0;
}
输出2 3 3 5
7. 三目运算符
#include<stdio.h>
int main()
{
int a = 0;
int b = 0;
if (a > 5)
b = 3;
else
b = -3;
//三目运算符 a>b?3:-3
}
8. 逗号表达式就是用逗号隔开的多个表达式。逗号表达式,从左向右依次执行,整个表达式的结果是最后一个表达式的结果。
下标引用操作符[ ] 操作数:一个数组名+一个索引值 int arr[10]; arr[9]=10。
函数调用操作符:接受一个或多个操作数,第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
示例如下
#include<stdio.h>
int get_max(int x, int y)
{
return x > y ? x : y;
}
int main()
{
int a = 10;
int b = 20;
//调用函数的时候的()就是函数调用操作符
int max=get_max(a,b);
printf("%d\n", max);
}
9. 创建一个学生结构体类型
struct stu
{
char name[20];
int age;
char id[20];
};
int main()
{
int a = 10;
//使用结构体类型创建了一个结构体变量学生对象s1并初始化
struct stu s1 = { "大力",10,"011" };
struct stu* ps = &s1;
printf("%s\n", ps->name);
printf("%d\n", ps->age);
//结构体指针->成员名
//printf("%s\n", (*ps).name);
//printf("%d\n", (*ps).age);
//printf("%s\n", s1.name);
//printf("%d\n", s1.age);
//printf("%s\n", s1.id);
//结构体变量.成员名
return 0;
}
10. 整形提升:cpu内整型运算器的操作数的字节长度一般就是int的字节长度,同时也是cpu的通用寄存器的长度(先转换为整型操作数的标准长度)
#include<stdio.h>
int main()
{
char a = 3;//char存储8bit
//00000000000000000000000000000011
//00000011 -a
char b = 127;
//00000000000000000000000001111111
//01111111 -b
//a和b如何相加,//整形提升是按照变量的数据类型的(符号位)来提升的,无符号位,直接补0
//00000000000000000000000000000011
//00000000000000000000000001111111
//00000000000000000000000010000010
//10000010 -c
//11111111111111111111111110000010 -补码
//11111111111111111111111110000001 -反码
//10000000000000000000000001111110 -原码 -126
char c = a + b;
printf("%d\n", c);
return 0;
}
示例
#include<stdio.h>
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
操作符的属性的三个因素:
操作符的优先级
操作符的结合性
是否控制求值顺序
运算符练习题
1)求一个整数存储在内存中的二进制中1的个数
#include<stdio.h>
int main()
{
int num = 0;
int count = 0;
scanf("%d", &num);
int i = 0;
for (i = 0; i < 32; i++)
{
if (1 == ((num >> i) & 1))
count++;
}
//32bit 按位与
// 00000000000000000000000000000010
// 00000000000000000000000000000001
// 00000000000000000000000000000000
//统计num的补码中有几个1
//while (num)
//{
// if (num % 2 == 1)
// count++;
// num = num / 2;
//}
printf("%d\n", count);
return 0;
}
2)
int main()
{
int a = 10;
int *p = &a;//取地址操作符
*p = 20;//解引用操作符
}
int main()
{
int a = 10; //sizeof 整型4bit
char c = 'r'; //字符型1bit
char* p = &c;//指针根据32/64位来定 32-4 64-8
int arr[10] = { 0 };//4*10=40
}
int main()
{
short s = 0;
int a = 10;
printf("%d\n", sizeof(s = (a + 5)));
printf("%d\n", s);
return 0;
//输出2 0 ,short占两个bit,sizeof括号内表达式是不参与运算的,s未发生变化
}
int main()
{
int a = 0;
printf("%d\n", ~a);
//00000000000000000000000000000000
//11111111111111111111111111111111 补码
//11111111111111111111111111111110 反码
//10000000000000000000000000000001 原码 -1
}
#include<stdio.h>
void test1(int arr[])
{
printf("%d\n", sizeof(arr));
}
void test2(char ch[])
{
printf("%d\n", sizeof(ch));
}
int main()
{
int arr[10] = { 0 };
char ch[10] = { 0 };
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(ch));
test1(arr);
test2(ch);
return 0;
}
输出40 10 4 4
两个int(32位)整数m和n的二进制表达中,有多少个bit位不同
输入例子:
1999 2999
输出:7个
#include<stdio.h>
int main()
{
int n = 0;
int m = 0;
int i = 0;
int count = 0;
printf("输入俩个整数\n");
scanf_s("%d%d", &m, &n);
for (i = 0; i < 32; i++)
{
if (((m >> i) & 1) != ((n >> i) & 1))
count++;
}
printf("不同比特位的数目为:%d\n", count);
return 0;
}