* arr []和** arr之间的区别

时间:2016-06-20 22:19:50

标签: c

是一样的

char* s1[size];

char** s2 = malloc(size * sizeof(char*));

它们有什么区别?

4 个答案:

答案 0 :(得分:2)

理论上,*arr[]**arr是不同的。例如:

char *arr[size]; //case 1

此处arr是一个大小为size的数组,其元素的类型为char*

然而,

char **arr; //case2

此处arr本身就是指向char*

类型的指针
  

注意:案例1 数组arr降级为指针成为char**类型,但不可能反过来ie , case 2 中的指针不能成为数组。

答案 1 :(得分:-1)

差异很小:

  • s1不是左值,因此无法修改(例如使用赋值或增量运算符)。因此,它类似于char** const s1类型,它也不允许修改(但在这种情况下,这是由const修饰符引起的。)
  • 在数组地址上使用的运算符&将返回数组的地址(即第一个元素的地址)。当&将用于变量时,它将返回其地址:

    assert((void*)&s1 == (void*)s1);
    assert((void*)&s2 != (void*)s2);
    
  • 数组上使用的
  • sizeof()将返回数组大小,而指针上使用的sizeof()将返回指针大小 - 通常它与sizeof(void*)相同,但C标准确实如此不需要这个(见下面的评论):

    assert(sizeof(s1) == size * sizeof(char*));
    assert(sizeof(s1) == size * sizeof(s1[0])); // this is the same
    assert(sizeof(s2) == sizeof(void*)); // on some platforms this may fail
    
  • 当然显而易见的一个 - s1在堆栈上分配,s2在堆上。由于此s1将在执行离开当前范围时自动销毁,s2需要调用free来释放内存。

更新:这是检查上述断言的示例代码:

#include <assert.h>
#include <stdlib.h>

int main()
{
    const int size = 22;

    char* s1[size];
    char** s2 = (char**)malloc(size * sizeof(char*));

    assert((void*)&s1 == (void*)s1);
    assert((void*)&s2 != (void*)s2);

    assert(sizeof(s1) == size * sizeof(char*));
    assert(sizeof(s1) == size * sizeof(s1[0])); // this is the same
    assert(sizeof(s2) == sizeof(void*)); // on some platforms this may fail

    free(s2);

    // Attempts to modify value
    char** const s3 = s1;
    ++s2; 
    //++s1; // compilation error - lvalue required as increment operand
    //++s3; // compilation error - increment of read-only variable ‘s3’

    return 0;
}

答案 2 :(得分:-1)

char* s1[size];

是在堆栈上分配的char类型的指针数组。

char** s2 = malloc(size * sizeof(char*));

是一个类型为char **的指针,它在堆栈上分配,但指向堆上分配的char *类型的动态指针数组。

两者在范围和数组与指针之间的通常差异方面存在差异。

答案 3 :(得分:-1)

s1是一个数组,s2是一个指针。 s2指向malloc ed数组的第一个元素。

数组s1具有自动存储持续时间,而s2指向的数组具有动态存储持续时间。

此外,在C89中char* s1[size];仅在size是常量表达式时有效,因为C89不支持可变长度数组。