C 函数中整数和寄存器常量字符的说明

C 函数中整数和寄存器常量字符的说明,c,function,pointers,C,Function,Pointers,我是编程新手,我得到了这段代码,它可以在字符串s1中找到第一个字符,该字符串也在字符串s2中。任务是理解C代码并将其转换为汇编代码。到目前为止,我的重点是理解C代码在做什么,我目前在指针方面遇到了困难。我可以在firstmatch()函数中对代码进行排序,然后继续往下看,但是我有点混淆了char*strchr()函数。我无法理解int c对于常量字符指针的意义是什么?如果有人能帮我解释一下,我将不胜感激 int c参数也可以是char c。*temp的类型是char strchr函数将指针放入以

我是编程新手,我得到了这段代码,它可以在字符串
s1
中找到第一个字符,该字符串也在字符串
s2
中。任务是理解C代码并将其转换为汇编代码。到目前为止,我的重点是理解C代码在做什么,我目前在指针方面遇到了困难。我可以在
firstmatch()
函数中对代码进行排序,然后继续往下看,但是我有点混淆了
char*strchr()
函数。我无法理解
int c
对于常量字符指针的意义是什么?如果有人能帮我解释一下,我将不胜感激

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


strchr函数将指针放入以nul结尾的字符串和字符中,并返回指向该字符下一次出现的指针,如果指针到达字符串末尾的nul,则返回null。

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

现在假设你有hello和meh字符串,你会:

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);
}
所以你叫:

    char * s1 = ['h', 'e','l','l','o','\0'] 
    char * s2 = ['m', 'e', 'h','\0']
temp的值为“hello”

现在你打电话

firstmatch('hello', 'meh')
*在这种情况下,temp相当于temp[0],即“h”

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

strchr('meh', 'h')
这将返回if条件中的firstmatch函数。 由于if条件在第三次迭代中传递,因此它返回“h”

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

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

如果您不理解为什么*temp==temp[0],请阅读C/C++中的指针算法。同样地,*temp++==temp[n+1](n表示当前字符)。

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

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

因此,您可以从内存中读取字符并将其与int进行比较。在大多数表达式中,
chars
隐式转换为
signed int
(如果这种转换通常可以在不丢失
char
类型的任何值的情况下进行)或
unsigned int
(否则)。看看这个。如果在这之后,
==
操作符的两边都是带符号的整数,那么一切都很简单,只需比较它们。如果一个是
unsigned int
(升级的
*s
字符),而另一个是
signed int
c
),则有符号的一个将转换为unsigned(逻辑/规则请参见同一链接文章),之后
==
的两侧具有相同的类型(
unsigned int
),并且具有可比性(这是C语言的关键思想之一,大多数二进制运算符将其输入转换为公共类型并生成该公共类型的结果)

简单地说,在C语言中,您可以比较不同的算术类型,编译器将插入必要的(根据语言规则)转换。也就是说,并非所有转换都保留值(例如,从
有符号int
无符号int
的转换不保留负值,但它们是以定义良好的方式转换的)这可能是令人惊讶的(例如,1u的计算结果为1,这对任何懂一点数学的人来说都是荒谬的),特别是对这种语言的新手来说

这里真正的问题似乎是“为什么
c
不定义为
char
?”。 如果检查标准C库函数,他们会发现
char
类型的值是(几乎是?)从未传递或返回,尽管传递或返回指向
char
的指针非常常见。单个字符通常通过
int
类型传递。原因可能是,如上所述,
char
将在表达式中转换为
int
无符号int
y、 因此,可以避免一些额外的转换(返回到
char
,然后再转换到
int
)。

代码示例中的函数
strchr()
是标准C库函数的一个不完整实现,该函数用于定位C字符串中第一个出现的字符(如果有的话)

由于历史原因,参数的类型为
int
:在早期版本的语言函数中,只有当隐式类型
int
不满足要求时,才会键入参数。字符参数作为
int
值传递,因此不需要以不同的方式键入参数

register
关键字已经过时:早期的C编译器不如当前的编译器先进,程序员可以通过修饰
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.
#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;
}