C中的数组和指针之间有什么区别?

这个问题可能听起来很愚蠢,但我并不确定。 我的意思是,有什么区别:

char* line = (char*) malloc(MAX_LINE_LEN);

char line[MAX_LINE_LEN];

究竟? 我知道前者是一个指针,后者是一个数组,但系统如何区分这个差异? 如何分配/存储内存?

另外,为什么当它被声明为一个指针时删除line占用的内存,而不是当它是一个数组? 我认为一个数组存储在其他地方,当超出范围时,系统会自动释放它的内存,这在处理指针时不会发生,因此您必须自己删除它。 我错了吗?


char* line = (char*) malloc(MAX_LINE_LEN);

这是不好的风格; 你不需要在C中投入malloc 。让我们把它分成两部分,因为它更容易描述和比较:

char *line; 声明一个指向char命名line的指针。 你可以指定它指向一个对象(或没有)。 所述sizeof一个目的是它的类型的大小,所以sizeof (line)sizeof (char *)它从系统而异,。 &line是一个char *的地址,它的类型是char ** (指向char的指针)。 它的存储时间取决于它的声明位置:

  • 如果它在任何函数之外声明,则它具有静态存储持续时间,该持续时间持续该程序的生命周期。 静态存储持续时间的对象被初始化为0 ,除非存在明确的初始化(例如在你的情况下)。 0是一个null pointer constant ,表明如果在没有初始化函数的情况下在函数之外声明该对象将指向任何内容。

  • 如果它是在一段代码中声明的,则它具有自动存储持续时间,该持续时间持续到执行到达该代码块的末尾。 具有自动存储持续时间的对象在使用之前必须显式初始化或分配给它们,因为它们的值在其他情况下是不确定的。

  • 你的初始化为它分配一个值,所以它不会从不确定开始。 malloc返回一个指向具有动态存储持续时间的对象的指针,这意味着指针指向的对象会一直存在,直到它明确free为止d。

    想想这line就像邮件信封上的邮政编码; 你可以在那里写一些东西,这些东西会指出你可以找到对象(和人)的位置。 邮编不会告诉你任何有关对象(或人物)的大小。


    char line[MAX_LINE_LEN];
    

    这声明了一个MAX_LINE_LEN字符数组。

  • 如果在任何函数之外声明,则它具有静态存储持续时间,并且整个数组都是零填充的。

  • 如果在函数或代码块中声明,它具有自动存储持续时间,并且数组中的值是不确定的; 它们需要被初始化(例如char line[MAX_LINE_SIZE] = { 0 };将初始化它们)或赋值给它们(例如line[0] = '';将分配给数组的第一个元素) '使用了。

  • 该类型为char[MAX_LINE_SIZE] ,因此大小将为sizeof (char[MAX_LINE_SIZE]) ,如您所看到的指定元素数量所示。 在这种情况下, &line的地址是一个char (*)[MAX_LINE_SIZE] (一个指向MAX_LINE_SIZE字符数组的指针)。

    这个不能像上面那样重新分配,所以它不同于我们的邮编示例。 在编译器需要指针的地方使用数组时,数组将隐式转换为指向第一个元素的指针。 例如,让我们考虑一下:

    strcpy(line, "Hello, world!");
    

    函数原型char *strcpy(char *restrict s1, const char *restrict s2); ,告诉我们strcpy接受两个char * (指向char的参数)参数。 在这个例子中,其中一个参数是char[MAX_LINE_LEN] ,另一个是char[14] 。 两者都转换为char *

    这个数组到指针的转换解释了为什么char *line; line = "hello"; char *line; line = "hello"; 是有效的,而char line[MAX_LINE_LEN]; line = "hello"; char line[MAX_LINE_LEN]; line = "hello"; 不是。 您不能更改转换所产生的指针。

    我知道前者是一个指针,后者是一个数组,但系统如何区分这个差异?

    如前所述,数组表达式在指针所在的地方使用时会转换为指针表达式。 例如, array中的array[x]被转换成pointerpointer[x] 你在问什么? 为什么它需要知道数组和指针之间的区别?

    我认为一个数组存储在其他地方,当超出作用域时,系统会自动释放它的内存,

    是。 我较早解释了不同的存储时间。

    当你处理指针时不会发生这种情况,所以你必须自己删除它。 我错了吗?

    是。 您将指针的概念与存储时间的概念混淆在一起。 int *p = malloc(sizeof *p); p被初始化为指向一个具有动态存储持续时间的int 。 这个int直到free(p);才会被销毁free(p); 叫做。 但是,下面的两个变量都具有自动存储持续时间,因为它们在main声明,没有任何限定符(如staticp指向i ; p是一个指针。 不要free p,因为它不指向具有动态存储持续时间的对象。 free只定义为销毁具有动态存储持续时间的对象。

    int main(void) {
        int i = 42;
        int *p = &i;
    }
    

    char* line;
    

    在堆栈上分配指针。 当程序计数器超出本声明的范围时,它将被自动释放。

    line = (char*) malloc(MAX_LINE_LEN);
    

    在堆上动态分配MAX_LINE_LEN个字节。 确切地说,你应该以这种方式使用malloc

    line = malloc(MAX_LINE_LEN * sizeof(char));
    

    稍后,您应该free(line)释放此堆内存。

    sizeof(line)将返回指针所占用的字节数(通常为4或8字节)。


    char line[MAX_LINE_LEN];
    

    在堆栈中分配MAX_LINE_LEN字符。 当程序计数器超出本声明的范围时,它将被自动释放。

    sizoef(line)将返回MAX_LINE_LEN * sizeof(char)个字节。


    理解这个最好的资源可能是comp.lang.c常见问题解答。

    实际上,差异在于sizeof运算符的效果。 sizeof(pointer)给你一个指针的大小,而sizeof(array)给你......你猜对了。

    当作为函数参数传递时,数组名会衰减为指向第一个元素的指针(丢失信息的sizeof )。 在一个正常表达式中,它的行为就好像它衰减为一个指针,因为数组语法是用等价的指针操作来定义的。 (实际上早期的C编译器声明了带有identifier[]指针identifier[]

    A[X]
    

    根据定义,它完全等同于

    *(A + X)
    

    注意在A[X]恰好是AX (任一)中的一个必须是指针或数组。

    链接地址: http://www.djcxy.com/p/79793.html

    上一篇: What's the difference between an array and a pointer in C exactly?

    下一篇: Firefox Add