2010-11-02 71 views
13

Trong C: Làm thế nào để bạn tìm thấy số phần tử trong một mảng cấu trúc, sau khi gửi nó đến một hàm?C: tìm số phần tử trong một mảng []

int main(void) { 
    myStruct array[] = { struct1, struct2, struct3, struct4, struct5, struct6 }; 
    printf("%d\n", sizeof(array)); 
    printf("%d\n", sizeof(array[0])); 
    f(array); 
} 
void f(myStruct* array) { 
    printf("%d\n", sizeof(array)); 
    printf("%d\n", sizeof(array[0])); 
} 

Vì lý do nào đó printf trong chính hiển thị kết quả khác với printf trong f. Nhu cầu của tôi là biết có bao nhiêu phần tử trong mảng.

+0

Vì 'sizeof()' là toán tử thời gian biên dịch chứ không phải hàm thành viên (như trong C++). – ruslik

Trả lời

18

Bạn không thể.

Bạn phải vượt qua các kích thước để các chức năng, ví dụ:

void f(myStruct* array, size_t siz); 

Cũng cần chú ý rằng trong f mảng là một con trỏ, trong khi ở main nó là một mảng. Mảng và con trỏ là những thứ khác nhau.

+1

Tại sao lại sử dụng 'size_t'? Bạn không thể chỉ sử dụng một số nguyên cho chiều dài mảng, hoặc là không an toàn bằng cách nào đó? –

+2

@Christian Mann: Một số lý do, bao gồm: loại giá trị được trả về bởi 'sizeof' là' size_t'; kích thước mảng không bao giờ có thể là tiêu cực, do đó, nó có ý nghĩa để sử dụng một loại unsigned cho kích thước mảng; 'size_t' được đảm bảo đủ rộng để giữ số byte tối đa có thể được cấp phát cùng một lúc, trong khi' int' không phải là (IOW, nếu một mảng T có thể chứa 2^64 byte, thì 'size_t' được bảo đảm rộng 64 bit, nhưng 'int' chỉ được đảm bảo tối thiểu 16 bit); –

+0

Một giải pháp thay thế cho việc truyền xung quanh là NULL - chấm dứt mảng, một giải pháp được kiểm tra thời gian, nhưng nó chỉ hoạt động nếu bạn có một mảng con trỏ (thường là mảng mảng trong C). –

10

Trong f array là một con trỏ, trong chính array là một mảng.

+5

Và một khi bạn có một con trỏ, bạn không thể xác định số lượng các phần tử. –

0

Bạn không thể cho biết số phần tử trong một mảng trong C một cách nhất quán. Đặc biệt nếu bạn truyền mảng xung quanh thông qua con trỏ.

Thông thường, nếu bạn phải sử dụng kích thước mảng trong hàm, chuyển nó làm tham số cho hàm.

+1

Số phần tử trong mảng luôn được cho bởi 'mảng mảng sizeof/sizeof [0]'. Miễn là mảng là một mảng trung thực-thần, nó rất dễ dàng :) – pmg

1

Bạn phải chuyển dữ liệu đó dưới dạng tham số riêng biệt cho hàm. Trong C và C++ ngay sau khi một mảng được truyền vào một hàm, mảng biến đổi thành một con trỏ. Con trỏ không có khái niệm về số lượng các phần tử trong mảng mà chúng trỏ tới.

Cách phổ biến để lấy kích thước là khai báo mảng và sau đó nhận ngay số phần tử mảng bằng cách chia tổng kích thước theo kích thước của một phần tử. Như thế này:

struct my_struct my_struct_array[] = { 
{"data", 1, "this is data"}, 
{"more data", 2, "this is more data"}, 
{"yet more", 0, "and again more data"} 
}; 
const size_t my_struct_array_count = sizeof(my_struct_array)/sizeof(my_struct_array[0]); 
0

Khi bạn sử dụng sizeof trong main, nó sẽ đánh giá mảng và cung cấp kích thước của mảng thực.

Khi bạn sử dụng sizeof trong f, bạn đã chuyển tên của mảng làm đối số cho hàm, do đó, nó đã phân rã thành con trỏ, vì vậy sizeof cho bạn biết về kích thước của con trỏ. Nói chung, nếu bạn chuyển một mảng vào một hàm, bạn cần phải viết hàm để chỉ làm việc với một kích thước cụ thể của mảng, hoặc thông qua một cách rõ ràng kích thước của mảng để nó hoạt động với một lời gọi cụ thể.

1

Trong đoạn mã trên, hàm f() không có cách nào biết được có bao nhiêu phần tử trong mảng ban đầu của bạn. Đó là một tính năng của ngôn ngữ và không có cách nào xung quanh nó. Bạn sẽ phải vượt qua chiều dài.

