#include <stdio.h>
#define _CRT_SECURE_NO_WARNINGS 1
C语言操作符
1、算术操作符
1.1 + - * 、 %
int main()
{
int a = 5 % 2;//%取模操作符必须两边操作数必须为整型
double b = 5 / 2.0;
printf("a= %d", a);
return 0;
}
1.2、移位操作符
//右移操作符:
//1、算术右移
// 右边丢弃,左边补原符号位
//2、逻辑右移
// 右边丢弃,左边补0
//左移操作符
// 左边丢弃,右边补0
1.2.1正数:
int main()
{
int a = 16;
int b = a >> 2;
printf("b= %d", b);//4
//移动的是二进制位
//00000000000000000000000000010000
//00000000000000000000000000000100
return 0;
}
1.2.2负数
整数的二进制表示有:原码、反码、补码
存储到内存的是补码
int main()
{
int a = -1;
//原码1000000000000000000000000000001
//反码1111111111111111111111111111110
//补码1111111111111111111111111111111
int b = a >> 1;
//补码1111111111111111111111111111111
//右移1111111111111111111111111111111
//反码1111111111111111111111111111110
//原码1000000000000000000000000000001
printf("b = %d", b);
return 0;
}
1.3、位操作符
& 按位与 有假为假,同真为真
| 按位或 有真为真,同真为真
^ 按位异或 相同为假,相异为真
int main()
{
int a = 3;
int b = 5;
int c = a&b;
int d = a | b;
int e = a^b;
//按位与
//00000000000000000000000000000011
//00000000000000000000000000000101
//00000000000000000000000000000001
//按位或
//00000000000000000000000000000011
//00000000000000000000000000000101
//00000000000000000000000000000111
//按位异或
//00000000000000000000000000000011
//00000000000000000000000000000101
//00000000000000000000000000000110
printf("%d\n", c);//1
printf("%d\n", d);//7
printf("%d\n", e);//6
return 0;
}
练习:不创建新的变量,互换a,b的值
int main()
{
//加减法--可能会溢出
int a = 30;
int b = 50;
//a = a + b;
//b = a - b;
//a = a - b;
//异或算法
//a 011
//b 101
// 110
// 011
// 101
a = a^b;
b = a^b;
a = a^b;
printf("a=%d b=%d", a, b);
return 0;
}
练习:计算一个整数二进制数含有1的个数
int main()
{
//16
//000000000000000000000000000010000
int input = 0;
int count = 0;
scanf_s("%d", &input);
for (int i = 0; i < 32; i++)
{
if (((input>>i) & 1) == 1)
count++;
}
printf("%d", count);
return 0;
}
2、赋值操作符 -- "="
2.1复合赋值符 -- "+="
3、单目操作符 -- ! , - , + , &(取地址操作符),
int main()
{
int a = 10;
int * p = &a;//& 取地址操作符 * 解引用操作符
printf("%d\n", !a); //0
return 0;
}
3.1sizeof -- 计算变量所占内存空间的大小, 单位是字节
int main()
{
int a = 10;
char c = 'r';
char *p = &c;
int arr[10] = { 0 };
printf("%d\n", sizeof(a));//4
printf("%d\n", sizeof(int));//4
printf("%d\n", sizeof(c));//1
printf("%d\n", sizeof(char));//1
printf("%d\n", sizeof(p));//4
printf("%d\n", sizeof(char*));//4 取的是地址占内存大小
printf("%d\n", sizeof(arr));//40
printf("%d\n", sizeof(int[10]));//40
return 0;
}
int main()
{
short s = 0;
int a = 10;
printf("%d\n", sizeof(s = a + 5));//2
printf("%d\n", sizeof(short));//2
printf("%d\n", s);//0 sizeof()内部的表达式不参与运算
return 0;
}
3.2 ~ --对一个数值二进制位取反
int main()
{
int a = 0;
printf("%d\n", ~a);//-1
//~按2进制位取反
//00000000000000000000000000000000
//11111111111111111111111111111111 -补码
//11111111111111111111111111111110 -反码
//10000000000000000000000000000001 -原码
int b = 11;
int c = b | (1 << 2);
printf("%d\n", c);//15
int d = b & ( ~ (1 << 2));
printf("%d\n", d);//11
//00000000000000000000000000001011
return 0;
}
3.3 ++ ,-- 前置后置
int main()
{
int a = 10;
printf("%d\n",++a); //11 前置++,先++,后使用
printf("%d\n", a++);//11 后置++,先使用,后++
return 0;
}
3.4 ()类型转换操作符
int main()
{
int a = (int)3.14;
printf("%d\n", a);//3
return 0;
}
void test1(int arr[])
{
printf("%d\n", sizeof(arr));//4 数组传的是地址
}
void test2(char ch[])
{
printf("%d\n", sizeof(ch));//4 数组传的是地址
}
int main()
{
int arr[10] = { 0 };
char ch[10] = { 0 };
printf("%d\n", sizeof(arr));//40
printf("%d\n", sizeof(ch));//10
test1(arr);
test2(ch);
return 0;
}
4、关系操作符
5、逻辑操作符 --&& --||
int main()
{
int a = 3;
int b = 4;
int c = a && b;//1
printf("%d", c);
return 0;
}
int main()
{
short s = 5;
int a = 10;
printf("%d\n", sizeof(s = a + 2));
printf("%d\n", s);
return 0;
}
练习:
int main()
{
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;//前面为假,后面不运算
printf("a = %d,b = %d,c = %d,d = %d", a, b, c, d); //a=1 b=2 c=3 d=4
return 0;
}
int main()
{
int i = 0, a = 1, b = 2, c = 3, d = 4;
i = a++ || ++b || d++; //前面为真,后面不运算
printf("a = %d,b = %d,c = %d,d = %d", a, b, c, d); //a=2 b=2 c=3 d=4
return 0;
}
6、条件操作符 --- exp1 ? exp2:exp3
int main()
{
int a = 0;
int b = 0;
if (a > 5)
{
b = 3;
}
else
{
b = -3;
}
b = (a > 5 ? 3 : -3);//跟上面的表达一样
return 0;
}
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, a, b = a + 1);
printf("a =%d,b = %d,c= %d", a, b,c);
return 0;
}
if(a = b + 1,c = a / 2,d > 0) 起判断作用的是最后d>0,但前面的运算还是进行
7、下标引用操作符[]、函数调用和结构成员
7.1、下标引用操作符[]
int main()
{
int arr[10] = { 0 };
return 0;
}
7.2、函数调用操作符
int get_max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
int a = 10;
int b = 20;
//函数操作符----调用函数时的()
int max = get_max(a, b);
printf("%d", max);
return 0;
}
7.3结构体struct
创建一个结构体类型:学生-struct stu
struct stu
{
//成员变量
char name[20];
int age;
char id[20];
};
int main()
{
//使用struct stu这个类型创建了一个学生对象s1并初始化
struct stu s1 = {"张三",20,"205936156"};
struct stu * ps = &s1;
printf("%s\n", s1.name);
printf("%d\n", s1.age);
printf("%s\n", s1.id);
//结构体变量.成员名
printf("%s\n", ps->name);
printf("%d\n", ps->age);
printf("%s\n", ps->id);
printf("%s\n", (*ps).name);
printf("%d\n", (*ps).age);
printf("%s\n", (*ps).id);
return 0;
}
8、隐式类型转换
8.1整型提升
整型算术运算总是以缺省整型类型的精度来进行
表达式中的字符和短整型操作数在使用之前被转换为普通类型--整型提升
整型提升的规则:按照变量的数据类型的符号位来提升的
int main()
{
char a = 3;
//00000000000000000000000000000011
//char类型截断为:00000011 -a
//提升为:其余位全补为第一位的符号位数字
char b = 127;
//00000000000000000000000001111111
//char类型截断为:01111111 -b
char c = a + b;
//00000000000000000000000000000011
//00000000000000000000000001111111
//00000000000000000000000010000010
//c为char类型,截断为:10000010
//11111111111111111111111110000010 -补码
//11111111111111111111111110000001 -反码
//10000000000000000000000001111110 -原码
printf("%d\n", c);//-126
}
int main()
{
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
printf("%d\n", a); //-74
if (a == 0xb6)
//==为运算符 b6整型提升为
//11111111111111111111111110110110 --补码
//11111111111111111111111110110101 --反码
//10000000000000000000000001001010 --原码
printf("a");
if (b == 0xb600)
printf("b");
if (c == 0xb6000000)
printf("c");
return 0;
}
int main()
{
char c = 1;
printf("%u\n", sizeof(c));//1
printf("%u\n", sizeof(+c));//4 参与运算,进行整型提升
printf("%u\n", sizeof(!c));//1
return 0;
}
8.2算术转换
操作符的属性 --影响因素(对应表格)
1、操作符的优先级
int main()
{
int a = 10;
int b = 20;
int c = b + a * 3;
printf("%d\n", c);
return 0;
}
2、操作符的结合性
3、是否控制求值顺序
//以下为问题代码: 不确定唯一的计算路径
int fun()
{
static int count = 1;
return ++count;
}
int main()
{
int answer;
answer = fun() - fun() * fun();
printf("%d\n", answer);
return 0;
}