[英]ANSI C - initializing an array
我一直在做的是:
int arr[] = {2, 3, 4};
并且一直有效。
我听说过使用指针初始化新数组的更好方法:
int *arr = {2, 3, 4};
但是,它在任何IDE中均不起作用,它会引发一些错误,例如int differs in levels of indirection from int
,或者too many initializers
。 我应该怎么做?
int arr[] = {2, 3, 4};
很好,而且完全正确。 无需更改。
在gcc上,该初始化似乎对我有用,但不正确。
int *arr = {2, 3, 4}; //weird behaviour, stores first value `2` as read-only
int arr[] = {2, 3, 4}; //array decl
前者不是初始化数组的正确方法。
对于char * ,这更有意义
char* arr = "abcde"; //Pointer to a read-only char array in memory
char[] arr = "abcde"; //Normal char array
区别:
前者被写入到程序集的Rodata (常量,只读数据)部分,而后者则位于读/写Data-Segment中 。 尝试更改前者可能会导致segmentation-fault 。
值的存储位置不同。
char* arr = "abcde";
arr[1] = 'f'; //(undefined behavior)
char[] arr2 = "abcde";
arr2[1] = 'f'; //no issue
如果要“初始化数组”,则必须初始化一个数组 ,而不是一个指针。
无论如何,在C99中可以使用复合文字,并且可以将指针初始化为
int *arr = (int []) {2, 3, 4};
这与您尝试执行的操作很接近。 尽管术语“ ANSI C”通常用于指代C89 / 90,但该功能不可用。
这种方法没有“更好”的选择。 它只是给您一个指针而不是一个数组,因此这实际上是您需要什么的问题。
为什么第二个版本会比第一个版本好?
至少第一个版本是显式的:您使用给定的元素定义一个int数组。 让编译器确定如何最佳地执行此操作。
从您的评论转到Evan Li(“字符串也是一种数组,并且使用指针对其进行了初始化。因此,数组也应以这种方式进行初始化。”)。 如果讲师确实告诉过您,我会认真考虑寻找新的讲师,因为他对事情感到困惑。
字符串文字是数组表达式。 文字“ Hello”是char
的6个元素的数组(在C ++中为const char
)。 字符串文字的存储方式是在程序的生命周期内分配它们的内存。 该内存可能是只读的,也可能不是只读的,具体取决于平台。 尝试修改字符串文字内容的行为是未定义的 ,这意味着您可能会遇到段错误,或者可能会修改字符串,或者发生其他情况。
当数组表达式出现在上下文中而不是作为sizeof
或一元&
运算符的操作数时,或者在声明中使用字符串常量来初始化另一个数组时,表达式的类型将被转换(“ decays”) “ T
N个元素数组”到“指向T
指针”,表达式的值是数组的第一个元素的地址。
这就是为什么你可以写像
char *foo = "This is a test";
字符串文字"This is a test"
是类型为“ 15个元素的char
数组"This is a test"
的数组表达式; 因为它不是sizeof
或&
运算符的操作数,并且不用于初始化另一个char
数组,所以表达式的类型变为“ char
指针”,并且第一个字符的地址分配给foo
。 通过对比,
char foo[] = "This is a test";
将foo
声明为char
数组 ; 从初始化程序字符串的大小(15个字符)计算出大小,并将字符串文字的内容复制到foo
。
字符串是数组表达式; 大括号括起来的值列表不是 。
int *foo = {1, 2, 3};
不会创建一个3元素的int
数组,并将第一个元素的地址分配给foo
; 相反,如果我正在阅读此权限,则应该违反约束:
6.7.9初始化
约束条件
2初始化程序不得尝试为未包含在正在初始化的实体内的对象提供值。
从C99开始,您可以使用所谓的复合文字 ,如下所示:
int *foo = (int []) {1, 2, 3};
强制转换表达式(int [])
是必需的。 这确实创建了一个新的3元素int
数组,并将第一个元素的地址分配给foo
。 与字符串文字不同,此类复合文字仅在封闭块1的持续时间内存在; IOW,如果您做了类似的事情
int *foo = NULL;
if (condition())
{
foo = (int []){1, 2, 3};
// do stuff
}
// do more stuff
foo
指向的匿名数组对象仅存在于if
块中; 一旦if
块退出,该数组将不再存在,并且foo
的值不再有效。
static
持续时间,并且在程序的生存期内存在。
int arr [] = {2,3,4}; 还可以
如果要使用指针,则必须使用例如malloc分配内存。 像这样:
int *arr = malloc(sizeof(int)*4);
arr[0]=1;
arr[1]=2;
arr[2]=3;
arr[3]=4;
//display
printf("%d %d %d %d\n",arr[0],arr[1],arr[2],arr[3]);
free(arr);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.