为什么将字符数组设置为NULL非法?传递功能改变行为

时间:2014-10-25 18:24:57

标签: c

数组的名称是数组第一个元素地址的同义词,那么为什么这个地址不能设置为NULL?它是防止内存泄漏的语言规则吗?

此外,当我们将一个数组传递给一个函数时,它的行为会发生变化,并且可以将它设置为NULL。

我不明白为什么会这样。我知道它与指针有关,但我无法绕过它。

示例:

void some_function(char string[]);
int main()
{
    char string[] = "Some string!";
    some_function(string);
    printf("%s\n", string);

    return 0 ;
}
void some_function(char string[])
{
    string = NULL;
}
  

输出:一些字符串!

我读到当一个数组传递给一个函数时,实际传递的是指向每个元素的指针,但是不知道数组本身的名称仍然是第一个地址的同义词元件?为什么在这里甚至允许将它设置为NULL,而不是在main函数中?

是否可以将数组设置为NULL?

2 个答案:

答案 0 :(得分:2)

数组不是指针 - 在您的情况下,符号string具有地址大小的属性,而指针只有地址属性。因为数组有一个地址,所以它可以转换为或解释为指针,并且语言在很多情况下都会隐式支持它。

当解释为指针时,您应该将其类型视为char* const - 即指向可变数据的常量指针,因此无法更改地址。

在将数组传递给函数的情况下,您必须了解C中的数组不是first class data types,并且它们是通过引用传递(即指针) - 丢失大小信息。传递给函数的指针是不是数组,而是指向数组的指针 - 它是独立于原始数组的变量。

您可以通过声明来说明实际发生的事情而不会增加函数调用语义的混淆:

char string[] = "Some string!";
char* pstring = string ;

然后做:

pstring = NULL ;

重要的是,原始数组数据在范围内时不能“消失”(或者根本不是静态的),数组的内容是变量,而指针是引用数据的变量。指针实现间接,而数组则不实现。将数组传递给函数时,会发生间接寻址并传递指向数组的指针,而不是数组的 copy

顺便说一下,要通过复制将数组(不是第一类数据类型)传递给函数,必须将int包装在struct(C {em>中的structs)第一类数据类型)。这主要取决于C的原始设计,在具有有限内存资源的系统的约束下,以及需要保持与早期实现和大量遗留代码的兼容性。

因此,您无法为数组指定指针这一事实并非令人惊讶的部分 - 因为这样做毫无意义。令人惊讶的可能是“传递数组”的语义以及数组不是第一类数据类型的事实;也许导致你对此事的困惑。

答案 1 :(得分:1)

您无法重新绑定数组变量。数组不是指针。确实,在低级别它们大致相似,除了指针没有关联的维度/等级信息。

您无法为实际数组(相同的范围)分配NULL,但您可以分配给参数,因为C将其视为指针。

标准说:

  

7应调整参数声明为''类型数组''   ''限定指向类型'',

因此在函数中,NULL赋值是合法的。