C语言 | 您所在的位置:网站首页 › C语言求平均数错误 › C语言 |
算术操作符
+ - * / %
加 减 乘 除(取商) 除(取余)
1:. 使用/(取商操作符)时,一般是这样的
#include
int main()
{
int a = 3/5;
printf("%d\n",a);
return 0;
}
//结果:0
若想求出有小数点后的数,则必须满足数据,数字,打印类型的准确。如:
#include
int main()
{
double a = 6.0/5.0;//两个数字至少有一个得是浮点数
//当两数均是整形时,无论数据类型是int还是double都取整数即1
printf("%lf\n",a);//注意这里不是%d
return 0;
}
结果:1.200000
2.% 取模操作符 取余数。其两个操作数只能是整形
#include
int main()
{
int a = 6%4;
printf("%d\n",a);
return 0;
}
移位操作符
左移操作符 右移操作符
(展示二进制后面的)a 0010 b 1000
图中-1;//是错误的
位操作符
& | ^
按位与 按位或 按位异或
(他们的操作数必须是整数)
#include
int main()
{
int a = 3;
int b = 5;
// & 按(二进制)位与
int c = a & b;
//按位与就是上下对应的二进制位,对应的位中只要有0则新的数的二进制为0,同时为1才为1
//3:00000000000000000000000000000011
//5:00000000000000000000000000000101
//c = 1:00000000000000000000000000000001
// | 按(二进制)位或
int d = a | b;
//按位或就是对应的位中只要有1则就是1,当两个都是0时才为0
//3:00000000000000000000000000000011
//5:00000000000000000000000000000101
//d = 7:00000000000000000000000000000111
// | 按(二进制)位异或
int d = a ^ b;
//对应的位相同时为0,相异为1
//3:00000000000000000000000000000011
//5:00000000000000000000000000000101
//e = 6:00000000000000000000000000000110
}
赋值操作符
可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值
=
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;//进行连续赋值
这样的代码感觉怎么样?
那同样的语义,你看看:
x = y+1;
a = x;//这样的写法更加清晰且易于调试。
2.复合赋值符
+= -= *= /= %= >>= 3//等于a >>= 3
注意: = 是赋值 , ==是判断相等
单目操作符
**
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反(包括符号位)
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
***
! //! #include int main() { int flag = 5;//flag为真,非0为真 printf("%d\n",!flag);//!将真的改成假的了,所以为0 return 0; } //结果:0 *** //sizeof #include int main() { int a = 10; int arr[10] = {0}; printf("%d\n",sizeof(arr));//计算数组的大小,结果:40 printf("%d\n",sizeof(int [10]));//40,除了数组名剩下的都是类型 printf("%d\n".sizeof(a));//计算a空间所占的大小,单位是字节 printf("%d\n".sizeof(int));//也可以直接计算类型 printf("%d\n".sizeof a);//计算字符大小时小括号可以省略,但是类型不能省 //所以sizeof是一个操作符,不是一个函数,函数的括号必须带 } #include int main() { short a = 10; int s = 5; printf("%d\n",sizeof(s)); //4 printf("%d\n",sizeof(a));//2 printf("%d\n",sizeof(a = s + 2));//结果仍然是2,因为sizeof中的表达式是不参与运算的 return 0; } #include void test1(int arr[]) { printf("%d\n", sizeof(arr));//(2)//这里是指针,因为传过来的是地址要拿指针接收 在32为机器下 字节为4 } void test2(char ch[]) { printf("%d\n", sizeof(ch));//(4)//同理,虽是char型,但是为指针变量在32上为4,64上为8 } int main() { int arr[10] = {0}; char ch[10] = {0}; printf("%d\n", sizeof(arr));//(1) 40 printf("%d\n", sizeof(ch));//(3) 10 test1(arr); test2(ch); return 0; } *** //~ ~对于正数是将原码全部按位取反(包括符号位)。对于负数是将其的补码全部按位取反(包括符号位) int main() { int a = -1; //原码:10000000000000000000000000000001 //反码:11111111111111111111111111111110 //补码:11111111111111111111111111111111 //~ 按(二进制补码)位取反(包括符号位) //原补码:11111111111111111111111111111111 //后补码:00000000000000000000000000000000 int b = ~a; printf("%d\n",b);//结果:0 return 0; } *** //++和--运算符 : 前置++和-- 后置++和-- #include int main() { int a = 10; int x = ++a;//先增加a,后使用a int y = --a;//先减小a,后使用a int x = a++;//先使用a,再增加a int y = a--;//先使用a,再减小a return 0; } #include int main() { int a = 1; int b = (++a) + (++a) + (++a);//结果:由于编译器系统的不同坑能有2种结果12/10 printf("%d\n",b); return 0; } *** * 间接访问操作符(解引用操作符) & 取地址(注意a & b中&是按位与,&a中&是取地址符) #include int main() { int a = 10; printf("%p\n",&a);//取a的地址,并打印地址 int* pa = &a;//这里*说明pa是指针变量,pa是用来存放地址的 *pa = 20;//* 间接访问操作符(解引用操作符),将a的值变成了20 printf("%d\n",a); return 0; } (类型) 强制类型转换 int main() { int a = (int)3.14; return 0; }
关系操作符 > >= < 0 1&&2---->1区分逻辑或(||) 和 按位或(|) 1|2----->3 1||2---->1 #include 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\nd = %d\n", a, b, c, d); return 0; } int main() { int i = 0, a = 1, b = 2, c = 3, d = 4; i = a++||++b||d++; printf("i = %d\n a = %d\n b = %d\n c = %d\nd = %d\n", i .a, b, c, d); return 0; } //1 2 2 3 4//当a = 0时 int main() { int i = 0, a = 0, b = 2, c = 3, d = 4; i = a++||++b||d++; printf("i = %d\n a = %d\n b = %d\n c = %d\nd = %d\n", i .a, b, c, d); return 0; } //1 1 3 3 4注意: 优先权平等下从左到有开始运算 逻辑与运算碰到错误直接结束,后面的运算就不再继续 逻辑或运算碰到正确直接结束,后面的运算就不再继续 (可以理解为从左到右运算时,逻辑与的话是遇到0即假时仅运算该运算符前的,后面的不在运算即原值。逻辑或同理)条件操作符(三目操作符) exp1 ? exp2 : exp3 exp1表示判断条件,exp2是exp1成立时的结果,exp3是不成立的结果 int main() { int a = 3; int b = 0; /* if(a>5) b = -1; else b = 1;*/ //可用条件操作符达成 b = (a>5 ? -1: 1) ; }逗号表达式(就是用逗号隔开的多个表达式) exp1, exp2, exp3, …expn 逗号表达式,从左向右依次执行,整个表达式的结果是最后一个表达式的结果。 //逗号表达式使用灵活,可用在很多地方 int main() { int a = 2; int b = 4; int c = 5; int d = (c = 3,a = b + 1,b = a + 3); printf("%d\n",d); return 0; } //结果:8 //逗号表达式也可用在if语句中 if (a =b + 1, c=a / 2, d > 0) //又如这个中 a = get_val(); count_val(a); while (a > 0) { //业务处理 a = get_val(); count_val(a); } //如果使用逗号表达式,改写: while (a = get_val(), count_val(a), a>0) { //业务处理 } #include int main() { int arr[] = {1,2,(3,4),5}; printf("%d\n",sizeof(arr)); return 0; } //(3,4)中是逗号表达式取最后的数即4 //int arr[] = {1,2,4,5}; //4个整形数即4*4 = 16下表引用,函数调用和结构成员 *** 下表引用操作符 [] int arr[10];//创建数组 arr[9] = 10;//实用下标引用操作符。 // [ ]的两个操作数是arr和9。*** 函数调用操作符 () #include void test1() { printf("sasade"); } test2(int x, int y) { return x + y; } int main() { test1(); //()为函数调用操作符,操作数为test1 test2(a,b);//操作数为test2,a,b return 0; }*** . 结构体.成员名 -> 结构体指针->成员名 #include struct Book { char name[20]; char id[20]; int price; };//注意结构体后需要加“;” int main() { struct Book b = {"C语言",“021BV922”,55}; struct Book * pb = &b; //为了找到结构体成员 printf("书名: %s\n", pb->name); printf("书号: %s\n", pb->id); printf("价钱: %s\n", pb->price); //printf("书名: %s\n", (*pb).name); //printf("书号: %s\n", (*pb).id); //printf("价钱: %s\n", (*pb).price); // printf("书名: %s\n", b.name); // printf("书号: %s\n", b.id); // printf("价钱: %s\n", b.price); return 0; }表达式求值 表达式求值的顺序一部分是由操作符的优先级和综合性决定。有些表达式的操作数在求值的过程中可能需要转化为其他类型 一.隐式类型转换 1.整形提升 整形提升:表达式中的字符和短整型操作数在使用之前被转换为普通整形(转换short,char型) // 无符号整形提升(unsigned char),高位补0 实例: #include int main() { char a = 3; //3:00000000000000000000000000011 //由于在char型下,只有8个比特位,从后往前截取得a: 00000011 char b = 127; //127:00000000000000000000001111111 //同上b:01111111 //正数的原码反码补码相同 char c = a + b; ///3: 00000000000000000000000000011 //127: 00000000000000000000001111111 //3+127 : 00000000000000000000010000010 //c:10000010 //c整形提升后:11111111111111111111111110000010,这是补码 //c原码: 10000000000000000000001111110 ———— -126 printf("%d\n",c);//打印时得求出原码 return 0; } 注意:内存中存的是补码,内存中数字计算的是补码 printf("%d\n",c);//打印时得求出原码实例 int main() { char a = 0xb6; short b = 0xb600; int c = 0xb60000000; if(a = 0xb6)//因为表达式中a是char类型,没达到一个整形大小,所以会整形提升 { printf("a");//而当a整形提升后便不再是原来的值,所以不会打印 } if(b = 0xb600) { printf("0xb600");//与上同理 } if(c = 0xb60000000) { printf("0xb60000000");//由于c本来就是整形,不去提升 } //仅打印c return 0; } //c int main() { char a = 1; printf("%u\n",suzeof(a));// 1 仅计算a的大小 printf("%u\n",suzeof(+a));//4 +a表示参与运算,则需进行整形提升 printf("%u\n",suzeof(-a));//4 同上 return 0; } 注意:c只要参与表达式运算就会发生整形提升2.算术转换 如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另外一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换 long double double float unsigned long int long int unsigned int int如果某个操作数的类型在上表中排名较低,那么首先要转换为另外一个操作数的类型后,再执行运算。(向长/精度更高的的转换) 二.操作符属性 复杂操作符的求值有3个影响因素: 1.操作符的优先级(执行的先后) 2.操作符的结合性(运算的方向) 3.是否控制求值顺序(有"&&","||","?:","," 四种) 两个相邻的操作符先执行哪个? 取决于他们的优先级,如果两者的优先级相同,取决于他们的结合性 优先级和结合性表: (从上到下优先级逐渐降低) (L-R表示结合性从左向右,R-L表示从右向左,N/A表示无结合性)
注意: 在我们掌握操作符的属性后,能处理大多数的情况,但是还有一部分表达式是没办法确定唯一计算顺序的 例如:当c = 3时 c + --c //3+2 = 5 //2+2 = 4 操作符的优先级只能决定自减--的运算在+的运算的前面,但是不能决定+操作符的左操作数的获取在右操作数之前还是之后求值 (如果我们不能通过操作符确定为一的计算路径,这个表达式是有问题的) ———————————————————————— 普热希提 |
CopyRight 2018-2019 实验室设备网 版权所有 |