函数

时间:2019-02-09 07:03:22

标签: c function pointers

char firstmatch(char *s1, char *s2) {
    char *temp;
    temp = s1;
    do {
        if (strchr(s2, *temp) != 0)
            return temp;
        temp++;
    } while (*temp != 0);
    return 0;
}

char *strchr(register const char *s, int c) {
    do {
        if (*s == c) {
            return (char*)s;
        }
    } while (*s++);
    return (0);
}

我是编程新手,因此我收到了这段代码,该代码可以找到字符串s1中的第一个字符,该字符串也位于字符串s2中。任务是了解C代码并将其转换为汇编代码。到目前为止,我的重点只是了解C代码的功能,而我目前在使用指针方面遇到困难。我可以对firstmatch()函数中的代码进行排序,并逐步解决,但是我对char * strchr()函数感到困惑。我无法理解int c对于常量字符指针有何意义?如果有人可以帮助解释,我将不胜感激。

4 个答案:

答案 0 :(得分:3)

代码示例中的函数strchr()是Standard C库函数的不完整实现,该函数无法找到C字符串中字符的第一个匹配项。

出于历史原因,该参数的类型为int:在早期版本的语言函数中,仅当隐式类型int不足时才输入参数。字符参数作为int值传递,因此不必另外输入参数。

register关键字已过时:早期的C编译器不如当前的C编译器先进,程序员可以通过使用register关键字修饰其定义来帮助代码生成器确定哪些变量要存储在CPU寄存器中。 。现代的编译器效率更高,通常在此游戏中胜过程序员,因此,如今该关键字通常被忽略。

但是请注意,此实现与标准函数的行为有所不同:比较之前,c的值必须转换为char。正如chux所指出的,出于比较目的,<string.h>中的所有函数都将C字符串和内存块中的字节视为无符号字符。

以下是具有正确行为的更易读的版本:

#include <string.h>

char *strchr(const char *str, int c) {
    const unsigned char *s = (const unsigned char *)str;
    do {
        if (*s == (unsigned char)c) {
            return (char *)s;
        }
    } while (*s++ != '\0');
    return NULL;
}

答案 1 :(得分:0)

int c参数也可以是char c*temp的类型为char

strchr函数将指针插入以nul终止的字符串和char中,并将指针返回到下一个出现的char;如果指针到达字符串末尾的nul,则返回null。

答案 2 :(得分:0)

strchr()接收一个指向序列中第一个(或唯一)字符的指针(认为是该地址的存储地址)。 该函数使用该指针s从内存中提取字符,并查看其值是否与c的值匹配。如果匹配,则返回指针。 如果不匹配,则将指针前进到序列中的下一个字符(即,将内存地址增加1)并重复。 如果没有匹配项,并且内存中的字符值为0,则返回NULL

指向const char的指针表示不会写入内存,但可以从中读取。实际上,该函数从不尝试使用指针进行写。

因此,您从内存中读取字符并将它们与int进行比较。在大多数表达式中,chars隐式转换为signed int(如果这样的转换通常是可能的,而不会丢失任何类型的char值)或unsigned int(否则)。参见integer promotions。如果在==运算符的两边都使用有符号的int表示所有内容都是微不足道的,只需将它们进行比较即可。如果一个是unsigned int(提升的*s字符),而另一个是signed intc),则已签名的一个将转换为未签名的(请参阅同一链接的文章以获取相关信息)。逻辑/规则),然后==的两侧具有相同的类型(unsigned int)并且具有可比性(这是C的主要思想之一,大多数二进制运算符将其输入转换为公共类型并产生该普通类型的结果。

简单地说,在C语言中,您可以比较不同的算术类型,并且编译器将插入必要的(根据语言规则)转换。也就是说,并非所有转换都保留值(例如,从signed intunsigned int的转换并没有保留负值,但是它们以明确定义的方式转换),这可能令人惊讶(例如,{ {1}}的计算结果为1,这对那些懂一点数学的人来说似乎是荒谬的),尤其是对于刚接触该语言的人而言。

这里真正的问题似乎是:“为什么-1 > 1u没有定义为c?”。 如果检查标准的C库函数,他们会发现char类型的值(几乎?)从未传递或返回,尽管传递或返回指向char的指针是很常见的。各个字符通常通过char类型传递。原因可能是,如上所述,int无论如何都会在表达式中转换为charint,因此需要进行一些额外的转换(返回到unsigned int然后再次避免使用char

答案 3 :(得分:-1)

字符* s1表示C中的字符串。 0表示Acsii等效于'\ 0',它是C中字符串的结尾。字符和整数可以互换,但是您需要知道每个字符的Ascii值。字母“ A”等于Ascii值的整数65。这应该回答您有关int c的问题。它对代码没有任何行为上的差异。

现在假设您有字符串hello和meh,您将拥有:

    char * s1 = ['h', 'e','l','l','o','\0'] 
    char * s2 = ['m', 'e', 'h','\0']

因此您致电:

firstmatch('hello', 'meh')

temp被分配了'hello'的值。

现在您打电话

strchr('meh', 'h')

*在这种情况下,temp等于temp [0],即'h'。

在strchr中,它从'm'开始循环遍历'meh'的每个字母。

First iteration: 
'm' == 'h' -> false therefore proceed to next letter (*s++)
Second iteration: 
'e' == 'h' -> false therefore proceed to next letter (*s++)
Third iteration: 
'h' == 'h' -> true therefore return a char value that is not 0.

这将使我们返回到if条件内的firstmatch函数。 由于if条件在第三次迭代中通过,因此返回“ h”。

假设第三次迭代失败,它将递增到s1中的下一个字母(即“ e”),并遵循上述相同的过程。

最后,(* temp!= 0)表示,如果我们在上面定义的“ hello”的s1中遇到“ \ 0”,则它将停止整个循环并返回0。指示没有相同的字母

如果您不了解* temp == temp [0]的原因,请阅读C / C ++中的指针算法。同样,* temp ++ == temp [n + 1](n代表当前字符)。