从字符串构建字符数组(C)

从字符串构建字符数组(C),c,arrays,function,pointers,types,C,Arrays,Function,Pointers,Types,我正在用C编写一个简单的函数,它应该从字符串“abc”构建一个字符数组——因此它应该构建{'a'、'b'、'C'}——并返回指向该数组的指针。以下是我的此函数代码: char * makeArr() { static char arr[3]; sprintf(arr, "%s\n", "abc"); return arr; } 在main中调用此方法时出现问题: int main(int argc, char *argv[]) { char *arr[3];

我正在用C编写一个简单的函数,它应该从字符串“abc”构建一个字符数组——因此它应该构建{'a'、'b'、'C'}——并返回指向该数组的指针。以下是我的此函数代码:

char * makeArr()
{
    static char arr[3];

    sprintf(arr, "%s\n", "abc");

    return arr;
}
在main中调用此方法时出现问题:

int main(int argc, char *argv[])
{
    char *arr[3];

    arr = makeArr();

    return 0;
}

编译器正在抱怨类型转换/冲突。我已经玩了很长一段时间的指针,投法和去参考,但似乎无法让它发挥作用。请让我知道我的逻辑哪里错了。

除此之外,你还弄糊涂了:

char-arr[3];//3个字符的数组。

以及

char*arr[3];//指向字符的3个指针数组。


在main()中,您应该只写
char*arr

除此之外,您还混淆了:

char-arr[3];//3个字符的数组。

以及

char*arr[3];//指向字符的3个指针数组。


在main()中,您应该只写
char*arr

首先,
字符arr[3]太小,无法存储
“abc\n”
。它必须至少有5个元素,包括终止空字符

然后,
char*arr[3]
是一个由
char*
组成的三元素数组
您应该将
makeArr()
的返回值(它具有
char*
类型)分配给
arr[0]
或其他元素,或者您应该将
main
函数中的
arr
的类型更改为
char*
,该类型与
makeArr()
的返回值的类型相同

此外,此
makeArr()
不生成任何数组,并返回(指向)现有数组的指针。您应该使用
malloc()
来“创建数组”

更新:

char*
的值赋值给数组
char arr[10]在C中似乎无效。

您应该使用
strcpy()
strncpy()
(比
strcpy()
更安全)在数组之间复制存储在数组中的字符串。

首先,
字符arr[3]太小,无法存储
“abc\n”
。它必须至少有5个元素,包括终止空字符

然后,
char*arr[3]
是一个由
char*
组成的三元素数组
您应该将
makeArr()
的返回值(它具有
char*
类型)分配给
arr[0]
或其他元素,或者您应该将
main
函数中的
arr
的类型更改为
char*
,该类型与
makeArr()
的返回值的类型相同

此外,此
makeArr()
不生成任何数组,并返回(指向)现有数组的指针。您应该使用
malloc()
来“创建数组”

更新:

char*
的值赋值给数组
char arr[10]在C中似乎无效。
您应该使用
strcpy()
strncpy()
(比
strcpy()
更安全)在数组之间复制存储在数组中的字符串。

Hmm。。。这段代码中有几个错误。让我们从编译器抱怨的最明显的问题开始:

char *arr[3];
此行将
arr
声明为指向
char
的三个指针的数组。从函数返回的是指向
字符的单个指针
->不匹配

下一步:

在这里您可以保留3个
char
s。
sprintf()
将写入5个
char
s<代码>%s
替换为字符串文字中的3个字符
“abc”
。添加一个换行符,然后添加一个
0
,作为“字符串”结尾的标记。等于5。顺便说一句,这是未定义的行为。写入超过数组末尾。这样的代码是可以编译的,但对于运行时会发生什么,根本无法保证


在这里做一个切口。你应该阅读C语言中的数组和指针。如果你正在阅读的文本声称它们是相同的。。。停在那里,找一个更好的文本。他们不是

我会在这里简单地解释一下,所以它适合问答风格

C中的数组实际上是几个值的连续空间
char-arr[3]
表示包含3
char
s的变量

另一方面,
char*
只是指向
char
的指针——这可能是数组的第一个元素

在C语言中,不能将数组作为函数参数传递,也不能从函数返回数组。尝试这样做会导致隐式转换:实际传递的是指向该数组第一个元素的指针

我认为缺少的最后一点信息是C中字符串文字的含义:它是一个数组(匿名,例如,它没有名称),包含双引号中的所有字符加上附加的
0
0
标记C中“字符串”的结尾

在表达式中,字符串文字的计算结果是指向第一个元素的指针

比如说:

char *foo = "bar";
#include <stdio.h>
char * makeArr(char *arr)
{
    sprintf(arr, "%s\n", "abc");
    return arr;
}

int main(int argc, char *argv[])
{
    char arr[10];

    makeArr(arr);
    printf("%s\n", arr);
    return 0;
}
将导致
foo
指向数组的
b
。就像写作一样

static const char no_name_0[] = { 'b', 'a', 'r', 0 };
char *foo = &(no_name_0[0]);
嗯。。。这段代码中有几个错误。让我们从编译器抱怨的最明显的问题开始:

char *arr[3];
此行将
arr
声明为指向
char
的三个指针的数组。从函数返回的是指向
字符的单个指针
->不匹配

下一步:

在这里您可以保留3个
char
s。
sprintf()
将写入5个
char
s<代码>%s
替换为字符串文字中的3个字符
“abc”
。添加一个换行符,然后添加一个
0
,作为“字符串”结尾的标记。等于5。顺便说一句,这是未定义的行为。写入超过数组末尾。这样的代码是可以编译的,但对于运行时会发生什么,根本无法保证


在这里做一个切口。你应该
int main(int argc, char *argv[]) {
  char arr[10];
  makeArr(arr);
  return 0;
}
#include <stdio.h>
char * makeArr(char *arr)
{
    sprintf(arr, "%s\n", "abc");
    return arr;
}

int main(int argc, char *argv[])
{
    char arr[10];

    makeArr(arr);
    printf("%s\n", arr);
    return 0;
}