2013-07-22 47 views
5

Tôi đang đọc giải pháp cho sự cố trong sách Cracking the Coding interview (Q 1.2). Mục đích là để thực hiện một hàm void revers(char* str) trong C để đảo ngược chuỗi kết thúc null.Trong C, địa chỉ của con trỏ có phải là 0 không?

Mã giải pháp trông giống như sau:

void reverse(char *str) 
{ 
    char* end=str; 
    char tmp; 
    if(str) 
    { 
     while(*end) 
     { 
      end++; 
     } 
     end--; 
     //code to reverse 
    } 
} 

Ở đây, str chứa được đúng địa chỉ? Và if(str) sẽ chỉ đánh giá là false nếu str0, phải không?

Vì vậy, những gì tôi đang nói là, là không có cơ hội mà str sẽ chứa địa chỉ 0x0000, do đó đánh giá if(str)-false?

+0

Tôi có thể giới thiệu bạn đến câu trả lời của tôi [ở đây] (http://stackoverflow.com/questions/17462299/initializing-variable-at-address-zero-in-c/17462496#17462496) liên quan đến một câu hỏi tương tự ? – Nobilis

+1

Không, trừ khi bạn tự vượt qua 'str' bằng 0 cho hàm. –

+0

Chạy lệnh này: 'char * p; printf ("% p", p); 'để trả lời câu hỏi của bạn. :) – ludesign

Trả lời

2

Không có cơ hội như vậy, trừ khi bạn vượt qua con trỏ NULL cho hàm.

Trong C không có loại boolean cho đến khi nó được giới thiệu trong C99. Bất kỳ hoạt động logic nào (bao gồm điều kiện) kiểm tra giá trị bằng 0, bất kể loại thực của nó là gì.

+1

Làm thế nào để bạn biết rằng 'reverse()' không được gọi với một con trỏ 0? –

+0

Tất nhiên, ý tôi là nếu bạn vượt qua một con trỏ hợp lệ. Tôi sẽ sửa một câu trả lời để làm rõ. –

+0

Rất tiếc, có vẻ như tôi đã hiểu nhầm câu hỏi. Xin lỗi vì chuyện đó. –

1

Nếu bạn đang yêu cầu tôi nên kiểm tra xem ai đó có truyền con trỏ NULL vào hàm của tôi không thì câu trả lời là CÓ.

+0

Tôi không đồng ý. Nó không phải là trách nhiệm chức năng để kiểm tra xem nó có được tham số hợp lệ hay không. Nếu ai đó đã thực hiện một "cuộc gọi sai" bằng cách chuyển một con trỏ 'NULL', thì hãy để chương trình gặp sự cố. Tất nhiên, điều này phụ thuộc nhiều vào bối cảnh, vì vậy nó có thể không áp dụng cho tình huống của người đăng. – Xaqq

+0

@Xaqq nó sẽ phụ thuộc vào việc chức năng này được dự định được gọi trực tiếp bởi các lập trình viên khác hay chỉ phục vụ như một hàm trợ giúp nội bộ. Khi nghi ngờ sai lầm về mặt thận trọng. – DuncanACoulter

4
if(str) 

là tương đương với

if(str != NULL) 

hoặc

if(str != 0) 

thử nghiệm này không phải là để kiểm tra xem str có địa chỉ của 0, nó kiểm tra cho dù str là một con trỏ null.

Lưu ý rằng một con trỏ rỗng không cần phải có địa chỉ 0, tiêu chuẩn chỉ đảm bảo rằng một con trỏ rỗng là không đồng đều với bất kỳ con trỏ không null nào khác.

C11 6.3.2.3 Pointers

Một biểu thức hằng số nguyên với giá trị 0, hoặc như một biểu đúc gõ void *, được gọi là một con trỏ constant.66 null) Nếu một con trỏ null hằng số được chuyển thành kiểu con trỏ , con trỏ kết quả, được gọi là con trỏ rỗng, được đảm bảo để so sánh không bằng với con trỏ với bất kỳ đối tượng hoặc hàm nào.

1

Có thể có nếu str là con trỏ NULL trên bất kỳ kiến ​​trúc nào đã đặt trước địa chỉ 0x000 cho null pointer.

