通过函数传递字符串。 C

时间:2016-07-10 08:08:10

标签: c arrays string function

void printInstructions();
char *getUserWord();


int main()
{
    printInstructions();
    char *baseWord = getUserWord();
    printf("%s", baseWord);
    return 0;
}


void printInstructions()
{
    printf("                      Instructions:                        \n"
   "===================================================================\n"
   "= This program is a hangman game.                                 =\n"
   "= The first user will enter the name to be guessed                =\n"
   "= After that, the second user will guess the letters of the word  =\n"
   "= the second user will loose if they have three strikes           =\n"
   "===================================================================\n");
   return;
}


char *getUserWord()
{
    static char str[20];
    scanf("%s", str);
    return str;
}

我的函数getUserWord通过传递字符串来完成其任务。从我在线阅读char *baseWord = getUserWord();是将字符串分配给主函数中的变量的唯一方法。我不知道为什么这有效,我甚至不确定这在记忆中是做什么的。以下是对我有意义的事情。为什么这不起作用?

 char baseWord[21];
 baseWord = getUserWord();

4 个答案:

答案 0 :(得分:5)

你已经陷入了相信指针和数组是同一个东西的陷阱。他们不是。

按照惯例,字符串中的字符串通常表示为char的数组,末尾附加了'\0'的附加终结符(所谓的空字符)。因此,字符串文字"AB"表示为三个char的数组,其值为'A''B''\0'

指针与数组完全不同,因为字符串是使用char数组表示的,所以指针和字符串是完全不同的东西。指针是一个包含内存中地址的变量。

在困惑的地方,数组的名称在许多上下文中被转换为指针。例如;

 char x[] = "AB";
 char *p = x;

此赋值有效,但这并不意味着数组是指针,或指针是数组。而是将名称x转换为指向其第一个字符的指针。所以初始化在功能上等同于

 char *p = &x[0];

因此p指向字符串'A'中值为"AB"的字符。

您的代码中也发生了同样的事情,所以

char *getUserWord()
{
    static char str[20];
    scanf("%s", str);
    return str;
}

相当于

char *getUserWord()
{
    static char str[20];
    scanf("%s", &str[0]);
    return &str[0];
}

在这两种情况下,getUserWord()返回的指针都有一个值str[0]的地址。这是用于在baseWord

中初始化main()的值
char *baseWord = getUserWord();

因为baseWord现在指向数组的第一个字符,所以它可以被视为AS,如果它是一个数组。在C中,对于给定的i值,这包括baseWord[i](在main())和str[i](在getUserWord()中)之间的等效。使用数组语法这一事实并不意味着指针和数组是同一个东西。这只意味着他们可以使用相同的语法进行处理。

然而,要实现的重要一点是,可以从函数返回指针(以及分配给或用于初始化另一个指针的返回值),但数组不能。所以,在main()这是合法的;

 char *p = getUserWord();
 p[0] = 'X';    /*  will change str[0] in getUserWord() */

但这不会是;

 char array[20] = getUserWord();

答案 1 :(得分:4)

无法在C中分配数组。这是C标准 1 的强制要求。第二个示例中的左值为baseWord,其类型为char[21],是一个数组。

在第一个示例中,当您返回类型为str的{​​{1}}时,它将转换为类型static char[20],并且可以从函数返回并分配给指针{ {1}}。由于char*具有静态存储持续时间,因此指针指向有效对象。

如果要返回非静态字符串,可以分配它(使用函数malloc),将现有字符串传递给函数或使用结构包装字符串。

1 (引自:ISO:IEC 9899:201X 6.3.2.1。左值,数组和函数指示符1)
可修改的左值是一个左值 没有数组类型,没有不完整的类型,没有const- 合格的类型,如果是结构或联合,则没有任何成员(包括, 递归地,所有包含聚合或联合的任何成员或元素) 合格的类型。

答案 2 :(得分:1)

这将解决您的问题。

#include <stdio.h>

void getUserWord(char* str);

int main(void)
{
    char baseWord[21] = ""; /* initialize for avoiding undefined behavior in case no data is read */
     getUserWord(baseWord);
     printf("%s", baseWord);

     return 0;
}

void getUserWord(char* str)
{
    scanf("%s", str);
}

答案 3 :(得分:-1)

此代码

        // Get the hours, minutes and seconds from the current time
        var hours = now.getHours();
        var minutes = now.getMinutes();
        var seconds = now.getSeconds();
        var amOrPm = 'AM';

        // Format hours, minutes and seconds
        if (hours > 12) {
            amOrPm = 'PM';
            hours = hours - 12;
        }
        if (minutes < 10) {
            minutes = "0" + minutes;
        }
        if (seconds < 10) {
            seconds = "0" + seconds;
        }

        // Gets the element we want to inject the clock into
        var elem = document.getElementById('clock');

        // Sets the elements inner HTML value to our clock data
        elem.innerHTML = hours + ':' + minutes + ':' + seconds + ' ' + amOrPm;

无法工作,因为从数组转换的内容不是左值(N1570 6.3.2.1),而赋值运算符的左操作数需要可修改的左值(N1570 6.5 0.16)。

您可以将指针传递给一个数组,其中将从被调用方存储读取的字符串。

char baseWord[21];
baseWord = getUserWord();

在此示例中省略,您应该检查读取是否成功。