Объяснение целого и регистр постоянного символа в функции - PullRequest
0 голосов
/ 09 февраля 2019
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 голосов
/ 09 февраля 2019

Функция strchr() в вашем примере кода является неполной реализацией стандартной библиотечной функции C, которая определяет местонахождение первого вхождения символа в строке C, если таковая имеется.

Аргумент имеет тип int по историческим причинам: в ранних версиях функций языка аргументы вводились только в том случае, если неявного типа int не хватало.символьные аргументы были переданы как int значения, поэтому вводить аргумент по-другому было не нужно.

Ключевое слово register устарело: ранние компиляторы C не были такими продвинутыми, как текущие, и программист мог помочь генераторам кода определитькакие переменные хранить в регистрах ЦП, украсив их определения ключевым словом register.Современные компиляторы более эффективны и обычно бьют программистов в этой игре, поэтому в настоящее время это ключевое слово в основном игнорируется.

Обратите внимание, однако, что эта реализация ведет себя иначе, чем стандартная функция: значение 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;
}
0 голосов
/ 09 февраля 2019

char * s1 представляет строку в C. 0 представляет Acsii эквивалент '\ 0', который является окончанием строки в C. Символы и целые числа являются взаимозаменяемыми, но вы должны знать значение Ascii каждогоголец.Буква «A» эквивалентна целому числу 65 по значению Ascii.Это должно ответить на ваш вопрос о 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,он перебирает каждую букву «meh», начиная с «m».

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.

Это возвращает нас к функции firstmatch внутри условия if.Поскольку условие if передается на третьей итерации, оно возвращает нам 'h'.

Предположим, что третья итерация не удалась, она будет увеличиваться до следующей буквы в s1, которая будет 'e', ​​и следовать той же самойописанная выше процедура.

Наконец, (* temp! = 0) означает, что если мы встретим '\ 0' в s1 для 'привет', который мы определили выше, то он останавливает весь цикл и возвращает 0. Указание на отсутствие одинаковых букв.

Прочтите об арифметике указателей в C / C ++, если вы не понимаете, почему * temp == temp [0].Аналогично * temp ++ == temp [n + 1] (n представляет текущий символ).

0 голосов
/ 09 февраля 2019

strchr() получает указатель (думаю, адрес памяти) на первый (или единственный) символ в последовательности.Функция извлекает символ из памяти, используя этот указатель s, и проверяет, соответствует ли его значение значению c.Если есть совпадение, он возвращает указатель.Если совпадений нет, он перемещает указатель на следующий символ в последовательности (то есть увеличивает адрес памяти на 1) и повторяется.Если совпадения нет и значение символа из памяти равно 0, возвращается NULL.

Указатель на const char подразумевает, что в память не будет производиться запись, но это может бытьчитать из.Действительно, функция никогда не пытается писать с помощью указателя.

Итак, вы читаете символы из памяти и сравниваете их с int.В большинстве выражений chars неявно преобразуется в signed int (если такое преобразование обычно возможно без потери какого-либо значения типа char) или unsigned int (в противном случае).См. целочисленные акции по этому вопросу.Если после этого обе стороны оператора == являются знаковыми, все тривиально, просто сравните их.Если один unsigned int (повышенный *s символ), а другой signed int (c), подписанный конвертируется в неподписанный (см. Ту же статью по логике / правилам), после чегообе стороны == имеют одинаковый тип (unsigned int) и являются сопоставимыми (это одна из ключевых идей C, большинство бинарных операторов преобразуют свои входные данные в общий тип и выдают результат этого общего типа).

Проще говоря, в C вы можете сравнить различные арифметические типы, и компилятор вставит необходимые (согласно правилам языка) преобразования.Тем не менее, не все преобразования сохраняют значение (например, преобразование из signed int в unsigned int не сохраняет отрицательные значения, однако они преобразуются четко определенным образом), и это может удивлять (например, -1 > 1u оценивается как1, что кажется абсурдным любому, кто немного разбирается в математике), особенно новичкам в языке.

Реальный вопрос здесь звучит так: «Почему c не определено как char?».Если проверить стандартные функции библиотеки C, они обнаружат, что значения типа char (почти?) Никогда не передаются и не возвращаются, хотя передача или возврат указателей на char довольно распространена.Отдельные символы обычно передаются с помощью типа int.Причина этого, вероятно, заключается в том, что, как упоминалось выше, char в любом случае будет преобразовано в int или unsigned int в выражении, поэтому некоторые дополнительные преобразования (обратно в char, а затем снова в int) могут бытьизбегать.

0 голосов
/ 09 февраля 2019

Аргумент int c также может быть char c.Тип *temp является char.

Функция strchr берет указатель на завершенную нулем строку и символ и возвращает либо указатель на следующее вхождение символа, либо ноль, если он достиг нуля в конце строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...