繁体   English   中英

如果 C 只能返回一个值(int、char 等),那么它如何返回字符串文字(字符数组)?

[英]If C can return only one value(int , char etc.) then how does it returns character string literal(array of chars)?

char *returnString()
{
    return "hello World";
}

int main()
{
    printf("\n %p ", &returnString());
    return 0;
}

returnString()在这里返回什么? 它是否返回'h'地址?
如果是,那么"hello world"存储在哪里(堆栈/堆)? 如何查看(打印)它的地址?

char Hello[] = "It's Hello";

char something[] = "something like ";

char *readInput(char str[]) {
    char *tempStr = NULL;
    if (strcmp(str, "hello") == 0)
        return Hello;

    tempStr = (char *)malloc((strlen(something)) + (strlen(str)) + 1);

    strcpy(tempStr, something);
    strcat(tempStr, str);

    return tempStr;
}

int main() {
    int i;
    char *userInput[] = { "hello", "xyz", "hello",  "abc" };
    char **result = (char **)malloc(sizeof(char *) * (4));

    for (i = 0; i < 4; i++) {
        result[i] = (char *)malloc(15);

        result[i] = readInput(userInput[i]);
    }
    printf("\n\n");

    strcpy(Hello, "String is Changed"); // this should not affect result[0] && result[2]

    for (i = 0; i < 4; i++)
        printf("\t\t %s", result[i]);

    printf("\n");
    return 0;
}

应该在第二个程序中进行哪些修改,以便即使在此之后 ---> strcpy(Hello, "String is Changed"); result[0]result[2]不会改变。

语句return "hello World"; 返回一个char * :指向字符串文字"hello World"的第一个字符的指针。 此字符串文字存储为 12 个char的空终止数组。 它通常与程序的其他常量数据一起存储在内存中。

尝试修改此数组会调用未定义的行为。 它应该被视为const并通过const char *处理。 将此函数定义为更安全

const char *returnString(void) {
    return "hello World";
}

此外,您不应在printf语句中的函数调用上使用& 它应该是:

int main(void) {
    printf("\n%p\n", (void*)returnString());
    return 0;
}

关于您的第二个问题,您应该在Hello返回字符串的副本。 使用这个简单的方法:

if (strcmp(str, "hello") == 0)
    return strdup(Hello);

strdup()未在 C 标准中定义,但在 Posix 标准中指定。 如果它在您的系统中不可用,则可以将其定义为:

char *strdup(const char *s) {
    char *p = malloc(strlen(s) + 1);
    if (p) strcpy(p, s);
    return p;
}

分配字符串的位置取决于您如何编写它。 这些都返回字符串,但方式不同:

const char *a()
{
    return "hello, world";
}

char *b()
{
    return strdup("hello, world");
}

char *c()
{
    char buf[16];
    strcpy(buf, "hello, world");
    return buf; /* wrong */
}

char *d()
{
    static char buf[16];
    strcpy(buf, "hello, world");
    return buf;
}

void e(char *buf)
{
    strcpy(buf, "hello, world");
}

a返回一个字符串文字。 它存储在只读存储器中,不能更改。

b返回分配在堆上的字符串。 必须通过调用free来释放它。

c返回分配在堆栈上的字符串。 但是,这是错误的,因为您不能返回指向局部变量的指针,在本例中为buf 当到达右括号时,被引用的对象不再存在。

d提供了对c的改进。 当变量声明为static ,它(在许多编译器上)存储在.bss段中。 然而,这不是更正,因为它不是线程安全的。

e不是通过返回机制返回一个字符串,而是通过填写一个地址。 不推荐使用此代码,因为可能会发生缓冲区溢出。 调用者可以在堆栈或堆上分配e的参数。 只要有足够的空间来执行复制,它就会工作。

e改进版本:

/* n is the size of buf, in chars */
void eImproved(char *buf, size_t n)
{
    if (n > sizeof "hello, world") /* enough room in buf for copy */
        strcpy(buf, "hello, world");
    else
        buf[0] = '\0';             /* if not enough room, make buf empty */
}

如果要打印地址,请在 printf 中使用%p

printf("%p", a());

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM