Creating a list and struct arrays using C [duplica

2019-08-12 23:03发布

I'm currently starting out with C so I thought I'd try creating my own custom list. Here's the code:

#include <stdio.h>

struct list {
    char data[10];
    struct list *n;
};

void clist(struct list *a) {
    int j=(sizeof(a)/sizeof(a[0]));
    j--;    
    for(int i=0; i<j-1; i++) {
        struct list *next=&a[i+1];
        a[i].n=next; 
    }
}

int main() {

    struct list first = {.data="one", .n=NULL};
    struct list second = {.data="two", .n=NULL};
    struct list third = {.data="three", .n=NULL};

    struct list arr[] = {first, second, third}; 
    struct list *p=&arr[0];

    clist(p);

    struct list looper = first;

    while(looper.n!=NULL) {
        printf("%s ", looper.data);
        looper = *looper.n;
    }

    return 0;
}

So basically I have a struct that saves a char array and a pointer. I initialize them and then I try to link them together by giving it to the clist method. There lies the problem: it seems clist isn't getting anything useful as the variable j stays at 0. If I do the whole size calculation before giving the array to the clist method, I'm getting the correct 3 as a result. Why is that?

2条回答
来,给爷笑一个
2楼-- · 2019-08-12 23:26

Your code has several errors.

The first one is that inside function clist expression

sizeof(a)/sizeof(a[0])

is equivalent to

sizeof( struct list * ) / sizeof( struct list )

and will be equal to 0 because there are used integer values and the size of the pointer is less than the size of the pointed structure object.

You need expicitly pass the size of the array to the function. But even the variable j will be indeed equal to the size of the array this code in the body of the function is invalid

j--;    
for(int i=0; i<j-1; i++) {
    struct list *next=&a[i+1];
    a[i].n=next; 
}

Let's assume that the array has two elements. In this case initial value of j will be also equal to 2. After statement

j--;    

it will be equal to 1 and inside the loop

for(int i=0; i<j-1; i++) {

condition

i<j-1

will be evaluated to false. So the loop will not be executed and the list will not be built.

Also this loop in main

while(looper.n!=NULL) {
    printf("%s ", looper.data);
    looper = *looper.n;
}

will not display the data member of the last element because the last element has data member n equal to NULL.

I suggest the following modification of your program

#include <stdio.h>

struct list 
{
    char data[10];
    struct list *next;
};

void clist( struct list *a, size_t n ) 
{
    for( size_t i = 0, j = 1; j < n; ++i, j++ )
    {        
        ( a + i )->next = a + j; 
    }
}

int main( void )
{
    struct list first  = { .data="one",   .next = NULL };
    struct list second = { .data="two",   .next = NULL };
    struct list third  = { .data="three", .next = NULL };

    struct list arr[] = { first, second, third }; 

    clist( arr, sizeof( arr ) / sizeof( *arr ) );

    for ( struct list *first = arr; first != NULL;  first = first->next ) 
    {
        printf( "%s ", first->data);
    }


    return 0;
}

Its output is as it is expected

one two three
查看更多
Anthone
3楼-- · 2019-08-12 23:40

In C, array parameters are treated as pointers . So the expression sizeof(a)/sizeof(a[0]) becomes sizeof(int *)/sizeof(int).

So what you are essentially getting is (how big your address is) / (size of integer)

The solution to this would be to send the number of elements in array a as another parameter to the function.

查看更多
登录 后发表回答