Lưu ý: Câu trả lời này áp dụng cho ngôn ngữ C, không phải C ++.
Con trỏ Null
Hằng số nguyên 0
có nghĩa khác nhau tùy thuộc vào ngữ cảnh mà nó được sử dụng. Trong mọi trường hợp, nó vẫn là một hằng số nguyên với giá trị 0
, nó chỉ được mô tả theo các cách khác nhau.
Nếu một con trỏ đang được so sánh với chữ không đổi 0
, thì đây là kiểm tra xem con trỏ có phải là con trỏ không. Điều này 0
sau đó được gọi là một hằng con trỏ null. Tiêu chuẩn C định nghĩa rằng 0
truyền tới loại void *
vừa là con trỏ null vừa là con trỏ null.
Ngoài ra, để giúp dễ đọc, macro NULL
được cung cấp trong tệp tiêu đề stddef.h
. Tùy thuộc vào trình biên dịch của bạn, nó có thể có thể #undef NULL
và xác định lại nó thành một cái gì đó lập dị.
Do đó, đây là một số cách hợp lệ để kiểm tra con trỏ null:
if (pointer == NULL)
NULL
được định nghĩa để so sánh bằng với một con trỏ null. Đó là việc thực hiện được định nghĩa định nghĩa thực sự NULL
là gì, miễn là nó là một con trỏ null hợp lệ.
if (pointer == 0)
0
là một đại diện khác của hằng số con trỏ null.
if (!pointer)
Câu if
lệnh này hoàn toàn kiểm tra "không phải là 0", vì vậy chúng tôi đảo ngược điều đó thành "0".
Sau đây là các cách INVALID để kiểm tra con trỏ null:
int mynull = 0;
<some code>
if (pointer == mynull)
Đối với trình biên dịch, đây không phải là kiểm tra con trỏ null, mà là kiểm tra đẳng thức trên hai biến. Điều này có thể hoạt động nếu mynull không bao giờ thay đổi mã và tối ưu hóa trình biên dịch liên tục gập 0 thành câu lệnh if, nhưng điều này không được đảm bảo và trình biên dịch phải tạo ra ít nhất một thông báo chẩn đoán (cảnh báo hoặc lỗi) theo Tiêu chuẩn C.
Lưu ý rằng con trỏ null trong ngôn ngữ C là gì. Nó không quan trọng trên kiến trúc cơ bản. Nếu kiến trúc cơ bản có giá trị con trỏ null được xác định là địa chỉ 0xDEADBEEF, thì tùy thuộc vào trình biên dịch để sắp xếp mớ hỗn độn này.
Như vậy, ngay cả trên kiến trúc ngộ nghĩnh này, các cách sau đây vẫn là những cách hợp lệ để kiểm tra con trỏ null:
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
Sau đây là các cách INVALID để kiểm tra con trỏ null:
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
vì những thứ này được xem bởi một trình biên dịch như là so sánh bình thường.
Nhân vật Null
'\0'
được định nghĩa là một ký tự null - đó là một ký tự có tất cả các bit được đặt thành 0. Điều này không có gì để làm với con trỏ. Tuy nhiên, bạn có thể thấy một cái gì đó tương tự như mã này:
if (!*string_pointer)
kiểm tra nếu con trỏ chuỗi đang trỏ vào một ký tự null
if (*string_pointer)
kiểm tra nếu con trỏ chuỗi đang trỏ vào một ký tự không null
Đừng nhầm lẫn với con trỏ null. Chỉ vì cách biểu diễn bit là như nhau và điều này cho phép một số trường hợp giao nhau thuận tiện, chúng không thực sự giống nhau.
Ngoài ra, '\0'
là (như tất cả các ký tự bằng chữ) là một hằng số nguyên, trong trường hợp này có giá trị bằng không. Vì vậy, '\0'
hoàn toàn tương đương với một 0
hằng số nguyên không được cung cấp - sự khác biệt duy nhất là ở mục đích mà nó truyền tải tới người đọc con người ("Tôi đang sử dụng điều này như một ký tự null.").
Người giới thiệu
Xem Câu hỏi 5.3 của Câu hỏi thường gặp về comp.lang.c để biết thêm. Xem pdf này cho tiêu chuẩn C. Kiểm tra các phần 6.3.2.3 Con trỏ, đoạn 3.