【问题标题】:Comparison between pointer (char*) and integer error指针(char*)与整数错误的比较
【发布时间】:2021-04-04 12:24:52
【问题描述】:

所以基本上用户在一个变量中输入他们访问过多少个国家,然后我把它作为数组的大小。

之后,我使用for 循环列出所有访问过的国家/地区。但我想让我的代码更智能一点,并将and 放在最后一个国家/地区的句子末尾。

例如3国家:

You visited Japan, Korea and Canada.
                 ^       ^^^
#include <stdio.h>
#include <cs50.h>


int main(void)
{
    int number_of_p = get_int("How many countries did you visit?\n");
    string countries[number_of_p];

    for (int x = 0; x < number_of_p; x++)
    {
        countries[x] = get_string("What countries did you visit?\n");
    }
    printf("You visited %i countries, including: ", number_of_p);
    for (int x = 0; x < number_of_p; x++)
    {

        printf("%s, ", countries[x]);
        /* looks for last element in arrays, inserts 'and' 
        to make it look grammatically correct. */

        if (countries[x] == number_of_p - 1 ) // ERROR HERE
        {
            printf(" and ");
        }

    }
    printf(".\n");

}

我正在比较指针 (char*) 和整数错误。

char* 是什么意思?

如何访问数组中的最后一个元素?

【问题讨论】:

  • x 是您的索引。这就是您要检查的内容。 countries[x] 是一个字符串。即if (countries[x] == number_of_p - 1 ) 应该是if (x == number_of_p - 1 )
  • 但我正在检查 x,如果国家 [x] == number_of_p - 1 然后打印 f。所以就像拿国家一样,它等于大小变量减1,然后用空格打印出'and'。我还有一个问题。 wtf char* 是什么意思?我使用了一个字符串而不是一个字符。还有 * 做什么,我查了一下它的意思是指针,但 char* 与此有什么关系,为什么我得到指针和 int 比较错误。请解释清楚,因为我是一个愚蠢的初学者

标签: c cs50 c-strings


【解决方案1】:

countries[x]string(在CS50中是char*的typedef),number_of_pint,你不能比较它们,它们是不同的类型,你可能有想要比较索引x,这是一种可能(且快速)的代码修复方法,包括标点符号如下所示:

Live demo

#include <stdio.h>
#include <cs50.h>

int main(void)
{
    int number_of_p = get_int("How many countries did you visit?\n");
    string countries[number_of_p];

    for (int x = 0; x < number_of_p; x++)
    {
        countries[x] = get_string("What countries did you visit?\n");
    }
    printf("You visited %i countries, including: ", number_of_p);
    for (int x = 0; x < number_of_p; x++)
    {

        printf("%s", countries[x]);
        if(x < number_of_p - 2){
            printf(", ");
        }
   
        if (x == number_of_p - 2)
        {
            printf(" and ");
        }  
    }
    printf(".\n");
}

输入:

3
Japan
Korea
Canada

输出:

You visited 3 countries, including: Japan, Korea and Canada.

