为何argc[argv-1]等价于argv[argc-1]?C代码编译运行疑问
关于
argc[argv-1]等价于argv[argc-1]及编译通过的解释 先看你贴的这段代码,核心的奇怪写法是argc[argv - 1],但实际效果和argv[argc - 1]一致,还能正常编译,这得从C语言的底层规则说起:
一、为什么argc[argv - 1]等价于argv[argc - 1]?
C语言里,数组下标运算符[]本质上是指针加法的语法糖,规则是:a[b]完全等价于*(a + b),而且加法满足交换律——a + b和b + a是同一个值,所以a[b]也等价于b[a],只要表达式的类型合法。
放到你的代码里拆解:
argv[argc - 1]展开是*(argv + (argc - 1)),这是常规写法:从argv指针(指向第一个命令行参数的指针)向后偏移argc-1个char*单位,解引用得到最后一个命令行参数。argc[argv - 1]展开是*(argc + (argv - 1)),利用加法交换律,这等价于*((argv - 1) + argc),也就是(argv - 1)[argc]。- 计算偏移量:
(argv - 1) + argc = argv + (argc - 1),和第一种情况的指针位置完全一致,解引用后自然就是同一个char*——也就是最后一个命令行参数。
说白了就是指针加法的交换律,让两种写法最终指向了同一个内存地址。
二、为什么这个表达式能通过编译?
putstr需要的参数类型是char*,我们来分析argc[argv - 1]的类型:
argv是char**类型(指向char*的指针),argv - 1还是char**类型(指向argv[0]前一个位置的指针)。- 计算
(argv - 1) + argc时,argc作为int类型会被当作指针偏移量:每个偏移单位是sizeof(char*)(即指针的大小),结果还是char**类型。 - 解引用
*( (argv - 1) + argc )后,得到的就是char*类型,正好和putstr的参数类型匹配。
需要注意的是,这种写法虽然语法合法,但属于极度晦涩的技巧,完全违背代码可读性原则,实际开发中绝对不要使用——42的piscine阶段出现这种代码,只是用来考察你对C语言指针与数组关系的底层理解。
内容的提问来源于stack exchange,提问作者Galoi5
相关产品推荐
相关产品推荐

