如何在 C 中重新初始化数组?
我应该通过指针定义它:int *data[]
还是我可以只编码:int data[] = {};
?
例如,我将其定义为:
int main(void) {
int data[] = {44, 22, 1, 2, 3, 1000, 3};
现在,如何重新初始化数组data
?
如何在 C 中重新初始化数组?
我应该通过指针定义它:int *data[]
还是我可以只编码:int data[] = {};
?
例如,我将其定义为:
int main(void) {
int data[] = {44, 22, 1, 2, 3, 1000, 3};
现在,如何重新初始化数组data
?
初始化只发生一次,当您创建数组时:
int foo[] = {0,1,2,3,4}; // creates a 5-element array of int and
// initializes it
定义数组后,您可以分配给单个元素:
foo[0] = 5;
foo[1] = 4;
foo[2] = 3;
foo[3] = 2;
foo[4] = 1;
但是您不能分配给数组本身;IOW,你不能写类似的东西
foo = {5,4,3,2,1};
但是,您可以使用将一个数组的内容memcpy
复制到另一个数组:
int foo[5];
int bar[5] = {1,2,3,4,5};
int i;
memcpy(foo, bar, sizeof bar); // Copies *contents* of bar to foo
for (i = 0; i < sizeof foo / sizeof *foo; i++)
printf("foo[%d] = %d\n", i, foo[i]);
同样,以这种方式创建的数组也无法调整大小;它的大小在声明时是固定的。在 C89 及更早版本中,必须在编译时知道数组大小 - 通过使用编译时常量(整数表达式或扩展为整数表达式的宏)指定大小或使用上述初始化器,从中计算数组大小。
C99 引入了可变长度数组,可以使用运行时值来声明,例如:
void foo(int x)
{
int arr[x];
...
}
请注意,与常规数组一样,VLA 在定义后无法调整大小。
或者,您可以使用 动态分配数组malloc
,尽管您不能以上述方式对其进行初始化:
int *foo = malloc(sizeof *foo * N); // where N is the number of elements
您仍然可以分配给单个元素:
foo[0] = 5;
foo[1] = 4;
foo[2] = 3;
...
或者您可以使用memcpy
如上所示。请注意,free
完成后您必须记住数组:
free(foo);
以这种方式创建的数组可以调整大小,使用realloc
:
int *tmp = realloc(foo, sizeof *foo * NEW_NUMBER_OF_ELEMENTS);
if (tmp)
foo = tmp;
为什么不将realloc
返回的结果分配给foo
?如果realloc
操作失败,它将返回 NULL。如果发生这种情况并且我们将结果分配回foo
,我们就会丢失我们已经分配的内存,从而导致内存泄漏。
C99 引入了数组字面量语法;你可以写类似
int *foo = (int[]){1,2,3,4,5};
然后foo
像数组一样索引:
printf("foo[%d] = %d\n", i, foo[i]);
虽然我很确定你不能改变 的内容foo[i]
,类似于试图改变字符串文字的内容是未定义的(尽管我还没有找到关于它的章节和经文)。
必须在创建变量期间进行初始化(如果有)。因为,在编译期间,编译器会将这个值赋给变量。此行之后的任何其他分配仅在运行时执行。
在您的情况下,您可以在创建数组期间对其进行初始化。下次您分配某个值并不意味着“初始化”;相反,它只是一个运行时分配。
如果要动态创建和存储元素,则可以使用指针来执行此操作。
我分配新值的部分解决方案(在gcc中使用c99 -syntax 工作):
#define arr_set(type, arr, ...) { \
int arr_size = sizeof((type[]){__VA_ARGS__}) / sizeof(type); \
type *parr = (type[]){__VA_ARGS__}; \
for (int i = 0; i < arr_size; i++) \
arr[i] = *parr++; }
它不安全(没有边界检查),只覆盖从头开始的连续成员,但我发现它有时很有用。
完整示例:
#include <stdio.h>
#define arr_set(type, arr, ...) { \
int arr_size = sizeof((type[]){__VA_ARGS__}) / sizeof(type); \
type *parr = (type[]){__VA_ARGS__}; \
for (int i = 0; i < arr_size; i++) \
arr[i] = *parr++; }
#define print_buf_int(buf) { \
for (int i = 0; i < sizeof(buf)/sizeof(buf[0]); i++) \
printf("%d ", (int)buf[i]); \
printf("\n"); }
#define print_buf_char(buf) { \
for (int i = 0; i < sizeof(buf)/sizeof(buf[0]); i++) \
if (buf[i]) \
printf("%c ", (char)buf[i]); \
else \
printf("null "); \
printf("\n"); }
#define print_buf_str(buf) { \
for (int i = 0; i < sizeof(buf)/sizeof(buf[0]); i++) \
printf("%s ", (char*)buf[i]); \
printf("\n"); }
int main()
{
int brr[8] = {};
int arr[8] = {3, 4, 5, 1, 0, 2};
print_buf_int(arr);
arr_set(int, arr, 9, 8 ,7);
print_buf_int(arr);
arr_set(int, arr, 0, 1, 2, 3, 4, 5, 6, 7);
print_buf_int(arr);
arr_set(int, arr, 11, 22, 33, 44, 55, 66, 77, 88, 99); // 'brr' gets overwritten!!!
print_buf_int(arr);
print_buf_int(brr);
unsigned char crr[13] = {'a', 'b', 'c', [12] = 'z'};
print_buf_char(crr);
arr_set(char, crr, 'd', 'e', 'f', '1', '2', '3');
print_buf_char(crr);
unsigned short srr[] = {111, 222, 333, 444, 555};
print_buf_int(srr);
arr_set(unsigned short, srr, -1, 0, 666);
print_buf_int(srr);
char *prr[] = {"hello", "variadic", "world"};
print_buf_str(prr);
arr_set(char*, prr, "good", "bye");
print_buf_str(prr);
}
输出:
3 4 5 1 0 2 0 0
9 8 7 1 0 2 0 0
0 1 2 3 4 5 6 7
11 22 33 44 55 66 77 88
99 0 0 0 0 0 0 0
a b c null null null null null null null null null z
d e f 1 2 3 null null null null null null z
111 222 333 444 555
65535 0 666 444 555
hello variadic world
good bye world