2015-06-19 14 views
5

Các con trỏ ký tự trong C gây nhầm lẫn cho tôi.Lẫn lộn về các ký tự con trỏ trong C

Giả sử chúng ta có con trỏ char, trỏ đến ký tự đầu tiên của chuỗi hằng số.

char *a="ABCD"; 

Sau đó, chúng tôi không thể thay đổi giá trị của ký tự đó bằng cách sử dụng con trỏ, như sau báo cáo dẫn đến lỗi phân đoạn.

*a='X'; 

Bây giờ giả sử chúng ta có một con trỏ char, mà chỉ vào một nhân vật liên tục.

const char B='X';  
char *ptr=&B; 

Sau đó chúng tôi được phép thay đổi giá trị của nhân vật mà sử dụng câu lệnh

*ptr='Z'; 

Câu hỏi của tôi là được này là một trường hợp hành vi undefined minh C là không mạnh mẽ? Hoặc là có một số logic sâu hơn có liên quan?

+0

@EugeniuRosca bạn có nghĩa là 'char const * a =" ABCD "'. Họ không có cùng ngữ nghĩa. – Quentin

+0

const nghĩa là bộ nhớ chỉ đọc. Giai đoạn. Bạn không được phép thay đổi nó bằng cách tham chiếu nó thông qua một con trỏ khác - điều này sẽ tạo ra một cảnh báo trình biên dịch. –

+1

Hãy xem http://stackoverflow.com/questions/2589949/c-string-literals-where-do-they-go – xp500

Trả lời

5

Lý do con trỏ thường chạy khác là chương trình C có một số phân đoạn bộ nhớ, một số phân đoạn được bảo vệ.

Sau đó, chúng tôi không thể thay đổi giá trị của ký tự đó bằng cách sử dụng con trỏ a, như sau tuyên bố dẫn đến lỗi phân đoạn.

Không giống như các hằng số khác, hằng số chuỗi được đặt vào phân đoạn được bảo vệ. Bất kỳ nỗ lực nào để sửa đổi phân đoạn này đều dẫn đến hành vi không xác định (tức là chương trình của bạn có thể phân đoạn).

Vì con trỏ trỏ vào hằng số chuỗi, giá trị mà nó không thể sửa đổi được.Nếu bạn buộc một bản sao của hằng số vào bộ nhớ sửa đổi bằng cách sử dụng một mảng, việc sửa đổi tương tự sẽ được phép:

char a[]="ABCD"; 
*a='X'; 

Sau đó chúng tôi được phép thay đổi giá trị của điều đó [single] nhân vật sử dụng câu lệnh

Điều này là do hằng số ký tự luôn được sao chép vào bộ nhớ có thể sửa đổi.

5

Trong C, sửa đổi chuỗi ký tự không được phép.

char *a="ABCD"; 

tương đương với

char const *a="ABCD"; 

*a='X'; được sửa đổi chuỗi chữ ABCD. Trong trường hợp thứ hai, ptr trỏ đến một ký tự không được thay đổi và *ptr='Z'; sẽ sửa đổi nội dung của vị trí chứa X cũng không hợp lệ.

Lưu ý rằng việc sửa đổi một đối tượng đủ điều kiện là một vi phạm ràng buộc const.

+1

Sửa đổi '* ptr' không hợp lệ một chút. – Quentin

+0

@Quentin; Rất tiếc! Đã đồng ý. Đã bỏ lỡ thông số 'const'. – haccks

7

Giả sử C cho phép bạn tự chụp chân mình một cách dễ dàng. Sửa đổi B vẫn chưa được xác định, mặc dù sửa đổi *a là do B đã được khai báo là const.

Để giúp với điều này, bật cảnh báo (mà bạn nên luôn làm trừ trong những trường hợp rất cụ thể) sẽ trả về sau đây trên GCC:

warning: initialization discards 'const' qualifier from pointer 
     target type [-Wdiscarded-qualifiers]