首页 > 解决方案 > CS50 凯撒(星号的用法)

问题描述

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

最初我运行!isdigit(argv[1])[without *] 它显示分段错误。在参考了在线解决方案后,我意识到我们应该将*. !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);
}

标签: cpointersc-stringscs50dereference

解决方案


似乎在这个参数声明中

string argv[]

namestring是 type 的别名char *

所以参数声明可以重写为

char * argv[]

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

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

至少写成这样会更正确

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

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


推荐阅读