【问题标题】:The best way to return a result返回结果的最佳方式
【发布时间】:2015-06-19 11:33:42
【问题描述】:

我写了以下函数。此函数接收十六进制值的地址,例如0x4571 并根据十六进制值的位位置计算日、月和年。

void fat_dir_date(char *dateAr) {   

    const unsigned int MaskDayOfMonth = 0x1F; //0000000000011111
    const unsigned int MaskMonthOfYear = 0x1E0; //0000000111100000
    const unsigned int MaskYear = 0xFE00; //1111111000000000

    unsigned int DayOfMonth = hex & MaskDayOfMonth; //AND Bit Operation

    unsigned int MonthOfYear = hex & MaskMonthOfYear; //AND Bit Operation
    MonthOfYear = MonthOfYear >> 5; //Bitshift to right position

    unsigned int Year = hex & MaskYear; //AND Bit Operation
    Year = Year >> 9; //Bitshift to right position

    printf("%d.%d.%d", DayOfMonth, MonthOfYear, 1980+Year);
}

计算工作正常。我在整数 DayOfMonth、MonthOfYear 和 Year 中得到了正确的数字。但是,我不想用 printf 将它们打印出来,而是想将这些值返回给调用者函数。以最好的方式连接在单个值或字符串中。

在 C 中解决这个问题的最佳方法是什么?

【问题讨论】:

  • 寻找best方式的问题不适合S.O
  • 也许你可以把它们都放在堆中创建的struct中,然后返回那个struct的地址。只是我的意见。
  • 你对“工作正常”有一些奇怪的定义。代码甚至无法编译。
  • 假设dateAr 指向一个足够大的缓冲区,您可以使用sprintf 将结果字符串放入dateAr

标签: c arrays char return c-strings


【解决方案1】:

你有几个选择:

  • 创建一个包含三个字段的struct,并将其返回,
  • 让来电者将您填写的struct 传递给您,
  • 让调用者向您传递一个字符串缓冲区,您可以使用sprintf 打印到该缓冲区,或者
  • 动态创建一个字符串,打印到它,然后返回。

第一个选项简洁易懂。它需要一些复制,但对于您需要的小型结构来说,这很好:

struct DateTime {
    int DayOfMonth;
    int MonthOfYear;
    int Year;
};
struct DateTime fat_dir_date(unsigned int hex) {
    struct DateTime res;
    res.DayOfMonth = ...
    res.MonthOfYear = ...
    res.Year = ...
    return res;
}

【讨论】:

  • 为什么不void fat_dir_date(unsigned int, unsigned int *, unsigned int *, unsigned int *)?为什么必须“返回”值?
  • @user3528438 因为这三个值是相关的。它们代表一个单一的逻辑事物,因此将它们组合成一个 struct 非常有意义。
  • 可能还有一个选项,虽然不那么受欢迎,但仍然有效。将fat_dir_date 声明为char *,并在fat_dir_date 中声明一个足够大小的静态缓冲区(例如static char buf[12] = {0};)。然后使用sprintf 或您喜欢的转换程序,填写并返回buf。通过将buf 声明为staticbuf 将继续存在并提供有效的返回。
  • @DavidC.Rankin 我根本不建议将此作为选项,因为它会创建一个不可重入函数。 C 库中的一些遗留函数就是这样(strtok 可能是其中最臭名昭著的),但它会让人头疼。我看到的函数返回静态缓冲区的一个问题是它们产生的问题很难识别:代码几乎一直完美无缺!
  • 同意,这就是为什么我用不那么受欢迎来限定它,但为了完整起见,记下了它。
【解决方案2】:

如果你需要打印数据并且不需要使用数值,我认为是这样的:

char * fat_dir_date(char *dateAr,unsigned int hex) {   

    const unsigned int MaskDayOfMonth = 0x1F; //0000000000011111
    const unsigned int MaskMonthOfYear = 0x1E0; //0000000111100000
    const unsigned int MaskYear = 0xFE00; //1111111000000000

    unsigned int DayOfMonth = hex & MaskDayOfMonth; //AND Bit Operation

    unsigned int MonthOfYear = hex & MaskMonthOfYear; //AND Bit Operation
    MonthOfYear = MonthOfYear >> 5; //Bitshift to right position

    unsigned int Year = hex & MaskYear; //AND Bit Operation
    Year = Year >> 9; //Bitshift to right position

    sprintf(dateAr,"%02u.%02u.%4u", DayOfMonth,MonthOfYear, 1980+Year);
    return dateAr;
}

int main(void)
{
    char dateAr[11];
    unsigned int hex=0x1010; //Random :)

    printf("%s\n" , fat_dir_date(dateAr,hex))

    return 0;
}

【讨论】:

  • 是的,可能会更好!!!为了安全起见,最好不要使用 printf 和公司!
猜你喜欢
  • 1970-01-01
  • 2017-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-22
  • 2020-09-03
  • 1970-01-01
相关资源
最近更新 更多