Я создал для этого функцию:

int SIGN_CHECKER (char* x)
{
    if(*x == '!')
    {
        return 1;
    } else if(*x == '?')
    {
        return 1;
    } else if(*x == '^')
    {
        return 1;
    } else if(*x == '&')
    {
        return 1;
    } else if(*x == '%')
    {
        return 1;
    } else
    {
        return 0;
    }
}

Но, как вы видите, это не так эффективно, кто-нибудь знает лучший способ? Спасибо

0
Marie 26 Янв 2022 в 15:45
2
Возможно return (strchr("!?^&%", *x) != NULL);
 – 
pmg
26 Янв 2022 в 15:48
1
Почему x является указателем?
 – 
HolyBlackCat
26 Янв 2022 в 15:48
Вместо этого вы можете использовать таблицу поиска или переключить регистр. (Согласно бенчмаркам, if'ы предпочтительнее переключать в диапазоне 4 проверок). Эффективнее - LUT, а не указатель, а просто char
 – 
kobi
26 Янв 2022 в 15:50
Предполагается ли, что SIGN_CHECKER проверяет только первый символ строки?
 – 
Some programmer dude
26 Янв 2022 в 15:51
Ваша функция неверна. Пожалуйста, покажите код, который вызывает SIGN_CHECKER, тогда мы сможем рассказать вам больше о том, почему это неправильно.
 – 
Jabberwocky
26 Янв 2022 в 15:53

3 ответа

Типичная скорость выполнения по сравнению с оптимизацией использования памяти заключается в создании простой справочной таблицы.

#include <stdbool.h>

int sign_checker (char x)
{
  static const bool is_special [256] = 
  {
    ['!'] = true,
    ['?'] = true,
    ['^'] = true,
    ['&'] = true,
    ['%'] = true,
  };

  return is_special [(unsigned char)x];
}

Машинный код x86 очень эффективен (gcc -O3):

SIGN_CHECKER:
        movsx   rdi, dil
        movzx   eax, BYTE PTR is_special.0[rdi]
        ret
is_special.0:
        .zero   33
        .byte   1
        .zero   3
        .byte   1
        .byte   1
        .zero   24
        .byte   1
        .zero   30
        .byte   1
        .zero   161
3
Lundin 26 Янв 2022 в 16:01

Во-первых, объявление параметра функции, имеющего тип char *, не имеет смысла, поскольку внутри функции проверяется только один символ.

Функция может быть объявлена и определена следующим образом

#include <string.h>

//...

int SIGN_CHECKER( char c )
{
    return c != '\0' && strchr( "!?^&%", c );
}

Как видите, внутри функции достаточно написать всего одну строку.

0
Vlad from Moscow 26 Янв 2022 в 15:54

Вы можете попробовать использовать регулярное выражение, например:

#include <regex.h>      
#include <stdio.h>  
#include <stdlib.h>
int check_pattern(char *string, char *pattern){
    regex_t regex;
    int res;

    // Compile regex
    res = regcomp(&regex, pattern, 0);
    
    // if there is error on compiling regex
    if (res)
        exit(1);

    // Execute regex
    res = regexec(&regex, string, 0, NULL, 0);
    if (!res) 
        return (1);
    else 
        return (0);

    // Free memory
    regfree(&regex);
}

Знать передать в функцию строку и специальные знаки в шаблоне регулярного выражения:

int main()
{
    // special signs are : "?*-"
    printf("%d\n", check_pattern("abc?d", "[?*-]"));
} 

Узнайте больше о том, как использовать регулярное выражение в c, из этого статья.

0
Abdellah Maarifa 26 Янв 2022 в 16:30