arrays - char **s vs char *s[] 初始化
问题描述
我正在努力理解char *s[]
和char s**
初始化之间的区别。我的char *s[]
工作正常,而我的char s1**
抛出错误[Error] scalar object 's1' requires one element in initializer。我不明白那个错误的含义。
我们怎样才能char s1**
正确初始化?
#include<stdio.h>
int main(void)
{
char *s[]={"APPLE","ORANGE"};
char **s1={"APPLE","ORANGE"};
return 0;
}
解决方案
TLDR char **s1=(char*[]){"apple","orange"};
:。
当然,您可以使用数组中元素的地址来初始化指针。这在更简单的数据类型中更常见:假设int arr[] = {1,2};
你可以说int *p = &arr[0];
; 一个我讨厌的符号,在这里只是为了说明我们在做什么。由于数组无论如何都会衰减为指向其第一个元素的指针,因此您可以更简单地编写int *p = arr;
. 请注意指针的类型是“指向元素类型的指针”。
现在您的数组s
包含“指向字符的指针”类型的元素。你可以做和以前一样的事情。元素类型是指向 char 的指针,因此指针类型必须是指向它的指针,指向指向 char 的指针,正如您正确编写的那样:
char **s2= &s[0];
,或者更简单char **s2= s;
。
现在这有点毫无意义,因为您s
已经并且不再需要指针了。你想要的是一个“数组文字”。C99 引入了一个符号,该符号在元素列表前面加上一种类型转换。使用一个简单的整数数组,它看起来像这样int *p = (int []){1, 2};
:使用您的 char 指针,它看起来像这样:
char **s1=(char*[]){"apple","orange"};
.
警告:虽然字符串文字具有静态存储持续时间(即,指向它们的指针在程序结束之前保持有效),但由文字创建的数组对象却没有:它的生命周期以封闭块结束。如果封闭块是main
这里的函数,那可能没问题,但是您不能,例如,在“初始化”例程中初始化一堆指针并稍后使用它们。
警告 2:最好将数组和指针声明为指向 const char,因为字符串文字通常在现代系统上不可写。您的代码仅出于历史原因编译;禁止char *s = "this is constant";
会破坏太多现有的代码。(C++确实禁止,这样的代码不能编译成C++。但是在这种特殊情况下,C++没有这种复合字面量的概念,下面的程序是无效的C++。)我在下面的完整程序演示了复合文字的使用。您甚至可以获取它的地址,就像任何其他数组一样!
#include<stdio.h>
int main(void)
{
/// array of pointers to char.
const char *arrOfCharPtrs[2]={"APPLE","ORANGE"};
/// pointer to first element in array
const char **ptrToArrElem= &arrOfCharPtrs[0];
/// pointer to element in array literal
const char **ptrToArrLiteralElem=(const char*[]){"apple","orange"};
/// pointer to entire array.
/// Yes, you can take the address of the entire array!
const char *(*ptrToArr)[2] = &arrOfCharPtrs;
/// pointer to entire array literal. Note the parentheses around
/// (*ptrToArrLiteral)- Yes, you can take the address of an array literal!
const char *(*ptrToArrLiteral)[2] = &(const char *[]){"apples", "pears"};
printf("%s, %s\n", ptrToArrElem[0], ptrToArrElem[1]);
printf("%s, %s\n", ptrToArrLiteralElem[0], ptrToArrLiteralElem[1]);
printf("%s, %s\n", (*ptrToArr)[0], (*ptrToArr)[1]);
// In order to access elements in an array pointed to by ptrToArrLiteral,
// you have to dereference the pointer first, yielding the array object,
// which then can be indexed. Note the parentheses around (*ptrToArrLiteral)
// which force dereferencing *before* indexing, here and in the declaration.
printf("%s, %s\n", (*ptrToArrLiteral)[0], (*ptrToArrLiteral)[1]);
return 0;
}
示例会话:
$ gcc -Wall -pedantic -o array-literal array-literal.c && ./array-literal
APPLE, ORANGE
apple, orange
APPLE, ORANGE
apples, pears
推荐阅读
- python - python 2.7.15中的反向三角形
- html - HTML5 总是显示视频控制面板
- javascript - 如何使用 html 视频标签在 react.js 中播放视频?
- c# - SmtpClient - 附件偶尔为 0 字节
- plc - IEC-61131 结构化文本是否允许比较布尔操作数?
- google-apps-script - “全局变量”的替代品
- c# - C#如何全局发送热键(需要后台进程,在系统托盘中运行)
- ffmpeg - 如何使用“ffprobe”命令检查直播是否还活着?
- android - 2个RecyclerViews之间的Android共享元素转换
- jquery - 管理菜单中的错误在第一次单击时未打开