无效的初始值设定项是什么意思?

What does invalid initializer mean?

有这个代码:

#include <stdio.h>
#include <stdlib.h>

#define SIZE 5

int main()
{
    //int (*ar)[10] = malloc(sizeof *ar * SIZE);
    int *ar[10] = malloc(sizeof *ar * SIZE);
    printf("%ld\n", sizeof *ar);
}

我得到了

a.c:8:19: error: invalid initializer
    8 |     int *ar[10] = malloc(sizeof *ar * SIZE);
      |

为什么这个指针初始化使用“无效初始化器”?这里有什么无效的?

您声明了一个包含 10 个元素的数组,类型为 int *

int *ar[10] = malloc(sizeof *ar * SIZE);

并尝试用表达式 malloc(sizeof *ar * SIZE) 初始化数组。所以编译器发出错误信息。

如果你想动态分配一个数组 SIZE 类型的元素 char[10] 那么你需要写

int ( *ar )[10] = malloc( SIZE * sizeof( char[10] ) );

为了简化指针的声明,您可以为包含 10 个元素的数组引入 typedef 声明。例如

typedef int TArray[10];
TArray *ar = malloc( SIZE * sizeof( TArray ) );

注意需要使用转换说明符%zu输出size_t类型的对象(即运算符返回值的类型sizeof) .例如

printf("%zu\n", sizeof *ar);

此调用将输出等于 10 * sizeof( int ) 的值。如果 sizeof( int ) 等于 4 那么输出值将是 40.

int *ar[10];

是一个包含 10 个指向 int 的指针的数组。您需要一个指针(不是数组)来为 referencceod 对象动态分配内存。

根据指针的类型,您可以:

int *ar = malloc(sizeof *ar * SIZE);   // space for SZIE integers
int **ar = malloc(sizeof *ar * SIZE);  // space for SIZE pointer to integers
int (*ar)[10] = malloc(sizeof *ar * SIZE); // space for SIZE * 10 integers, but pointer type is array to 10 integers/

就像3+(4*5)完全不同于(3+4)*5,

int *(x[10]);    // int *x[10];

完全不同
int (*x)[10];

下面创建一个包含 10 个指针的数组:

int *ar[10];

数组使用 { }.[1] 进行初始化 例如,您可以使用以下内容:

int *ar[10] = {
   NULL, NULL, NULL, NULL, NULL,
   NULL, NULL, NULL, NULL, NULL
};

但在这种情况下,您可能会使用如下内容:

int *ar[10];

for (int i=10; i--; ) {
   ar[i] = malloc(sizeof(*ar));
   *(ar[i]) = 0;
}

这会产生以下结果:

                          +---------------+    sizeof( ar       ) == sizeof( int * ) * 10
ar                   +--->| 0             |    sizeof( ar[0]    ) == sizeof( int * )
+---------------+    |    +---------------+    sizeof( *(ar[0]) ) == sizeof( int   )
|             -------+
+---------------+
|             -------+
+---------------+    |    +---------------+
|               |    +--->| 0             |
       ...                +---------------+
|               |
+---------------+

下面创建一个指向 10 个指针数组的(单个)指针。

int (*p)[10];

可分配如下:

int (*p)[10] = malloc(sizeof(*p));

for (int i=10; i--; )
   (*p)[i] = 0;

这会产生以下结果:

p
+---------------+         +---------------+    sizeof( p       ) == sizeof( int * )
|             ----------->| 0             |    sizeof( *p      ) == sizeof( int * ) * 10
+---------------+         +---------------+    sizeof( (*p)[0] ) == sizeof( int   )
                          | 0             |
                          +---------------+
                          |               |
                                 ...       
                          |               |
                          +---------------+

  1. 特例,

    char s[] = "abc";
    

    是 shorthand 为

    char s[] = { 'a', 'b', 'c', 0 };
    

Why is this pointer initialization uses "invalid initializer"? What is invalid here?

int *ar[10] 没有声明指针。它声明了一个数组。数组的初始值设定项应该在大括号内,{ … },因此 malloc(sizeof *ar * SIZE) 不能有效地初始化数组。

方括号 [ … ] 比取消引用运算符 * 绑定得更紧密,因此 int *ar[10]int *(ar[10]),构成一个指针数组。要创建指向数组的指针,您必须使用 int (*ar)[10],如您的第一个声明所示。

你应该使用: 此外,您对 sizeof.

使用了错误的语法
// pointer to an array of five numbers
 int (* ar)[10] = NULL;

#include <stdio.h>
#include <stdlib.h>
#define SIZE 5

int main(){
    int *ar = malloc(sizeof(int) * SIZE);
    printf("%ld", sizeof(ar));
    return 0;
}