【讨论】:

  • 我真的被你的代码弄糊涂了。你为什么要这样做 if(x
  • 第二,你为什么要这样做 if (x == number_of_p - 2) {printf(" and"},为什么不是 number_of_p - 1?最后,我很困惑。这不只是在句末打印'and'而不打印最后一个国家。你不需要在循环结束时使用另一个语句,如 printf("%s", countries[x]" 吗?否则你不会得到'japan korea canada and',因为你漏掉了最后一个打印声明吗?
  • @ShahJacob 所以你不想在打印最后两个国家之后打印昏迷,在你想要的倒数第二个之后 and 并且在最后一个之后你什么都不想要,所以你可以打印一个句号。有意义吗?
  • @ShahJacob,因为你先打印国家,然后是逗号,所以你希望最后两个国家后面没有逗号。所以韩国和加拿大后面不需要逗号。
  • @ShahJacob 您必须记住索引从0countries[0]countries[1]countries[2] 开始。我们打印countries[0]和逗号,countries[1]不需要逗号,countries[2]number_of_p - 2也不需要1,所以在打印countries[1],(if x == 1)之后我们打印and,见什么意思?
【解决方案2】:

if 语句中的条件

    if (countries[x] == number_of_p - 1 )

没有意义。左操作数countries[x] 的类型为char *,而右操作数的类型为int

即类型说明符string 是类型char * 的别名,而这个数组声明

string countries[number_of_p];

相同
char * countries[number_of_p];

所以你有一个指向字符串的指针数组。

C 中 char * 类型的别名 string 定义如下

typedef char * string;

循环看起来像

for (int x = 0; x < number_of_p; x++)
{
    if ( x != 0 )
    {
        putchar( ',' );
        putchar( ' ' );

        if ( x ==  number_of_p - 1 )
        {
            printf( "%s ", "and " );
        }
    }
    printf("%s", countries[x]);
}

这是一个演示程序

#include <stdio.h>

int main(void) 
{
    enum { number_of_p = 3 };
    char *countries[number_of_p] =
    {
        "Japan", "Korea", "Canada"
    };
    
    printf( "You visited %i countries, including: ", number_of_p );
    
    for (int x = 0; x < number_of_p; x++)
    {
        if ( x != 0 )
        {
            putchar( ',' );
            putchar( ' ' );

            if ( x ==  number_of_p - 1 )
            {
                printf( "%s ", "and" );
            }
        }
        printf("%s", countries[x]);
    }
    
    return 0;
}

它的输出是

You visited 3 countries, including: Japan, Korea, and Canada

【讨论】:

  • 我很困惑,char* 是什么意思。 char* 和 char 有什么区别。我知道 C 中的字符串基本上是 char 类型的数组,但 char* 是什么意思,它有什么作用。还有为什么我的 if 语句有意义。
  • 我也是一个 C 初学者,我不知道 *countries[number_of_p] 是做什么的。那是一个指针吗?你为什么在数组的索引处使用指针。对不起,我真的不知道指针是如何工作的,我一个月前才开始用 C 编程。还有 enum 做什么以及 char 是什么。你能回答我所有的问题吗?我很困惑和沮丧
  • @ShahJacob 程序中使用的类型说明符字符串是 char * 类型的别名。您正在输入字符串,函数 get_string 返回指向第一个字符的指针。
  • @ShahJacob 这个声明字符串国家[number_of_p];与声明 char * countries[number_of_p]; 相同
  • 我不明白你刚才说的任何东西,请用更简单的词解释。类型特定的字符串和别名是什么意思。以及输入字符串和指向函数 get_string 返回的第一个字符的指针是什么意思。
【解决方案3】:

你可以用一个 printf 来做这种事情,使用一个预定义的字符串作为分隔符。使用单个 printf 而不是特殊的大小写,列表的尾部通常更容易维护。许多人对三元运算符感到困惑。这里有两种不同的方法,首先使用 switch,然后使用三元运算符:

#include<stdio.h>

int main(void)
{
        char *countries[] = { "foo", "bar", "baz" };
        int number_of_p = sizeof countries / sizeof *countries;
        /* First loop, using a switch */
        for( int x = 0; x < number_of_p; x++ ) {
                char *div = ", ";
                switch( x ){
                case sizeof countries / sizeof *countries - 2: div = ", and "; break;
                case sizeof countries / sizeof *countries - 1: div = ".\n"; break;
                }
                printf("%s%s", countries[x], div);
        }
        /* Same loop as above, with if/else instead of the switch */
        for( int x = 0; x < number_of_p; x++ ) {
                char *div = ", ";
                if( x == number_of_p - 2 ) {
                        div = ", and ";
                } else if( x == number_of_p - 1 ) {
                        div = ".\n";
                }
                printf("%s%s", countries[x], div);
        }
        /* Same loop as above, written less verbosely */
        for( int x = 0; x < number_of_p; x++ ) {
                printf("%s%s", countries[x], x == number_of_p - 2 ? ", and " :
                        x == number_of_p - 1 ? ".\n" : ", ");
        }
}

【讨论】:

  • 对不起 *countries] = {foo, bar, baz} 是什么意思。特别是 *countries[] 是什么意思,我知道 * 是一个指针符号,但我刚开始用 C 编程,不知道指针是如何工作的。为什么在声明数组时使用指针符号。还有为什么你使用双引号而不是单引号,因为它是一个字符。还有你为什么要做国家的规模/ *国家的规模,*国家是什么意思。 *countries 的功能是什么,为什么要使用指针。请解释一下
  • char *countries[] = { "foo", "bar", "baz" } 只是一种初始化数组的方法。您的用户输入与我的解决方案并不特别相关,因此为了清楚起见,我将其全部省略。双引号是因为countries 不是一个字符,它是一个指向字符的数组。 "foo" 是一个常量字符串,countries 数组的第一个元素被分配到该字符串。 sizeof countries / sizeof *countries 是获取数组元素数量的标准技术。
  • sizeof 是编译时运算符(不是函数),sizeof countries 是整个数组的大小。在我的盒子里,一个 char * 的大小是 4。由于数组有 3 个元素,sizeof countries 是 12。sizeof *countries 是其中一个元素的大小,所以 sizeof countries / sizeof *countries 是 3。
  • 很遗憾,在switch语句的情况下不能使用变量,但是可以使用编译时常量。这个限制就是为什么我更喜欢嵌入在 printf 中的三元运算符来处理这类事情。它比一长串 if 语句更简洁 (IMO)。
  • 你的意思我很困惑。国家怎么不是字符。也不是你的意思是字符串而不是字符。其次你为什么用*char,*char的作用是什么,这里使用指针*符号的作用是什么(我们还没有学过指针uet)。其次,如果它是字符,为什么要使用双引号而不是单引号。第三个为什么 sizeof 国家/*国家的规模有效。你为什么使用*国家,你为什么在这里使用指针。国家/地区的大小甚至意味着什么,它实际上是相同的陈述除以相同的陈述?你能解释一下吗
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-13
  • 1970-01-01
  • 2012-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多