Cho các khai báo sau:
Void *tongquat;
Int *nguyen;
Char *kitu;
Phép gán nào là không hợp lệ:
Trả lời:
Đáp án đúng: B
Trong C/C++, kiểu `void *` là một kiểu con trỏ đặc biệt, nó có thể trỏ đến bất kỳ kiểu dữ liệu nào. Do đó, ta có thể gán một con trỏ kiểu khác cho `void *` một cách an toàn mà không cần ép kiểu. Tuy nhiên, khi gán ngược lại (từ `void *` sang một kiểu con trỏ cụ thể), ta cần ép kiểu tường minh để trình biên dịch biết kiểu dữ liệu mà con trỏ `void *` đang trỏ tới.
Xét các phương án:
A. `tongquat = nguyen;` Hợp lệ vì gán con trỏ `int *` cho `void *`.
B. `*nguyen = *tongquat;` Không hợp lệ vì `tongquat` là `void *`, cần ép kiểu về `int *` trước khi giải tham chiếu. Ví dụ: `*nguyen = *(int*)tongquat;` mới đúng.
C. `kitu = (char) tongquat;` Không hợp lệ. Phép ép kiểu `(char)` sẽ chuyển giá trị của con trỏ `tongquat` thành kiểu `char`, sau đó gán giá trị `char` này cho `kitu`. `kitu` là một con trỏ `char *`, phải nhận một địa chỉ, không phải một giá trị `char`. Phải ép kiểu con trỏ `tongquat` về `char*` trước khi gán: `kitu = (char*)tongquat;`
D. `tongquat = kitu;` Hợp lệ vì gán con trỏ `char *` cho `void *`.
Vậy, phương án B và C đều không hợp lệ, nhưng câu hỏi chỉ yêu cầu chọn một đáp án, và đáp án B thể hiện rõ hơn về lỗi gán giá trị không tương thích giữa các kiểu dữ liệu khi giải tham chiếu con trỏ `void *` mà không ép kiểu. Tuy nhiên, vì phương án C cũng sai nên ta chọn B là đáp án sai rõ ràng hơn.