1

if(str) được thêm vào để kiểm tra xem đường có cấp phát bộ nhớ hay không. Thực hành tốt nhất là khởi tạo một con trỏ đến NULL khi nó được khai báo.

ở trên là tương đương với

if(str != NULL) 
{ 

} 
2

Vì vậy, những gì tôi đang nói là, là không có cơ hội mà str sẽ chứa 0x0000 địa chỉ, do đó đánh giá if (str) để sai?

Có, có: trong trường hợp bạn gọi reverse() bằng con trỏ rỗng, nó sẽ đánh giá là sai.

Điều này được sử dụng làm lưới an toàn, trong trường hợp xảy ra reverse() được gọi với con trỏ rỗng, để mã không truy cập bộ nhớ không hợp lệ khi thực sự đảo ngược chuỗi.

3

Con trỏ về mặt lý thuyết 0x0 là hợp lệ, nhưng tất cả ngày nay trình biên dịch sẽ không cung cấp cho bạn địa chỉ ảo 0, vì nó được dành riêng để biểu thị con trỏ null (con trỏ đến không có gì).

Một số hạt nhân vẫn có thể sử dụng nó, nhưng trừ khi bạn đang viết một cái gì đó rất thấp ở hạt nhân rất hiếm, bạn có thể giả định rằng 0x0 không trỏ đến bất kỳ bộ nhớ nào.

hằng số NULL được tạo cho giá trị cho con trỏ không trỏ bất kỳ thứ gì. Bây giờ NULL luôn coi trọng 0.

13

str không thực sự chứa một địa chỉ (đó là một con trỏ đến char), và if(str) sẽ đánh giá false iff str bằng với con trỏ null.

Lưu ý rằng con trỏ null không được yêu cầu theo tiêu chuẩn để chỉ đến địa chỉ 0; tuy nhiên, tiêu chuẩn bắt buộc rằng một giá trị bằng của 0 khi được sử dụng trong ngữ cảnh con trỏ phải được trình biên dịch giải thích là địa chỉ của con trỏ null - bất kỳ thứ gì có thể.

Điều này có nghĩa là thử nghiệm if(p == 0) được đảm bảo luôn luôn giống như if(p == NULL). Ngoài ra, điều kiện if(p) được đảm bảo luôn luôn giống như if(p != 0).

Kết luận: mã của bạn sẽ luôn phát hiện con trỏ rỗng, nhưng không giống như con trỏ trỏ đến địa chỉ 0 (mặc dù trong thực tế bạn sẽ thấy rằng nó thường là).

1

Ở đây, str có địa chỉ đúng?

Có. Nó là char *. Giá trị của nó đại diện cho địa chỉ của số char.

Và nếu (str) sẽ chỉ đánh giá sai nếu str là 0, phải không?

Có.

không có cơ hội nào str sẽ chứa địa chỉ 0x0000, do đó đánh giá nếu (str) thành sai?

Điều này là hoàn toàn có thể. Chỉ cần gọi hàm với giá trị này.

char * myCharPointer = 0; 
reverse(myCharPointer); 

Tôi chưa bao giờ sử dụng kiểu này. Tôi thích sử dụng NULL, được đảm bảo bởi tiêu chuẩn C là tương đương. Tôi thích NULL vì nó có tính biểu cảm hơn và giúp tách các giá trị số nguyên thông thường khỏi các địa chỉ.

char * myCharPointer = NULL; 
reverse(myCharPointer); 

Xem thêm những câu hỏi liên quan:

0

Tuyên bố

if (str) 

tương đương với

if (str != 0) 

mà lần lượt được giải thích bởi trình biên dịch như

if (str != null-pointer-value-for-char-pointer-type) 

Tức là nó không có gì để làm với "địa chỉ số không" ở tất cả. Trình biên dịch được yêu cầu để nhận ra bối cảnh con trỏ và thực hiện so sánh với giá trị con trỏ null phụ thuộc vào loại char *. Cái sau sẽ được thể hiện bằng vật lý bởi một giá trị địa chỉ phụ thuộc thực hiện, không nhất thiết là địa chỉ 0.

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