C language中对指针和数组不明白的地方

发布于 2022-09-02 10:26:19 字数 788 浏览 17 评论 0

还是直接从代码看问题吧,谢谢各位的时间。

#include <stdio.h>
#include <string.h>

int lookup_keyword(char const * const desired_word, char const * keyword_table[]);

char const *keyword[] = {
    "do",
    "what",
    "ever",
    "anything",
    "you",
    "want",
    NULL
};


int main(void)
{
    int lenth = lookup_keyword("do", keyword); //这里main中调用函数是否正确呢,特别是第一个参数?
    printf("%d\n", lenth);
    return 0;
}

int lookup_keyword(char const * const desired_word, char const * keyword_table[])
{
    char const **kwp;  

    for(kwp= keyword_table; *kwp != NULL; kwp++) 
        if (strcmp(desired_word, *kwp) == 0)
            return (*kwp - desired_word);
        return -1;        //为什么书中对于for循环不加上大括号{}来包含代码块呢,所以在这里想问的是**什么情况下可以不用加大括号(指的是代码语句在二条及以上的时候)**
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

银河中√捞星星 2022-09-09 10:26:19
  1. 是对的。第一个参数char const* const是指向常量字符的
    常量指针。可以接收char*, const char*, char const* const

类型参数。"str"会被作为const char*代入参数

  1. if,for后面接单条语句,{}内的语句可视为单条语句。
    你不想让if或者for影响的语句就不用放在{}内了。

if(cond)
   statement in if
   statment not in if
statment not in if

if(cond)
{
    statement in if
    statment in if
}
    statement not in if
statement not in if
天生の放荡 2022-09-09 10:26:19

你这什么书?语法都好奇怪,比如char const * const 是啥?
我只知道const char*
至于你的问题,那样调用是对的,

而for循环,也是没问题的,但是多于单行代码的时候,我建议还是加上{}

浪漫人生路 2022-09-09 10:26:19

第一个参数是常量指针和指针常量的概念;const放在星号左边的时候,是常量指针,指的是指针指向的内容不能被修改,const放在星号右边的时候,是指针常量,指的是指针本身存储的地址不能被修改;题主贴的代码里面const在星号左右都有,说明既不能更改指针的地址,也不能更改指针指向的内容;

第二个问题,for、if下面只有一句的时候可以不添加大括号{},这里if包括if下面的一句话整个内容可以认为是一句话,放在for下面不加大括号是没有问题的。当然这种编码风格并不提倡。

帅的被狗咬 2022-09-09 10:26:19
int main(void)
{
    int lenth = lookup_keyword("do", keyword); //这里main中调用函数是否正确呢,特别是第一个参数?
    // -- 当然正确,C语言是允许使用*字符串字面量*的,不过注意的是
    // 函数的参数一般至少要是 char const *,修改字面量的后果是未定义的
    printf("%d\n", lenth);
    return 0;
}

int lookup_keyword(char const * const desired_word, char const * keyword_table[])
{
    char const **kwp;  

    for(kwp= keyword_table; *kwp != NULL; kwp++) 
        if (strcmp(desired_word, *kwp) == 0)
            return (*kwp - desired_word);
        return -1;        //为什么书中对于for循环不加上大括号{}来包含代码块呢,所以在这里想问的是**什么情况下可以不用加大括号(指的是代码语句在二条及以上的时候)**
        // -- 当编译器可以判断你的语句属于 if 或者 for语句的子语句的时候就可以省略这个{}
        // 这种写法纯粹属于个人的代码风格问题,像我就喜欢除非是特别短的语句一般都会加上{}
        //    for(kwp= keyword_table; *kwp != NULL; kwp++)  {
        //        if (strcmp(desired_word, *kwp) == 0)    {
        //            return (*kwp - desired_word);
        //        }
        //    }
        //
}
雨落星ぅ辰 2022-09-09 10:26:19

补充一下:

如果声明或定义中出现了const*,根据两者的相对位置来决定const的作用:
*右边是const,说明是一个不可变的指针;
*左边是const(如char const * const char *),说明指针指向的内容不可变。
那么const * const则说明该指针和所指内容都不变。

但是如果你遇到了* const *嘛,那就是遇到函数声明(定义)了。
具体推荐看c专家编程,里面有读声明的方法。


至于加不加括号啊,如果想让if在不加花括号的情况下执行多个语句,可以用逗号。但是不推荐:

if (x == 0)
    x += 1, x += 2, x += 3;

注意从左到右的执行顺序。
感觉考试最喜欢出这种题了...

还有这样一种不推荐,但是的确可以的写法:

#include <stdio.h>

int main(void) {
    for (int i = 0; i < 1; i++)
        if (1 == 2)
            printf("one\n");
        else
            printf("two\n");
    return 0;
}

至于为什么不推荐嘛...因为debug时会de了你的命!

命硬 2022-09-09 10:26:19

第一个问题

int lenth = lookup_keyword("do", keyword);这里main中调用函数是否正确呢,特别是第一个参数?

正确。如果你觉得关于 low-level const 和 top-level const 的问题比较迷糊,可以参考 C++ Primer 5e 2.4.3 Top-Level const(C 与 C++ 在个这问题的处理是相同的)。里面关于这二者的区别讲的比较清楚。

第二个问题

为什么书中对于for循环不加上大括号{}来包含代码块呢?

  • return -1;语句缩进层次应该与for相同,即for循环里只有一个语句(if语句)。

  • 一个if语句,是指if (statement1) statement2;这样的形式,整体算一个语句,即这个if语句里包含一个return (*kwp - desired_word);语句。

如下:

int lookup_keyword(char const * const desired_word, char const * keyword_table[])
{
    char const **kwp;  

    for(kwp= keyword_table; *kwp != NULL; kwp++)  // for 后面只有一个语句时候可以省略括号(复合语句)
        if (strcmp(desired_word, *kwp) == 0)      // 这一行和下一行整体是**一个** if 语句
            return (*kwp - desired_word);
    return -1;
//  ^ 这个 return 和 for 是同一缩进层级的
}

什么情况下可以不用加大括号(指的是代码语句在二条及以上的时候)?

如果是for循环中代码语句在二条及以上的时候,必须将他们组成一个语句才行。组成的办法常见的有:

  • 使用大括号{}将循环体中的语句组成一个复合语句(常用);

  • 使用逗号表达式,将循环体中的语句组成一个语句(不常用)。

后一种方法可以不用加大括号。

如果还不能理解,那你对于基本语法还不是很清楚,你可能需要了解 (1) 什么叫语句(statement) (2) 什么叫复合语句(compound statement)(3) 一个复合语句也是一个语句。这三条请查阅任意一本优秀的编程语言入门教材,前三章内肯定有讲解。

水中月 2022-09-09 10:26:19

题主不知道你是不是正在看《C和指针》这本书。因为这个代码正是出于这本书第8章8.3小节指针数组。
这里首先要弄清楚一个概念,对于字符串常量,它的右值是一个“指向字符的常量指针”,也就是说你可以把“hello”这样的字符串常量赋值给指向字符的指针,而不能赋值给字符数组(当然除了在初始化字符数组的情况下)。实际上你不能直接将一个字符串常量赋值给一个字符数组,这不满足语法。如下:

char *pConstStr = "hello";    //将字符串常量赋值给指向字符的指针。
char str[6] = "hello";        //用字符串常量初始化一个字符数组。

但是,你能直接写出将字符串常量赋值给字符数组的语句吗?肯定不能。
因为在使用字符串常量时,它代表了自身的存储地址,而不是它的内容。理解了这一点,你的第一个疑问自然可以解决。

lookup_keyword("do", keyword)函数的第一个参数是char const * const desired_word,是一个指向常量字符的指针常量,除去两个const的修饰属性,它就是一个指向字符的指针,自然可以将“do”这个字符串常量作为实参传递给它。看到这里你也应该明白,为什么数组定义是一个指向字符的指针数组:

char const *keyword[] = {
    "do",
    "what",
    "ever",
    "anything",
    "you",
    "want",
    NULL
};

如果要定义成一个字符数组,那就必须是一个二维的字符数组:

char const keyword[][9] = {
    "do",
    "what",
    "ever",
    "anything",
    "you",
    "want",
    NULL
};

对于第二个问题,很好解答,因为下面的if语句就是一条语句,可以不加{}直接放在for循环后面。当然,加上{},代码的风格更好,可读性更强。

第一次答题,有错请大家拍砖。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文