K&R练习:多维数组转换为指针数组

发布于 2024-07-13 14:00:37 字数 606 浏览 4 评论 0原文

练习(5-9): 使用指针而不是索引重写例程day_of_year

static char daytab[2][13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

/* day_of_year: set day of year from month and day */
int day_of_year(int year, int month, int day)
{
    int i, leap;

    leap = (year%4 == 0) && (year%100 != 0) || (year%400 == 0);
    for (i = 1; i < month; i++)
    {
        day += daytab[leap][i];
    }

    return day;
}

我可能只是累了,没有思考,但是如何实际创建一个带有指针的多维数组呢?

我可能可以弄清楚函数的其余部分,但我无法正确理解语法。

Exercise (5-9):
Rewrite the routines day_of_year with pointers instead of indexing.

static char daytab[2][13] = {
    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
    {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

/* day_of_year: set day of year from month and day */
int day_of_year(int year, int month, int day)
{
    int i, leap;

    leap = (year%4 == 0) && (year%100 != 0) || (year%400 == 0);
    for (i = 1; i < month; i++)
    {
        day += daytab[leap][i];
    }

    return day;
}

I may just be tired and not thinking, but how does one actually create a multidimensional array with pointers?

I could probably figure out the rest of the function, but I can't get the syntax right.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夏了南城 2024-07-20 14:00:37

您只是被要求修改 day_of_year 例程,而不是 daytab 声明。 我会按原样保留该数组,并修改 day_of_year 如下:

/* day_of_year: set day of year from month and day */
int day_of_year(int year, int month, int day)
{
    char* p = (year%4 == 0) && (year%100 != 0) || (year%400 == 0) ? 
        daytab[0] : daytab[1];

    p++;
    for (i = 1; i < month; i++, p++)
    {
        day += *p;
    }

    return day;
}

如果您希望 p 的声明更短,您可以这样做:

    char* p = daytab[(year%4 == 0) && (year%100 != 0) || (year%400 == 0)];

如果您仍然想要也删除该访问权限:

    char* p = *(daytab + ((year%4 == 0) && (year%100 != 0) || (year%400 == 0)));

有人可能会说它看起来很难看,但是嘿,这就是指针所得到的结果。

You're just asked to modify the day_of_year routine, not the daytab declaration. I would leave that array as-is, and modify day_of_year as follows:

/* day_of_year: set day of year from month and day */
int day_of_year(int year, int month, int day)
{
    char* p = (year%4 == 0) && (year%100 != 0) || (year%400 == 0) ? 
        daytab[0] : daytab[1];

    p++;
    for (i = 1; i < month; i++, p++)
    {
        day += *p;
    }

    return day;
}

If you want to the declaration of p to be shorter, you can do this:

    char* p = daytab[(year%4 == 0) && (year%100 != 0) || (year%400 == 0)];

If you still want to remove that access, too:

    char* p = *(daytab + ((year%4 == 0) && (year%100 != 0) || (year%400 == 0)));

One might argue that it looks ugly, but hey, that's what you get with pointers.

oО清风挽发oО 2024-07-20 14:00:37

有两种方法可以处理这个问题:

第一种是模拟 C 实际处理多维数组的方式,也就是说根本不这样做。 char[4][4] 实际上只是 char[16] 周围的语法糖。 您可以创建一个指向 16 字节数组的指针(在本例中),并且您得到了相同的结果。

另一种是创建一个指向指针的指针。 按照前面的示例:

char **foo = malloc(sizeof(char *) * 4);
for(int i = 0; i < 4; ++i)
    foo[i] = malloc(sizeof(char) * 4);
foo[0][0] = bar;

There are two ways of handling this:

The first is to emulate the way that C actually handles multidimensional arrays, which is to say not at all. char[4][4] is really just syntactical sugar around char[16]. You can create a pointer to an array of 16 bytes (in this case) and you've got the same thing.

The other is to create a pointer to a pointer. Following the previous example:

char **foo = malloc(sizeof(char *) * 4);
for(int i = 0; i < 4; ++i)
    foo[i] = malloc(sizeof(char) * 4);
foo[0][0] = bar;
忆伤 2024-07-20 14:00:37

以下完整的程序将满足您的要求。 我已将您的数组转换为字符指针(字符串)并散布闰年值。 我还删除了虚拟条目并调整了循环。

该测试程序缺乏严重的错误检查,因此不要指望它能够处理不可靠的参数。

#include <stdio.h>

static char *daytab =
    "\x1f\x1f\x1c\x1d\x1f\x1f"
    "\x1e\x1e\x1f\x1f\x1e\x1e"
    "\x1f\x1f\x1f\x1f\x1e\x1e"
    "\x1f\x1f\x1e\x1e\x1f\x1f";

/* day_of_year: set day of year from month and day */
int day_of_year(int year, int month, int day) {
    int i, leap;

    leap = (year%4 == 0) && (year%100 != 0) || (year%400 == 0);
    for (i = 0; i < month-1; i++) {
        day += *(daytab+i*2+leap);
    }

    return day;
}

int main (int argc, char *argv[]) {
    if (argc != 4) {
        printf ("Usage: blah yy mm dd\n");
        return 1;
    }
    printf ("%4.4s/%2.2s/%2.2s -> %04d/%02d/%02d -> %d\n",
        argv[1], argv[2], argv[3],
        atoi (argv[1]), atoi (argv[2]), atoi (argv[3]),
        day_of_year (atoi(argv[1]),atoi(argv[2]),atoi(argv[3])));
    return 0;
}

The following complete program will do what you desire. I've converted your array into a char pointer (string) and interspersed the leap year values. I've also removed the dummy entries and adjusted the loop.

The test program lacks serious error checking so don't expect it to work with dodgy arguments.

#include <stdio.h>

static char *daytab =
    "\x1f\x1f\x1c\x1d\x1f\x1f"
    "\x1e\x1e\x1f\x1f\x1e\x1e"
    "\x1f\x1f\x1f\x1f\x1e\x1e"
    "\x1f\x1f\x1e\x1e\x1f\x1f";

/* day_of_year: set day of year from month and day */
int day_of_year(int year, int month, int day) {
    int i, leap;

    leap = (year%4 == 0) && (year%100 != 0) || (year%400 == 0);
    for (i = 0; i < month-1; i++) {
        day += *(daytab+i*2+leap);
    }

    return day;
}

int main (int argc, char *argv[]) {
    if (argc != 4) {
        printf ("Usage: blah yy mm dd\n");
        return 1;
    }
    printf ("%4.4s/%2.2s/%2.2s -> %04d/%02d/%02d -> %d\n",
        argv[1], argv[2], argv[3],
        atoi (argv[1]), atoi (argv[2]), atoi (argv[3]),
        day_of_year (atoi(argv[1]),atoi(argv[2]),atoi(argv[3])));
    return 0;
}
凉栀 2024-07-20 14:00:37

旧线程,但我实际上有一个不使用索引的解决方案,甚至不使用 [0]。 所以不要

day += daytab[leap][i];

写写

day += *(*(daytab+leap)+i);

Old thread, but I actually have a solution that doesn't use indexing, not even [0]. So instead of writing

day += daytab[leap][i];

write

day += *(*(daytab+leap)+i);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文