1.逻辑运算符的短路效应
/*
逻辑运算符的短路效应
对于逻辑与(&&)来说,同为真时才为真,所以当条件1为假时不需要计算条件2
对于逻辑或(||)来说,同为假时才为假,所以当条件1为真时不需要计算条件2
下面的运算形式为,先计算(++a && ++b)的结果,
++a为真,故再计算++b,结果也为真,所以表达式(++a && ++b)为真
对于((++a && ++b) || ++c),已经有一项为真,所以不计算++c
*/
int main()
{
int a = 0;
int b = 0;
int c = 0;
if(++a && ++b || ++c)
{
a++;
b++;
c++;
}
printf("%d,%d,%d\n",a,b,c);
return 0;
}
2.关系表达式的值
/*
关系表达式的值
关系运算符的结合律是从右往左,先计算(10>5),结果为真,在C语言中即为1
用结果与后面的比较(1>3)结果为假,在C语言中为0,输出小于号
*/
int main()
{
if(10 > 5 > 3)
{
printf(">\n");
}
else
{
printf("<\n");
}
}
3.函数压栈
/*
函数压栈顺序
函数压栈,是从右往左压栈,且压栈时就要确定实参的值
所以,先看第二个参数,压栈时i是0,所以压arr[0]
然后压第一个参数,i经过自增此时是1,所以压arr[1]
*/
int main()
{
int arr[] = {1,2,3,4,5};
int i = 0;
printf("%d,%d\n", arr[i++], arr[i++]);
}
4.数组与指针的区别
/*
数组与指针的区别
1.大小不同
2.指针可以++,数组名不可以
3.访问方式不同
数组名何时表示数组
1.在定义数组的同一个函数中求sizeof(arr)
2.在定义数组的同一个函数中取地址+1,&arr+1
3.在函数调用中传递数组,数组会退化成指针
*/
void Fun(int arr[10])//退化成指针
{
printf("%d\n",sizeof(arr));
}
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int *p = arr;
printf("%d,%d,%d\n",sizeof(arr),&arr,&arr+1);
printf("%d,%d\n",arr[2],p[2]);
printf("%d,%d\n",*(arr+3),*(p+3));
Fun(arr);
return 0;
}
5.数据溢出及默认类型转换
/*
数据溢出及默认类型转换
整数默认为int,小数默认是double
当给执行char a = 197时,先计算197,因为是正数,所以它的原码就是它的补码
计算机中197的补码 0000 0000 0000 0000 0000 0000 1100 0101,
因为a是char类型所以只需要一个字节的二进制码,所以只截取后一个字节1100 0101
而因为计算机中按二进制码保存所以a认为1100 0101是它的补码
计算机中a的补码 1100 0101
因为符号位是1,所以是负数,通过取反+1计算原码,
故a的原码为 1011 1011 通过计算可得-59,
此处需要手算,因为电脑的计算其是给予的任何二进制码它都认为是补码
*/
int main()
{
char a = 197;//补码 1100 0101-> 原码 1011 1011->-59
char b = 255;//补码 1111 1111-> 原码 1000 0001->-1
char c = -1;
int d = a;
printf("%d\n",d);//-59
d = b;
printf("%d\n",d);//-1
d = c;
printf("%d\n",d);//-1
//无符号整形无符号位
unsigned char e = 197;
unsigned char f = 255;
unsigned char g = -1;//255
d = e;
printf("%d\n",d);//197
d = f;
printf("%d\n",d);//255
d = g;
printf("%d\n",d);//255
return 0;
}