初阶C语言 |
您所在的位置:网站首页 › c操作符的优先级别 › 初阶C语言 |
操作符详解
一、操作符分类二、操作符详解2.1算术操作符2.2移位操作符2.2.1左移操作符2.2.2右移操作符
2.3位操作符2.4赋值操作符2.5单目操作符2.5.1单目操作符介绍2.5.2sizeof和数组
2.6关系操作符2.7逻辑操作符2.8条件操作符2.9逗号表达式2.10下标引用、函数调用和结构成员2.11表达式求值2.11.1隐式类型转换2.11.2算术转换2.11.3操作符的属性
一、操作符分类
算术操作符 移位操作符、位操作符(这两者都是对二进制补码操作) 赋值操作符、单目操作符、关系操作符、逻辑操作符、条件操作符、逗号表达式 下标引用、函数调用和结构成员 二、操作符详解 2.1算术操作符有+ - * / % 1.除了%操作符之外,其他操作数可以是整数或者浮点数,%的两个操作数必须是整数。返回的是整除之后的余数 2.对于/操作符的两个数是两个整数的话,执行整数除法,否则只要有一个是浮点数,执行浮点数除法。 2.2移位操作符>:右移操作符 注:移位操作符的操作数只能是整数,计算的是二进制补码 数据在内存存储的是补码,计算的是补码,但最终打印出的结果是原码的十进制的值 移位之后,本身的值是没有改变的,例如: #include int main() { int num = 10; num -1;//error 2.3位操作符&(按位与)(对应二进制位有0则为0,两个同时为1才为1,符号位也一样) | (按位或)(对应的二进制位有1则为1,两个同时为0才为0,符号位也一样) ^ (按位与或)(对应的二进制位相同为0,不同则为1,符号位也一样) 注:他们的操作数必须是整数,比较的还是操作数的二进制位补码 例子: int main() { int num = 1; int num1 = 2; int a = num & num1; int b = num | num1; int c = num ^ num1; printf("%d %d %d", a, b, c); return 0; }其次注意的是复合赋值符的用法 += -= *= /= %= >>= printf("%d\n", sizeof(arr));//求数组名的大小,数组名本质上是首元素地址,地址就是指针,相当于求的就是指针大小,在32平台上指针大小为4个字节,在64位平台上指针大小为8 } void test2(char ch[]) { printf("%d\n", sizeof(ch)); } int main() { int a = -10; int* p = NULL; int arr[10] = { 0 }; char ch[10] = { 0 }; printf("%d\n", sizeof(arr));//求数组的大小 printf("%d\n", sizeof(ch));//求数组的大小 test1(arr);//将数组名首地址传过去 test2(ch); return 0; } exp1?exp2:exp3 if(a>5) b=3; else b=-3; //将该表达式转化为条件表达式 b=a>5?3:-3;//如果表达式1为真,执行表达式2,否则执行表达式3 2.9逗号表达式exp1,exp2,…expN 从左向右依次执行,整个表达式的结果是最后一个表达式的结果 int main() { int a = 1; int b = 2; int c = (a > b, a = b + 10, a, b = a + 1);//0 12 12 13 printf("%d", c); return 0; }[ ] 下标引用操作符 操作数:一个数组名+一个索引值 如:arr[0]; ( ) 函数调用操作符(接受一个或多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数)如:test(1,2) . 结构体.成员名 -> 结构体指针->成员名 struct stu { char name[20]; int age; char sex[5]; }; int main() { struct stu a; struct stu* b = &a; a.age = 20;//结构体变量访问成员 b->age = 20;//结构体指针访问成员 return 0; } 2.11表达式求值表达式求值的顺序一部分是由操作符的优先级和结合性决定。同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。 2.11.1隐式类型转换整形提升的意义: 表达式的整形运算要在CPU的运算器内执行,CPU内整形运算器的操作熟的直接长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。 因此,即使两个char类型的相加,在CPU执行时实际上也要转换为CPU内整形操作数的标准长度。 通用CPU是难以实现两个8比特直接直接相加运算(虽然机器指令中可能存在这种直接相加指令)。所以,表达式中各种长度可能小于int长度的整形值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。 int main() { char a = 1; char b = 2; char c; c = a + b;//b和c 的值被提升为普通整形,计算完之后,在截断 return 0; }
这里的%u是打印无符号十进制形式,通过结果可以发现,+c和-c中的c都发生了运算,只要发生运算就会进行整形提升,所以sizeof(+c)和sizeof(-c)都是4个字节大小,而sizeof(c)计算的就是c的本身类型大小大小为1个字节 2.11.2算术转换long double double float unsigned long int long int unsigned int int unsigned char char 当进行以上不同类型的操作数计算时,其转换方式是由下向上转换的,若算术转换从上往下转时,会存在一些精度的丢失 float f=3.14; int num=f;//隐式转换,会有进度丢失 2.11.3操作符的属性复杂表达式的求值有三个影响的因素。 1.操作符的优先级 2.操作符的结合性 3.是否控制求值顺序 两个相邻操作符先执行哪个取决于他们的优先级,若优先级相同,取决于他们的结合性 到底是先算 ab cd ab+cd ef ab+cd+ef 还是 ab cd ef ab+cd ab+cd+ef c+--c; //+的左操作数先准备好还是--c之后准备好c nt main() { int i = 10; i = i-- - --i * (i = -3) * i++ + ++i; //到底是现--i准备好i后,还是++i准备好i后计算呢,不同编译器存在不同的差异 return 0; }end~ |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |