如何在C中重新初始化数组?
我应该通过指针定义它:int *data[]
,还是只需编码:int data[] = {};
?
例如,我已将其定义为:
int main(void) {
int data[] = {44, 22, 1, 2, 3, 1000, 3};
现在,如何重新初始化数组data
?
答案 0 :(得分:11)
初始化仅在创建数组时出现一次:
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]
的内容,类似于如何尝试改变字符串文字的内容是未定义的(尽管我还没有找到章节和那节经文)。
答案 1 :(得分:4)
你不能重新初始化任何类型,绝对不是数组 初始化是一次性事件,当您在创建变量时为同一语句中的变量提供某些值。
如果您需要为每个人分配新值,您可以显式循环遍历数组并重新填充它
OR
使用 memset() 或 memcpy() 将所有元素设置为特定值或将特定元素复制到其中。
答案 2 :(得分:1)
初始化(如果有)必须在创建变量期间完成。因为,在编译期间,编译器会将此值分配给变量。此行之后的任何其他分配仅在运行时执行。
在您的情况下,您可以在创建阵列期间初始化阵列。下次分配某个值时,并不意味着初始化&#39 ;;相反,它只是一个运行时分配。
如果要动态创建和存储元素,则可以使用指针来执行此操作。
答案 3 :(得分:1)
我分配新值的部分解决方案(适用于 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