1

Khi C reference nói, bạn không thể làm điều này trừ khi phần tử cuối cùng là duy nhất hoặc bạn chuyển một số phần tử mảng cho hàm.

1

bạn phải kết thúc mảng với một giá trị đặc biệt và trong hàm được gọi là bạn phải đếm đến giá trị đó là cách strlen() hoạt động với giá trị NULL '\ 0'.

+0

Đó chắc chắn là một giải pháp, nhưng đó không phải là giải pháp duy nhất. –

+0

bạn đang gửi hàm một con trỏ (một địa chỉ trong bộ nhớ) làm thế nào nó sẽ đếm, nếu nó không biết nó kết thúc ở đâu. Không có loại mảng nào trong C như chúng ta biết trong các ngôn ngữ cao hơn. Bạn có thể tạo một lớp mảng trong C++ cũng lưu trữ kích thước của nó (hoặc sử dụng các lớp đã định nghĩa) – bkilinc

0

Bạn có thể sử dụng định dạng cho mảng của mình. Tôi đang sử dụng các yếu tố chuỗi, nó sẽ làm việc cho struct.

#define NULL "" 
#define SAME 0 

static char *check[] = { 
     "des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256", 
     "blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes", 
     "cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea", 
     "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt", 
     "camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320", 
     "lzo", "cts", "zlib", NULL 
}; // 38 items, excluding NULL 

trong chính()

char **algo = check; 
int numberOfAlgo = 0; 


while (SAME != strcmp(algo[numberOfAlgo], NULL)) { 
    printf("Algo: %s \n", algo[numberOfAlgo++]); 
} 

printf("There are %d algos in the check list. \n", numberOfAlgo); 

Bạn sẽ nhận được kết quả:

Algo: des 
    : 
    : 
Algo: zlib 

There are 38 algos in the check list. 

Ngoài ra, nếu bạn không muốn sử dụng NULL, làm điều này thay vì:

numberOfAlgo = 0; 

while (*algo) { 
    printf("Algo: %s \n", *algo); 
    algo++;   // go to the next item 
    numberOfAlgo++; // count the item 
} 

printf("There are %d algos in the check list. \n", numberOfAlgo); 
0

Như một ví dụ để giải pháp của bạn:

Với

struct contain { 
char* a;  // 
int allowed; // 

struct suit { 
    struct t { 
      char* option; 
      int count; 
    } t; 

    struct inner { 
      char* option; 
      int count; 
    } inner; 
} suit; 
}; 

// ví dụ. khởi

 struct contain structArrayToBeCheck[] = { 
    { 
     .a = "John", 
     .allowed = 1, 

     .suit = { 
      .t = { 
       .option = "ON", 
       .count = 7 
      }, 

      .inner = { 
       .option = "OFF", 
       .count = 7 
      } 
     } 
    }, 
    { 
     .a = "John", 
     .allowed = 1, 

     .suit = { 
      .t = { 
       .option = "ON", 
       .count = 7 
      }, 

      .inner = { 
       .option = "OFF", 
       .count = 7 
      } 
     } 
    }, 
    { 
     .a = "John", 
     .allowed = 1, 

     .suit = { 
      .t = { 
       .option = "ON", 
       .count = 7 
      }, 

      .inner = { 
       .option = "OFF", 
       .count = 7 
      } 
     } 
    }, 
    { 
     .a = "John", 
     .allowed = 1, 

     .suit = { 
      .t = { 
       .option = "ON", 
       .count = 7 
      }, 

      .inner = { 
       .option = "OFF", 
       .count = 7 
      } 
     } 
    } 

}; 

trong chính()

printf("Number of Struct within struct array: %d \n", sizeof(structArrayToBeCheck)/sizeof(struct contain)); 

mang đến cho bạn câu trả lời chính xác.

1

Lưu ý rằng trong mảng main(), tham chiếu đến mảng thực tế và do đó sizeof() đưa ra câu trả lời bắt buộc.

Nhưng khi bạn chuyển nó làm tham số hàm, bạn thực sự chuyển địa chỉ của phần tử đầu tiên của mảng được lưu trữ trong biến con trỏ 'mảng'.
Vì vậy, bây giờ sizeof() cho kích thước của biến con trỏ đó là lý do tại sao nó khác với câu trả lời thực tế.

giải pháp có thể có thể để

1.Declare mảng toàn cầu

2.Pass kích thước mảng như tham số chức năng Hy vọng nó sẽ giúp!

Các vấn đề liên quan