【问题标题】:CS50 Caesar (usage of asterisk) [duplicate]CS50凯撒(星号的使用)[重复]
【发布时间】:2020-06-08 12:54:29
【问题描述】:

我有一个关于如何在我的代码中使用星号的问题。

最初我运行!isdigit(argv[1]) [没有*] 它显示分段错误。在参考了一个在线解决方案后,我意识到我们应该将* 放在!isdigit(*argv[1]) 中。有人可以解释代码中* 的功能吗? 以下是我的代码:

#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

int main (int argc, string argv[])
{
    if (argc !=2 || !isdigit(argv[1]))
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }

    int key = atoi(argv[1]);

    string p = get_string("plaintext: ");
    printf ("ciphertext: ");

    for ( int i=0, x=strlen(p); i<x; i++)
    {
        if (p[i]>='a' && p[i]<='z')
        {
            p[i] = (p[i] -'a'+key ) %26 +'a';
        }
        if (p[i]>='A' && p[i]<='Z')
        {
            p[i] = (p[i] -'A'+key ) %26 +'A';
        }
    }
    printf("%s\n",p);
}

【问题讨论】:

  • 非常类似于问题here(以及我在那里给出的答案)。
  • argv[1] 是一个指针(被不属于标准 c 的“字符串”类型所掩盖),所以 *argv[1] 是一个指针间接寻址,第二个命令行的第一个字节程序运行时传递给程序的参数。
  • @AdrianMole,谢谢我阅读了你的解释。假设我的 argv[1] = 你好,当我输入 *argv[1] 时,这意味着它将取消引用字符串到 argv[1][0]、argv[1][1]...argv[1][4] ?
  • *argv[1] 将是argv[1][0] 处的单个字符。对于字符串中的第二个字符,即argv[1][1],您可以使用*(argv[1] + 1),但在这种情况下,只使用两个[a][b] 格式会更清楚。

标签: c pointers c-strings cs50 dereference


【解决方案1】:

好像在这个参数声明中

string argv[]

名称string 是类型char * 的别名。

所以参数声明可以改写成这样

char * argv[]

也就是说,它是一个char * 类型的指针数组。编译器将此声明隐式调整为char **argv

所以表达式argv[1] 给出了传递给函数主数组的第二个元素,索引为1。它的类型为char *。函数 isdigit 需要将 char 类型的对象转换为 unsigned char 类型。因此,要获得 char 类型的对象(指向字符串的第一个字符),您必须取消引用类型为 char * 的指针 argv[1],例如 *argv[1] 或 argv[1][0]

至少写成这样会更正确

!isdigit( ( unsigned char )*argv[1] )

但总的来说,这种检查是不够的。您应该检查指针argv[1] 指向的整个字符串是否代表一个数字。

【讨论】:

  • 没有isdigit() 期望int
  • 更重要的是,为什么首先会出现段错误。我无法使用 int isX(int c) { return c &gt;= '0' &amp;&amp; c &lt;= '9'; } 之类的简单函数来重现它
  • @Waqar 它希望将用作参数的 unsigned char 类型的对象转换为参数的类型。
  • @Waqar 来自 C 标准“1 标头 声明了几个对字符分类和映射有用的函数。198) 在所有情况下,参数都是一个 int,其值应为可表示为无符号字符”注意“分类和映射字符”这句话。和“可表示为无符号字符”。
猜你喜欢
  • 1970-01-01
  • 2014-03-27
  • 2020-08-02
  • 2020-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多