C语言-操作符详解(下)
除了隐式类型转换外还有一种蒜素转换
算数转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系成为寻常算数转换。
long double
double
float
unsigned long int
long int
unsigned int
int
如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。
警告:但是算数转换要合理,要不然会有一些潜在的问题。
操作符的属性
复杂表达式的求值有三个影响的因素
1、操作符的优先级
2、操作符的结合性
3、是否控制求值顺序
两个相邻的操作符先执行那个?取决于它们的优先级,如果两个优先级相同,取决于它们的结合性。
操作符优先级
int main(){
int a = 4;
int b = 5;
int c = a + b * 7; //优先级决定了计算顺序
int c = a + b + 7; //优先级不起作用,结合性决定
return 0;
}
一些问题表达式
//表达式的求值部分由操作符的优先级决定
//表达式1
a * b + c * d + e * f
注释:代码1在计算的时候,由于比+的优先级高,只能保证,的计算是比+早,但是优先级并不能决定第三个*比第一个+早执行。
所以表达式的计算机顺序就可能是:
a*b
c*d
a*b + c*d
e*f
a*b + c*d + e*f
或者:
a*b
c*d
e*f
//表达式2
c + --c
//注释:同上,操作符的优先级只能决定自减--的运算在+
//的运算的前面,但是我们没有办法得知,+操作符左边操作数的获取在操作数之前还是之后求值,所以结果是不可预测的,是有歧义的。
//代码3-非法表达式
int main(){
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n",i);
return 0;
}
表达式3在不同编译器测试结果:非法表达式程序的结果
值 | 编译器 |
---|---|
-128 | Tandy 6000 Xenix 3.2 |
-95 | Think C 5.02(Macintosh) |
-86 | IBM PowerPC Aix 3.2.5 |
-85 | Sun space cc(K&C编译器) |
-63 | gcc,HP_UX 9.0,Power C 2.0.0 |
4 | Sun Sparc acc(K&C编译器) |
21 | Turbo C/C++ 4.5 |
22 | FreeBSD 2.1 R |
30 | Dec Alpha OSF1 2.0 |
36 | Dec VAX/VMS |
42 | Microsoft C 5.1 |
//代码4
int fun(){
static int count = 1; //在多次调用的情况下如果添加修饰是static那么多次调用的时候不会重新赋值。
//也就是说第一此调用等于2,第二次调用就不会赋值为1,而是继续使用第一次计算得到的结果2.
return ++count;
}
int main(){
int answer;
answer = fun() - fun() * fun();
printf("%d\n",answer);//输出多少?
return 0;
}
这个代码没有实际的问题
有问题!
虽然在大多数的编译器上求得结果都是相同的。
#include <stdio.h>
int main(){
int arr[] = {1,2,(3,4),5};//注意这里的括号内是逗号表达式,也就是说结果是最后一个数字4
printf("%d\n",sizeof(arr));//4X4 = 16
return 0;
}
#include <stdio.h>
int main(){
char str[] = "hello bit";
//hello bit\0
printf("%d %d\n", sizeof(str),strlen(str));
//sizeof 算数组空间长度 一个char是一个字节所以 10 strlen算长度 不计算/0
return 0;
}
数组名表示首元素的地址