符号的技巧
专题二:符号的技巧。包括以下章节:
- 注释符号
- 接续符和转义符
- 单引号和双引号
- 逻辑运算符使用分析
- 位运算符分析
- ++、–操作符使用分析
- 优先级和类型转换分析
问题
- int = 3; (++i)+(++i)+(++i)=?
- c语言灰色地带
6-1.c
#include<stdio.h>
int main()
{
int i = 3;
//(++i)+(++i)+(++i)=?
//编译器1:三个小括号计算一遍,得到i=6,然后6+6+6=18
//编译器2:前两个小括号计算,得到5+5;然后计算最后一个小括号,5+5+6=16
//一般编译器是按照编译器2来编译的
//在编程中尽量不要这样写,因为可能得到的不是我们想要的结果。
printf("%d\n", (++i)+(++i)+(++i));
return 0;
}
结果:
- 逗号表达式
#include<stdio.h>
int main()
{
int x;
int i = 3;
//(++i, i++, i+10)=?
//从左到右的顺序求值,最后一个表达式的值就是逗号表达式的值
//++i=4,i++=4(i=5,表达式的值=4),i+10=15
x = (++i, i++, i+10);
printf("%d\n", x);
return 0;
}
结果:
c语言中的贪心法
- 编译器处理每个字符应该尽可能多的包含字符
- 编译器以从左到右的顺序一个一个尽可能多的读入字符
- 当即将读入的字符不可能和已读入的字符组成合法字符为止
实例分析6-1
#include<stdio.h>
int main()
{
int i = 0;
//编译器读到++i++,懵逼了,出错。
int j = ++i+++i+++i;
//++i++,编译器编译错误相同
//1++,编译器编译错误相同
int a = 1;
int b = 2;
int c = a+++b;
int* p = &c;
//b=b/*p;
return 0;
}
结果:
#include<stdio.h>
int main()
{
int i = 0;
//编译器读到++i++,懵逼了,出错。
//int j = ++i+++i+++i;
//++i++,编译器编译错误相同
//1++,编译器编译错误相同
int a = 1;
int b = 2;
//a+++b,编译器编译正确。即a++ + b
int c = a+++b;
printf("%d\n", c);
int* p = &c;
//b=b/*p;
return 0;
}
结果:
#include<stdio.h>
int main()
{
int i = 0;
//编译器读到++i++,懵逼了,出错。
//int j = ++i+++i+++i;
//++i++,编译器编译错误相同
//1++,编译器编译错误相同
//int a = 1;
//int b = 2;
//a+++b,编译器编译正确。即a++ + b
//int c = a+++b;
//printf("%d\n", c);
int* p = &c;
//编译出错。根据贪心法规则,编译器会认为/*为注释符号。
b=b/*p;
return 0;
}
正确的写法应该是加上空格
#include<stdio.h>
int main()
{
int i = 0;
//相当于(++i)+ (++i)+ (++i):先计算前2个括号,i=2,2+2;计算后一个括号,2+2+3=7
int j = ++i+ ++i+ ++i;
printf("%d\n", j);
int a = 1;
int b = 2;
int c = a+++b;
printf("%d\n", c);
int* p = &c;
//2/3=0,取整数等于0
b = b / *p;
printf("%d\n", b);
return 0;
}
结果: