Cách lấy số lượng phần tử trong mảng struct

product san_pham[MAX]
{
product("But bi", 3000, 34),
product("But chi", 2000, 65),
product("Tay", 5000, 25),
product("Got but chi", 3500, 50),
product("Vo", 7000, 33),
product("Giay A4", 500, 130),
};

Em có mảng struct như này, cần lấy ra số lương phần tử có trong mảng thì có cách nào k ạ?
Em cảm ơn ạ

không thể. vì những lý do sau

  1. san_pham đã được cấp phát sizeof(product) * MAX. nên nếu xài sizeof(san_pham) / sizeof(product) thì nó sẽ ra MAX (trừ khi MAX bằng với số product bạn đã init)

  2. nếu bạn chạy loop để kiểm tra các biến có được init thì có 2 trường hợp
    2.1 Nếu san_pham là global variable, thì khi này struct sẽ được khởi tạo bằng giá trị mặc định. ví dụ int thì là 0, boolean là false. bạn có thể lợi dụng cách này để đếm
    2.2 nếu khởi tạo trong một scope bất kỳ không phải global -> trên stack, thì không có cách nào kiểm tra, vì bạn đang khởi tạo struct trên stack, và khi này các giá trị sẽ là ngẫu nhiên. không có cách nào bạn check là struct 1 đã được init hay chưa cả.

mảng object trong C++ thì mỗi object đều được init bằng default ctor mà :V Lý do là vì nó sẽ được tự động hủy khi ra khỏi phạm vi của nó, mà khi hủy mảng thì nó phải gọi hàm hủy cho từng phần tử đã được khởi tạo luôn, nhưng lúc compile time làm sao biết phần tử nào sẽ được init lúc runtime mà gọi hàm hủy cho đúng. Vì vậy phải gọi hàm hủy cho tất cả các phần tử, dẫn tới khi khai báo mảng object tất cả các obj phải được khởi tạo. Chỉ với phần tử có kiểu nguyên thủy thì mới ko cần ctor/dtor thôi.

mà ở đây đã gọi ctor cho mảng san_pham bằng {...}aggregate initialization :V :V trong đó nó có ghi

For a non-union aggregate, each element that is not an explicitly initialized element is initialized as follows:

  • If the element has a default member initializer, the element is initialized from that initializer. (since C++11)
  • Otherwise, if the element is not a reference, the element is copy-initialized from an empty initializer list.
  • Otherwise, the program is ill-formed.

nghĩa là từng phần tử ko được khởi tạo tường minh thì sẽ được copy-initialized bằng empty initializer list :V :V chắc là gọi default ctor. Mà nếu default ctor được viết là product() {} mà nếu phần tử chuỗi, tạm gọi là name, ko phải là std::string mà là const char* thì name mang giá trị rác thật, tuy có gọi default ctor nhưng default ctor ko khởi tạo const char* name nên thành ra cũng như ko khởi tạo :V Nếu khai báo biến name theo kiểu default member initializer const char* name{}; thì ok, default ctor sẽ khởi tạo name = 0 thì check được :V

(sao tôi thử thấy explicitly defaulted default ctor, aka viết theo kiểu product() = default; nó lại gán 0 cho const char* lẫn int luôn nhỉ :V mà ko tìm thấy chỗ nào trong doc viết, chắc là ngẫu nhiên)
ồ tôi tìm ra rồi nếu class/struct product đó là trivial thì class/struct được viết product() = default vẫn giữ được là trivial class (trong khi product() {} được xem là user-provided ctor, nên class này ko còn trivial nữa), nên init với empty init list nó sẽ được value initialized, sẽ zero-initialized cho từng phần tử kiểu nguyên thủy :cold_face:

tóm lại để chắc ăn thì viết cái default ctor cho product đàng hoàng nữa là kiểm tra được:

class product {
public:
  product() : name{}, value1{}, value2{} {}
};

hoặc nếu xài C++11 trở lên thì

class product {
public:
  product() = default;

private:
  <kiểu chuỗi> name{}; // xài default member initializer cho từng phần tử trong product
  int value1{};
  int value2{};
};

rồi check san_pham[i].name là chuỗi trống hay là NULL là được. Với điều kiện san_pham[i] đã khởi tạo thì name phải ko là chuỗi trống hay NULL được :V :V

1 Like

Đã dùng C++ thì sao không dùng std::vector luôn cho rồi?

Code:
std::vector<product> san_pham 
{
product("But bi", 3000, 34),
product("But chi", 2000, 65),
product("Tay", 5000, 25),
product("Got but chi", 3500, 50),
product("Vo", 7000, 33),
product("Giay A4", 500, 130),
};

auto size = san_pham.size();

Hoặc là bỏ luôn cái MAX đi:

Code:
product san_pham[] = 
{
product("But bi", 3000, 34),
product("But chi", 2000, 65),
product("Tay", 5000, 25),
product("Got but chi", 3500, 50),
product("Vo", 7000, 33),
product("Giay A4", 500, 130),
};

auto size = sizeof(san_pham)/sizeof(*san_pham);

Ưu/nhược điểm mỗi cách thì tự tìm hiểu nha bạn.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?