2013-12-18 122 views
2

好吧,我得到这个代码:指针结构的阵列的

#include <stdio.h> 
#include <stdlib.h> 

#define ARR_SIZE 5 

struct mys 
{ 
    double first; 
    unsigned long second; 
    char str[10]; 
}; 

int main(int argc, char** argv) 
{ 
    size_t i = 0; 
    struct mys thes[ARR_SIZE] = 
     { 
      {1.1, 1, "First"}, 
      {2.2, 2, "Second"}, 
      {3.3, 3, "Third"}, 
      {4.4, 4, "Fourth"}, 
      {5.5, 5, "Fifth"} 
     };//load array of structures with values 

    for (; i < ARR_SIZE; ++i) 
     fprintf(stdout, "second->%lu\n", thes[i].second);//loop through array thes and print element second 

    return (EXIT_SUCCESS); 
} 

现在,我想所谓的第二零元素THES的元素的地址,然后用它来遍历将它们排列并打印每个第二个元素。

#include <stdio.h> 
#include <stdlib.h> 

#define ARR_SIZE 5 

struct mys 
{ 
    double first; 
    unsigned long second; 
    char str[10]; 
}; 

int main(int argc, char** argv) 
{ 
    size_t i = 0; 
    unsigned long * ptr = NULL;//pointer to unsigned long 
    struct mys thes[ARR_SIZE] = 
     { 
      {1.1, 1, "First"}, 
      {2.2, 2, "Second"}, 
      {3.3, 3, "Third"}, 
      {4.4, 4, "Fourth"}, 
      {5.5, 5, "Fifth"} 
     }; 

    //first loop 
    for (; i < ARR_SIZE; ++i) 
     fprintf(stdout, "second->%lu\n", thes[i].second); 

    ptr = &thes[0].second;//get the address of the second element of the zero'th array structure and store it in ptr 

    // Now I want to use the above pointer ptr to loop through the array thes and display the second element like I did above, but I can't manage to do that. 
    //The output of this loop should be the same as the first loop 

    return (EXIT_SUCCESS); 
} 

所以,我已经实现了指针,但我有问题编写第二个循环的代码。任何帮助表示赞赏。

+0

@itwasntpete我的代码是C :) – user2699298

回答

4
for (; i < ARR_SIZE; ++i) 
    fprintf(stdout, "second->%lu\n", *(unsigned long *)((char *)ptr + i * sizeof(struct mys))); 
+0

所有的投射看起来比我想象的还要糟糕...... – StoryTeller

+0

@StoryTelle而不是无符号长* ptr你可以使用struct mys * ptr = thes;并在print语句中使用ptr-> second,然后简单地增加ptr:++ ptr。这会更简单。 –

+0

祝贺...... **确切** 4000分:) – user1810087

0

你不能那样做。至少不是简单的。你的数组是结构。他们连续坐在记忆中。增加指针ptr而不进行任何强制转换,会将其移动到内存块中的下一个long地址,该地址不在下一个结构中,而是在其旁边。

2

您的要求没有多大意义:您拥有的只是一个指向unsigned long的指针,没有任何信息可以确定所涉及的数字是否属于某个特定的结构数组的一部分。

可以这样做,使用指针技巧,但它肯定不是直截了当的,或者我在一般编程中推荐的东西。

为什么你需要这样做?

我会通过计算指针备份到结构做到这一点,使迭代清洁:

const struct mys *mysp = (struct mys *) ((char *) ptr - 
             offsetof(struct mys, second)); 

它使用offsetof到“备份”从指针结构成员的结构本身。

+0

我只是想了解它是如何完成的,我没有计划在通用编程中使用它。 – user2699298

3

你不能(或者更重要的是不应该)那样做。你应该做的是安全的数组的第一个元素的指针,所以你可以迭代它。

struct mys* ptr; 

ptr = &thes[0]; 

for(int i=0; i<10; i++, ptr++) 
    fprintf(stdout, "second->%lu\n", ptr->second); 

,但你必须要小心,因为没有单元结束,并iteratig [0-10)只对符合ptr = &thes[0];开始的情况下。

1

这是对弗拉德解决方案的一点解释。这是写在C++(在for循环中声明的变量):

我们铸造了ptrunsigned char*(字节PTR),再由mys占地将其设置为下一个元素的second的字节数增加它。然后我们将它转​​换回ulong,并将指针取消引用以获取其值。

ptr = &thes[0].second; //get the address of the second element of the zero'th array structure and store it in ptr 
for (i = 0; i < ARR_SIZE; ++i) 
{ 
    unsigned char* pointer_as_byte = (unsigned char*)ptr; // get ptr as byte ptr to increment it 
    unsigned char* pointer_offset = pointer_as_byte += (i * sizeof(struct mys)); // next structure's [second] field 
    unsigned long* final_pointer = (unsigned long*)pointer_offset; // cast byte ptr back to ulong ptr 

    fprintf(stdout, "second->%lu\n", *final_pointer); 
} 

或者其他方式,也许是更容易理解:

ptr = &thes[0].second;//get the address of the second element of the zero'th array structure and store it in ptr 
for (i = 0; i < ARR_SIZE; ++i) 
{ 
    mys* pointer_as_mys = (mys*)ptr; // get ptr as mys pointer 
    pointer_as_mys += i; // increment is to i'th mys.second 
    ptr = (unsigned long*)pointer_as_mys; // cast it back to save the offset to ptr 

    fprintf(stdout, "second->%lu\n", *ptr); 
} 
2

当然,你可以做到这一点。不好,没用,但可以通过操纵你的指针来完成。

了解,看看你的内存结构阵列的布局,让我们说你的阵列开始地址为0x0000:

0x0000 : array[0].first - first part of mys.first 
0x0004 : array[0].first - second part of mys.first 
0x0008 : array[0].second 
0x000c : array[0].str[0-3] - first four elements of your string 
0x0010 : array[0].str[4-7] - next four elements 
0x0014 : array[0].str[8-9] - last two elements and padding 
0x0018 : array[1].first - second element ! 

...

所以你可以看到,在它们之间字段中的两个连续元素的数组具有结构的大小。

要遍历内存中几个连续结构的相同字段,您只需要声明一个指向第一个结构元素的指针,并通过结构的大小增加它以访问下一个元素的相同字段阵列。

在你的情况下,它会再看看这样的:

int i; 
struct mys my_array[SIZE]; 
char* my_iterator = &my_array[0].second; 
for(i=0; i<SIZE; i++) { 
    fprintf(stdout, "second->%lu\n", *(unsigned long*)my_iterator); 
    my_iterator += sizeof(mys); 
} 

但这真的不好看,你就可以改善了一点,但仍然是不指针玩的时候它不是好的做法需要。

int i; 
struct mys my_array[SIZE]; 
strut mys* my_iterator = &my_array[0].second; 
for(i=0; i<SIZE; i++, my_iterator++) { 
    fprintf(stdout, "second->%lu\n", *(unsigned long*)my_iterator); 
}