【问题标题】:Alternatives to my global variables for constant arrays?常量数组的全局变量的替代方案?
【发布时间】:2023-03-30 00:26:02
【问题描述】:

我在学校有一个重建 printf 的项目。

我不想一直在我的代码中检查字符的格式说明符,因为我发现它很乱,而且很难看。

就目前而言,我已经找到了一种方法,即创建一些全局常量数组并使用它们进行检查。但我不喜欢在我的代码中也有这么多全局变量的想法。

这是其中一种情况是全局变量可以吗?或者我应该使用其他方法来获得我想要的东西?

我是这样开始的:

全局常量数组

const char  g_sp_integer[] = {
    'd',    //signed decimal int
    'i',    //signed decimal int
    'o',    //unsigned octal
    'u',    //unsigned decimal int
    'x',    //unsigned hex int
    'X',    //unsigned hex int (uppercase)
    '\0'
};

我的标题

#ifndef  FT_PRINTF_H
# define  FT_PRINTF_H

# include <stdarg.h>
# include <stdint.h>
# include <stdlib.h>

# include "libft.h"

# define SUCCESS (int32_t)0
# define FAILURE (int32_t)-1

/*
** Those extern definitions are used to check the specifier flags
*/

extern const char   *g_sp_integer;

int ft_printf(const char *format, ...);

#endif

还有我的 printf 函数

#include "ft_printf.h"

static int32_t  is_sp_integer(char c)
{
    uint32_t    i;

    while (g_sp_integer[i] != '\0')
    {
        if (g_sp_integer[i] == c)
            return (i);
        ++i;
    }
    return (FAILURE);
}

int ft_printf(const char *format, ...)
{
    va_list ap;
    char    *tmp;
    int32_t sp_type;

    tmp = format;
    va_start(ap, format);
    while (tmp != '\0')
    {
        if (tmp != '%')
        {
            ft_putchar(tmp);
            continue;
        }
        if ((sp_type = is_sp_integer(++tmp)) != FAILURE)
            ;   //parse_flag(sp_type);
        //continue checking the type of the specifier
    }
    va_end(ap);
    return (SUCCESS);
}

我想避免的:

这些只是简单的原型,但我想知道是否有适当的方法让我的函数像那样干净。这意味着,在我看来,如果可能的话,我想避免做这样的检查:

if (c == 'd' || c == 'i')
    //manage the integer flag
else if (c == 'o')
    //manage the octal flag, etc.

如果不可能,最好的方法是我想避免的,请告诉我!

感谢大家的耐心等待,因为有时很难找到好的做法!

编辑:

我使用的解决方案:

虽然第一个解决方案对我在这种情况下应该做的事情有全局答案(在该文件中使用静态变量),但我已经结束了第二个答案中建议的操作,因为它符合我的需要,并避免使用静态或全局变量。

这是我的函数代码:

static int32_t is_sp_integer(char c) {
  const char    *sp_integer;
  const char    *sp_ptr;

  sp_integer = "dDioOuUxX";
  sp_ptr = sp_integer;
  while (*sp_ptr != '\0')
  {
    if (*sp_ptr == c)
      return (sp_ptr - sp_integer);
    ++sp_ptr;
  }
  return (FAILURE);
}

谢谢大家!

【问题讨论】:

  • 这个怎么样:strchr(c, "diouxX") != 0; string.h 中还有一组标准函数,即isdigit,您可以使用它来代替 is_sp_integer。
  • 除了 malloc、free、exit 和 write,我不能真正使用标准库。但可以肯定的是,我可以编码并做到这一点。感谢这个想法。
  • @Serge 注意strchr(c, "diouxX") != 0,当c==0strchr(c, "diouxX") 返回一个非空指针。防止c== 0应该不是问题。
  • @cbaillat How to check that two format strings are compatible? 经历了许多相同的事情。
  • const char g_sp_integer[] --> static const char g_sp_integer[],现在g_sp_integer[]只有文件范围。

标签: c global-variables constants


【解决方案1】:

g_sp_integer 只在is_sp_integer 函数内部使用,所以在那里定义它:

static int32_t  is_sp_integer(char c)
{
    const char  g_sp_integer[] = {
        'd',    //signed decimal int
        'i',    //signed decimal int
        'o',    //unsigned octal
        'u',    //unsigned decimal int
        'x',    //unsigned hex int
        'X',    //unsigned hex int (uppercase)
        '\0'
    };

    uint32_t    i;

    while (g_sp_integer[i] != '\0')
    {
        if (g_sp_integer[i] == c)
            return (i);
        ++i;
    }
    return (FAILURE);
}

【讨论】:

  • 目前仅在此处使用,但我可能需要进行多次检查,因为我需要解析标签等。不过感谢您的建议,也许我会尝试那样做。谢谢!
  • 如果您需要在多个函数中使用它,请在文件范围内使用static 定义它,并从标题中删除extern 声明,这样它在其他源文件中不可见。跨度>
  • 谢谢,我会这样做的!
【解决方案2】:

这里有一点不同的使用指针的实现。我认为它比数组更有效。

const char  *g_sp_integer= "diouxX";
static int32_t  is_sp_integer(char c)
{
    const char *p = g_sp_integer;
    while (*p) {
        if (*p == c)
            return (p - g_sp_integer);
        p++;
    }
    return (FAILURE);
}

【讨论】:

  • 好主意!我一定会尝试实现它并检查它是否更快!
猜你喜欢
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 2018-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多