Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
数组';s指数与argc符号_C_Arrays_Unsigned_Signed - Fatal编程技术网

数组';s指数与argc符号

数组';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

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阵列订阅

其中一个表达式应具有类型 “指向对象类型的指针”,另一个 表达式应具有整数类型
, 并且结果的类型为“type”

它没有说明它的标志性(或者我没有发现)。使用否定数组索引(
array[-1]
)的代码非常常见,但这不是未定义的行为吗

  • 数组的索引应该是无符号的吗

main()中使用int的原因是历史性的——它一直都是这样,很久以前这种语言就已经标准化了。数组索引的要求是它在数组的范围内(或者在某些情况下,超过了数组的末尾)-其他任何内容都是未定义的,因此符号性是无关紧要的。

1)关于main()argc type:IMHO该标准延续了一个非常古老的传统(超过30年!),现在。。。现在改变一切已经太晚了(注意:在大多数系统上,如果“argc”定义为“unsigned”,编译器、链接器和CPU都不会抱怨,但您超出了标准!)

2) 在大多数实现中,argv[argc]是合法的,计算结果为NULL。实际上,找到参数列表结尾的另一种方法是从0开始迭代argv,并在argv[i]为NULL时终止

3) 只要从(p-n)到p的地址范围属于同一内存对象,带负数的数组/指针算法是合法的。也就是说,你可以

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环境中,有些环境会将第三个参数提供给main
char**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) 我知道,但标准中没有写。这是一个有趣的解释方式。