数组';s指数与argc符号
(5.1.2.2.1程序启动)说明: 程序启动时调用的函数 它被命名为main。[…]数组';s指数与argc符号,c,arrays,unsigned,signed,C,Arrays,Unsigned,Signed,(5.1.2.2.1程序启动)说明: 程序启动时调用的函数 它被命名为main。[…] 其应定义为 返回类型为int,不带 参数: intmain(void){/*…*/} 或具有两个参数[…]: intmain(intargc,char*argv[]){/*…*/} 后来说: argc的值应为非负 为什么不应该将argc定义为unsigned int,argc应该是“参数计数”的意思 是否应将argc用作argv的索引 所以我开始怀疑C标准是否说明了数组索引的类型。签字了吗 6.5.2.1
其应定义为 返回类型为int,不带 参数:
intmain(void){/*…*/}
或具有两个参数[…]:intmain(intargc,char*argv[]){/*…*/}
后来说:
argc的值应为非负
- 为什么不应该将
定义为argc
,unsigned int
应该是“参数计数”的意思argc
- 是否应将
用作argc
的索引argv
array[-1]
)的代码非常常见,但这不是未定义的行为吗
- 数组的索引应该是无符号的吗
char array[100];
char *p;
p = &array[50];
p += -30; /* Now p points to array[20]. */
指针算法的这种用法是合法的,因为生成的指针仍然保留在原始内存对象(“数组”)中。在大多数系统上,指针算法可用于违反此规则在内存中导航,但这是不可移植的,因为它完全依赖于系统。1)Argc是一个参数计数,但老实说,您如何在程序名前面加上一个参数,即argv[0]
。设想一个名为foo
的程序,你不能简单地说args1 foo args2
,因为这是没有意义的,尽管argc
是int
的有符号类型,也就是说,没有argv[-1]
这样的东西会让你得到“args1”
2) 原因argc实际上不是参数向量的索引(因此“argv”),因为运行时将可执行程序名填充到第0个偏移量,即argv[0]
,因此argc
将关闭1
3) 数组索引,就指针操作而言,前提是您位于指针所在内存块的边界内,使用数组下标作为负数是合法的,因为数组下标是指针的快捷方式,而且不仅仅是它们是可交换的,例如
char v[100];
char *p = &v[0];
You can do this:
p[55] = 'a';
Which is the same as
*(p + 55) = 'a';
You can even do this:
p = &v[55];
p[-10] = 'b' /* This will stuff 'b' into 45'th offset! */
Which is the same as
*(p - 10) = 'b';
charv[100];
char*p=&v[0];
您可以这样做:
p[55]=“a”;
这和
*(p+55)=“a”;
您甚至可以这样做:
p=&v[55];
p[-10]='b'/*这将把'b'填充到第45个偏移量*/
这和
*(p-10)=“b”;
此外,如果您以超出边界的方式使用和操作数组,则这是未定义的行为,并且将取决于运行时的实现,取决于如何处理它,可能是分段错误或程序崩溃
4) 在*nix环境中,有些环境会将第三个参数提供给mainchar**endvp
,这在Microsoft的DOS/Windows环境中也很少使用。一些*nix运行时实现,出于历史前的原因,您可以通过运行时传入环境变量。一般来说,在C语言中,“最小意外原则”意味着最好对变量进行签名,除非有很好的理由将其取消签名。这是因为在混合使用有符号和无符号值时,类型提升规则可能会导致意外结果:例如,如果argc
为无符号,则此简单比较将导致意外结果:
if (argc > -1)
(将
-1
提升为unsigned int
,因此它的值被转换为UINT\u MAX
,这几乎肯定大于argc
)。只要声明它为unsigned,就不会发生什么坏事。它实际上是用3个参数调用的,你可以添加char*env[]。@nobugz,是的,我知道不会发生什么坏事,我只是想知道为什么argc
是按照标准签名的char*envp[]
依赖于平台,而char*apple[]
在MacOSX/Darwin上。这个问题是@caf的翻版,哇,你是怎么发现的?我花了大约20分钟来寻找一些关于它的话题。谢谢你的链接。抱歉重复。tusbar:我知道我曾经看过它,这可能会有所帮助-我想我只是在搜索框中插入了“argc unsigned”。1)我问为什么argc
在标准中没有未签名,而不是我是否可以使用负索引。2) 我的第二个问题是argc
的符号性与数组索引(aka operator[]的参数)的符号性之间的关系。4) 我知道,但标准中没有写。这是一个有趣的解释方式。