结构指针-使用指针访问结构数组

时间:2018-12-16 11:39:04

标签: c pointers struct

我有一个简单的程序:

#include <stdio.h>

struct time
{
    int hours ;
    int minutes ;
    int seconds ;
} t[2] = {1,2,3,4,5,6};

int main() {    
    struct time *tt = t;
    printf("%d\n", (*tt));
    printf("%d", *(tt+1));
}

现在预期的输出应该是:

1
4

但是我得到的输出是2个完全相同的内存地址。我将此程序发送给其他人,有些人具有预期的输出,但有些人没有。我认为这是C或GCC版本的问题。它可以解决吗?为什么在我的C版本中会发生这种情况?

最奇怪的是,即使我取消了指针的引用,它仍然会打印一些地址。这怎么可能?

另一方面,如果我将程序更改为此:

$include <stdio.h>

struct time
{
    int hours ;
    int minutes ;
    int seconds ;
} t[2] = {1,2,3,4,5,6};

int main() {    
    struct time *tt = t;
    printf("%d\n", (*tt).hours);
    printf("%d", (*(tt+1)).hours);
}

它将打印预期的输出。

对此行为有何解释?谢谢。

3 个答案:

答案 0 :(得分:2)

问题不在编译器中,而是您对C的理解。让我们使用GCC版本7.3.0(Ubuntu 7.3.0-27ubuntu1〜18.04)进行编译:

% gcc struct_time.c      
struct_time.c: In function ‘main’:
struct_time.c:12:14: warning: format ‘%d’ expects argument of type ‘int’, 
          but argument 2 has type ‘struct time’ [-Wformat=]
     printf("%d\n", (*tt));
             ~^     ~~~~~
struct_time.c:13:14: warning: format ‘%d’ expects argument of type ‘int’,
          but argument 2 has type ‘struct time’ [-Wformat=]
     printf("%d", *(tt+1));
             ~^   ~~~~~~~

您的格式为%d,它期望将int作为相应的参数,并且您要传入struct time。程序的行为是不确定的,因为转换说明符与实际参数的类型不匹配。

位置在内存中并不重要-它们的类型也很重要。尽管tt[0]的地址与tt[0].hours相同,但是它们具有不同的类型。在一个中,您需要整个结构,在另一个中,您需要第一个成员中包含的值。

答案 1 :(得分:1)

您的代码无效。这是您的编译器应产生的错误(也许您没有启用警告?):

error: format specifies type 'int' but the argument has type 'struct time' [-Werror,-Wformat]
    printf("%d\n", (*tt));

您根本无法编写这样的代码,然后抱怨其行为。您告诉printf()传递整数,然后传递结构。什么都可能发生。

要获得加分,您会遇到样式问题,合理的编译器也会警告您:

error: suggest braces around initialization of subobject [-Werror,-Wmissing-braces]
} t[2] = {1,2,3,4,5,6};

那是因为您要用一个数字列表来初始化2个结构。应该是{{1,2,3},{4,5,6}}

答案 2 :(得分:0)

它的行为正常,因为数组用作指针(100%正常)

所以tt指向第一个数组元素(索引为0),tt + 1指向第二个数组元素(索引1)。

当您向该指针添加一个指针(并且该指针属于该结构的类型的指针)时,结果指针将引用该类型的下一个结构。

如果取消引用结构或联合的指针,请使用->

(*tt).hours == tt -> hours(tt + 1).hours == (tt + 1) -> hours