操作符分类:
算数操作符:+ - * / %
//算数操作符
// int main()
// {
// // /除法 1.整数除法(除号两端都是整数) 2浮点数除法,除号的两端只要有一个小数就执行小数除法
// // 除法中,除数为0
// int a = 7 / 2;
// printf("%d\n",a); //3
// double b = 7 / 2;
// printf("%lf\n",b); //3.000000
// double c = 7 / 2.0;
// printf("%lf\n",c); //3.500000
// int d = 0;
// int e = 5 / d; //除数不可为0,编译器会报错
// printf("%d\n",e);
// return 0;
// }
int main()
{
int a = 17 % 8; //% 得到数整数的余数
//int b = 17.0 % 8.0; // %取模操作符的两个操作数必须都是整数才行
printf("%d\n",a);
return 0;
}
移位操作符:<< >>
//移位操作符
// <<左移操作符
// >>右移操作符
//注意:以为操作符的操作数只能是整数 移动的是二进制
int main()
{
//int a = 15;//00000000000000000000000000001111 -原码 //00000000000000000000000000001111 -反码 //00000000000000000000000000001111 -补码
//int c = -15; //10000000000000000000000000001111 -原码 //11111111111111111111111111110000 -反码(原码的符号位不变,其他位按位取反) 11111111111111111111111111110001 -补码(反码+1就是补码)
//int b = a >> 1;//移动的就是a中的二进制信息 //0000000000000000000000000000111 - 7
//右移:算术右移(右边丢弃,左边直接补原来的符号位) 逻辑右移(右边丢弃,左边直接补0)
// C语言没有明确规定是算术右移还是逻辑右移
//int c = a << 1;//00000000000000000000000000011110
//整数的二进制表示形式 : 原码 反码 补码
//正整数的原码、反码、补码是相同的
//负的整数原码、反码、补码是要计算的
//首先不管是正整数还是负整数都可以写出二进制原码 1.根据正负直接写出的二进制序列就是原码
//1个整型是4个字节 = 32bit位
//整数在内存中存储的是补码
//计算的时候也是使用补码计算的
// printf("%d\n",b); //7
// printf("%d\n",c); //30
// int d = -15; //10000000000000000000000000001111
// int e = d >> 1;//11111111111111111111111111110001 -> 11111111111111111111111111111000 -> 11111111111111111111111111110111 ->00000000000000000000000000001000
// printf("%d\n",e);
//!移位操作符不要移负数哦
int a = 6;// 110
int b = a << 1;//1100
printf("%d\n",b); //12
return 0;
}
位操作符:& | ^
//位操作符
//也是操作二进制位
// &
// int main()
// {
// int a = 3; //00000000000000000000000000000011
// int b = -5;//10000000000000000000000000000101 11111111111111111111111111111010 补码11111111111111111111111111111011
// int c = a & b;
// // & -- 对应二进制位,有0则为0,两个同时为1才是1
// //00000000000000000000000000000011
// //11111111111111111111111111111011
// //00000000000000000000000000000011 -补码
// printf("%d\n",c); //3
// return 0;
// }
//|
// int main()
// {
// int a = 3; //00000000000000000000000000000011
// int b = -5;//10000000000000000000000000000101 11111111111111111111111111111010 补码11111111111111111111111111111011
// int c = a | b;
// // | -- 对应二进制位,有1则为1,两个同时为0才是0
// //00000000000000000000000000000011
// //11111111111111111111111111111011
// //11111111111111111111111111111011 -补码
// //11111111111111111111111111111010
// //10000000000000000000000000000101 -5
// printf("%d\n",c); //-5
// return 0;
// }
//^
int main()
{
int a = 3; //00000000000000000000000000000011
int b = -5;//10000000000000000000000000000101 11111111111111111111111111111010 补码11111111111111111111111111111011
int c = a ^ b;
// ^ -- 对应二进制位,相同为0,相异为1
//00000000000000000000000000000011
//11111111111111111111111111111011
//11111111111111111111111111111000 -补码
//11111111111111111111111111110111
//10000000000000000000000000001000
printf("%d\n",c); //-8
return 0;
}
//不能创建临时变量,实现两个整数的交换
int main()
{
int a = 3;
int b = 5;
printf("交换前: a=%d b=%d\n",a,b);
// int tmp = a;
// a = b;
// b = tmp;
// a = a + b;
// b = a - b;
// a = a - b; 超过整形最大存储则不行
//a ^ a -> 0
//a ^ 0 = a
// 异或是支持交换律的
//a ^ b ^ a = 5
//a ^ a ^ b = 5
a = a ^ b;
b = a ^ b; // b = a ^ b ^ b = a
a = a ^ b;// a = a ^ b ^ a = b
printf("交换后: a=%d b=%d\n",a,b);
return 0;
}
编写代码实现:求一个整数存储在内存中的二进制中1的个数
//编写代码实现:求一个整数存储在内存中的二进制中1的个数
//方法1
// int main()
// {
// //整数有32个bit位
// //获得32个bit位的每一位,
// //判断这一位是否为1
// //是1就是记数器+1
// int num = 10;
// int count = 0;
// while (num)
// {
// if (num%2 == 1)
// {
// count++;
// }
// num = num/2;
// }
// printf("二进制中1的个数 = %d\n",count);
// return 0;
// }
//方法2
int main()
{
int num = 10;
int i = 0;
int count = 0;
for(i=0;i<32;i++)
{
if (num & (1 << i))
{
count++;
}
}
printf("二进制中1的个数 = %d\n",count);
return 0;
}
赋值操作符: = += -= *= /= ....
//赋值操作符
int main()
{
int weight = 120;//体重
weight = 89; //不满意就赋值
double salary = 10000.0;
salary = 20000.0;
int a = 10;
int x = 0;
int y = 20;
a = x = y+1;//连续复制
return 0;
}
单目操作符: ! sizeof + - ~ & *
//单目操作符
// int main()
// {
// int flag = 5;
// if(flag == 0)
// {
// printf("hehe\n");
// }
// if(!flag) //flag为假打印hehe
// {
// printf("hehe\n");
// }
// if(flag)
// {
// printf("haha\n");
// }
// return 0;
// }
//单目操作符只有一个操作数
// int main()
// {
// int a = 5;
// int b = -a;
// printf("%d\n",b);
// return 0;
// }
//& * 应用于指针
// int main()
// {
// int a = 10;
// //pa是指针变量
// int* pa = &a; // &-取地址操作符 取出a的地址
// *pa = 20; //解引用操作符(间接访问操作符)-单目操作符-通过pa中存放的地址,找到指向的空间(内容)
// int c = *pa;
// printf("%d\n",c);
// return 0;
// }
//sizeof 不是函数,是操作符号
//sizeof 计算的是类型创建变量的大小,单位是字节
// int main()
// {
// int a = 10;
// double b = 10.0;
// printf("%d\n",sizeof(int));//4
// printf("%d\n",sizeof(a));//4
// printf("%d\n",sizeof(b));//8
// return 0;
// }
// int main()
// {
// int arr1[10];
// printf("%d\n",sizeof(arr1)); //40 计算整个数组的大小,单位字节
// printf("%d\n",sizeof(int [10])); //40
// int arr2[20];
// printf("%d\n",sizeof(arr2));//80
// return 0;
// }
// ~ 按位取反 按补码二进制位取反
// int main()
// {
// int a = 0;
// printf("%d\n", ~a);
// //00000000000000000000000000000000
// //11111111111111111111111111111111 -补码
// //11111111111111111111111111111110
// //10000000000000000000000000000001 -1
// return 0;
// }
// int main()
// {
// int a = 13;
// //00000000000000000000000000001101
// //00000000000000000000000000010000
// a |= (1<<4);
// //00000000000000000000000000011101
// //11111111111111111111111111101111
// //00000000000000000000000000001101
// printf("%d\n",a); //29
// a &= (~(1 << 4));
// printf("%d\n",a);
// return 0;
// }
// int main()
// {
// int a = 0;
// //scanf 读取失败返回的是EOF
// //假设scanf读取失败了,返回了EOF ---> -1
// //while (scanf("%d",&a) != EOF)
// while(~scanf("%d",&a)) //~ -1为false
// {
// printf("%d\n",a);
// }
// return 0;
// }
// --前置、后置--
//++前置 、后置++
// int main()
// {
// int a = 1;
// int b = a++; //后置++,先使用,后++
// //int c = ++a; //先置++ ,先++在使用
// printf("b=%d a=%d\n",b,a);
// int c = 1;
// int e = c--; //后置--,先使用,后--
// printf("e=%d c=%d\n",e,c);
// return 0;
// }
//强制类型转换
int main()
{
int a = (int)3.14; //强制转换
printf("%d\n",a);
// int a = int(3.14) //err
return 0;
}
void test1(int arr[]) //int* 4/8个字节
{
printf("%d\n",sizeof(arr));
}
void test2(char ch[]) //char* 4/8个字节
{
printf("%d\n",sizeof(ch));
}
int main()
{
int arr[10] = {0};
char ch[10] = {0};
printf("%d\n",sizeof(arr)); //40
printf("%d\n",sizeof(ch)); // 10
test1(arr); // x86上是4 ,x64上是8
test2(ch); // x86上是4 ,x64上是8
return 0;
}
关系操作符: > < >= <= =. !=. 关系操作符只能应用到适合的类型上
int main()
{
int a = 0;
int b = 0;
scanf("%d %d",&a ,&b);
if(a == 5 && b ==5)
{
printf("hehe\n");
}
if(a == 5 || b ==5)
{
printf("haha\n");
}
return 0;
}
int main()
{
int y = 0;
scanf("%d",&y);
//判断是否是闰年 1.能被4整除,并且不能被100整除
//2 .能被400整除是闰年
if(((y%4==0) && (y%100!=0)) || (y%400==0))
{
printf("y=%d是闰年\n",y);
}
else
{
printf("不是闰年");
}
return 0;
}
逻辑操作符:&& 逻辑与 并且 || 逻辑或 或者
int main()
{
int i = 0, a = 0, 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);//1 2 3 4
i = a++ || ++b ||d++;
printf("a = %d\n b = %d\n c = %d\n d = %d\n",a,b,c,d);//1 3 3 4
return 0;
}
条件操作符:? :
//条件操作符也叫三目操作符 有三个操作数 exp1 ? exp2 : exp3
//双目操作符 a+b
//单目操作符 !a
// int main()
// {
// int a = 0;
// int b = 0;
// // if (a > 5)
// // {
// // b = 3;
// // } else
// // {
// // b = -3;
// // }
// //(a > 5) ? (b = 3) : (b = -3);
// b = (a > 5) ? 3 : -3;
// printf("%d\n",b);
// return 0;
// }
int main()
{
int a = 0;
int b = 0;
scanf("%d %d",&a,&b);
int m = (a > b) ? a : b;
printf("%d\n",m);
return 0;
}
逗号表达式 : ,
//exp1,exp2,exp3,....expN
//逗号表达式 : 从左向右计算,整个表达式的结果是最后一个表达式的结果
// int main()
// {
// int a = 1;
// int b = 2;
// int c = (a>b, a = b+10 ,a,b=a+1); //13
// printf("%d\n",a); //12
// printf("%d\n",b); //13
// printf("%d\n",c); //13
// return 0;
// }
// int main()
// {
// // a = get_val();
// // count_val(a);
// // while (a > 0)
// // {
// // //业务处理
// // a = get_val();
// // count_val(a);
// // }
// //使用逗号表达式
// while (a = get_val(),count_val(a), a>0)
// {
// //业务处理
// }
// return 0;
// }
下标引用,函数调用和结构成员: []. (). . ->
[] 下标引用操作符
操作数:一个数组名+一个索引值
//[] 下标引用操作符
// int main()
// {
// int arr[10] = {1,2,3,4};
// //数组的起始是有下标的,下标是从0开始的
// printf("%d\n",arr[2]); //arr 和 2是[]的两个操作数
// return 0;
// }
()函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数
// return 0;
// }
int Add(int x,int y)
{
return x + y;
}
//函数调用操作符
int main()
{
int len = strlen("abc"); //()函数调用操作符
//()的操作数是:strlen 函数名 "abc" 实参
printf("%d\n",len);
int c = Add(3,5);
printf("%d\n",c);
//对于函数调用操作符来说,最少有1个操作数
return 0;
}
访问一个结构的成员
. 结构体,成员名
-> 结构体指针 -> 成员名
结构体 -复杂类型 -自定义类型
//可变参数列表 -参数的个数是变化的 -探索
struct Book
{
char name[30];
char author[20];
float price;
};
void Print(struct Book * p)
{
//printf("%s %s %f\n",(*p).name,(*p).author,(*p).price);
printf("%s %s %f\n",p->name,p->author,p->price);
// ->
//结构指针->成员名 p->name
}
int main()
{
struct Book b1 = {"C语言","ccc",66.8f};//书
struct Book b2 = {"Java入门","jjj",55.8f}; //书
Print(&b1);
//printf("%s %s %f\n",b1.name,b1.author,b1.price);
//printf("%s %s %.1f\n",b2.name,b2.author,b2.price);
//结构体变量,成员名
return 0;
}
表达式求值
表达式求值的顺序一部分是由操作符的优先级和结核性决定。
同样,有些表达式的操作数在求值的过程中困难需要转化为其他类型
//表达式求值
//1表达式在计算的过程中,有哪些类型转换?
//2表达式的求值顺序是怎么样的
//类型转换 1整型提升 2算术转换
//整形提升 C的整型算术运算总是至少一缺省整型类型的精度来进行的 为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升
int main()
{
char c1 = 5;
//00000000000000000000000000000101
//00000101 - c1
char c2 = 127;
//00000000000000000000000001111111
char c3 = c1 + c2; // -124
//00000000000000000000000000000101
//00000000000000000000000001111111
//00000000000000000000000010000100
//%d - 10进制的形式打印有符号的整数
//11111111111111111111111110000100
//10000000000000000000000001111100 -124
printf("%d\n",c3);
return 0;
}
// %u 打印10进制的形式无符号的整数
// int main()
// {
// char c = 1;
// printf("%u\n",sizeof(c)); //1
// printf("%u\n",sizeof(+c)); //1
// printf("%u\n",sizeof(-c)); //1
// return 0;
// }
// int main()
// {
// float f = 3.14;
// int a = 10;
// char b = a + f; // 13
// int c = a + f; // 13
// printf("%d\n",b);
// printf("%d\n",c);
// return 0;
// }
//相邻操作符优先级高的先算,低低后算
//相邻操作符的优先级相同的情况下,结合性起作业
// int main()
// {
// int a = 2 + 3 * 5;
// return 0;
// }
// int main()
// {
// int i = 10;
// i = i-- - --i * (i = -3) * i++ + ++i;
// printf("i = %d\n", i);
// return 0;
// }
int fun()
{
static int count = 1;
return ++count;
}
int main()
{
int answer;
answer = fun() - fun() * fun(); // 2 - 3*4 -10
printf("%d\n",answer); //输出多少
return 0;
}