K&R2示例代码中(*++argv)[0]与*++argv[0]语法原理疑问
核心原理:C语言运算符优先级规则
你推导错误的根本原因是搞反了运算符优先级:[]下标运算符的优先级高于前置自增++和解引用*,所以*++argv[0]的运算顺序和你想象的完全不同。
分步拆解执行逻辑
我们结合外层循环执行后的上下文来分析:
- 外层
while循环的判断条件(*++argv)[0] == '-'执行时,argv会先自增1,已经指向当前待处理的选项字符串(比如-xn这类支持合并写的选项,不是最初的程序名),此时argv[0]就是指向该选项字符串首字符(也就是'-')的char*指针。 *++argv[0]的实际运算顺序:- 第一步:执行
argv[0],拿到指向当前选项字符串首字符的char*指针 - 第二步:执行
++argv[0],把这个char*指针本身自增1,指向字符串的下一个字符(第一次执行时就从'-'跳到后面的实际选项位) - 第三步:执行
*解引用,取出指针指向的字符赋值给c - 当指针走到字符串末尾的
'\0'时,赋值给c的结果就是0,内层while循环自动终止,刚好完成当前选项字符串所有字符的遍历。
- 第一步:执行
实际运行示例
假设你执行的命令是./find -xn test_pattern:
- 外层循环第一次运行:
argc减为3,argv自增1指向选项字符串"-xn",判断(*argv)[0]为'-',进入内层循环 - 内层第一次迭代:
argv[0]初始指向'-',自增后指向'x',解引用得到'x',触发对应分支将except设为1 - 内层第二次迭代:
argv[0]当前指向'x',自增后指向'n',解引用得到'n',触发对应分支将number设为1 - 内层第三次迭代:
argv[0]当前指向'n',自增后指向字符串末尾的'\0',解引用得到0,内层循环退出 - 外层循环继续判断下一个参数,直到遇到非
'-'开头的参数,此时argv就指向最后的模式串test_pattern,逻辑完全通顺。
你的推导错误点说明
你误以为运算顺序是先执行++argv再取下标[0],但因为[]优先级更高,自增操作的对象是argv[0]这个指向单条选项字符串的指针,而不是argv本身,所以不会跳到下一条命令行参数,只会在当前选项字符串内部向后遍历。
内容的提问来源于stack exchange,提问作者HerrWeishaupt
相关产品推荐
相关产品推荐

