Vấn đề là bạn đang cố sửa đổi chuỗi ký tự. Làm như vậy làm cho hành vi của chương trình của bạn không được xác định.
Giả sử bạn không được phép sửa đổi chuỗi chữ là một sự đơn giản hóa. Nói rằng các chuỗi ký tự là const
là không chính xác; họ không có.
CẢNH BÁO: Thông báo sau.
Chuỗi ký tự "this is a test"
có biểu thức loại char[15]
(14 cho độ dài, cộng 1 cho kết thúc '\0'
).Trong hầu hết các ngữ cảnh, kể cả ngữ cảnh này, một biểu thức như vậy được chuyển đổi hoàn toàn thành con trỏ tới phần tử đầu tiên của mảng, thuộc loại char*
.
Hành vi cố gắng sửa đổi mảng được tham chiếu bằng một chuỗi ký tự là không xác định - không phải vì nó là const
(không phải), mà vì tiêu chuẩn C cụ thể nói rằng nó không xác định.
Một số trình biên dịch có thể cho phép bạn thoát khỏi điều này. Mã của bạn thực sự có thể sửa đổi mảng tĩnh tương ứng với chữ (có thể gây ra sự nhầm lẫn lớn sau này).
Hầu hết các trình biên dịch hiện đại, sẽ lưu trữ mảng trong bộ nhớ chỉ đọc - không phải ROM vật lý, nhưng trong vùng bộ nhớ được bảo vệ khỏi hệ thống bộ nhớ ảo. Kết quả của việc cố gắng sửa đổi bộ nhớ như vậy thường là lỗi phân đoạn và lỗi chương trình.
Vậy tại sao không phải là chuỗi ký tự const
? Vì bạn thực sự không nên cố gắng sửa đổi chúng, nó chắc chắn sẽ có ý nghĩa - và C++ không tạo chuỗi ký tự const
. Lý do là lịch sử. Từ khóa const
không tồn tại trước khi nó được giới thiệu bởi tiêu chuẩn ANSI C 1989 (mặc dù nó có thể được thực hiện bởi một số trình biên dịch trước đó). Vì vậy, một chương trình pre-ANSI có thể trông như thế này:
#include <stdio.h>
print_string(s)
char *s;
{
printf("%s\n", s);
}
main()
{
print_string("Hello, world");
}
Không có cách nào để thực thi thực tế là print_string
không được phép sửa đổi các chuỗi được trỏ đến bởi s
. Tạo chuỗi ký tự const
trong ANSI C có thể đã phá vỡ mã hiện có, mà ủy ban ANSI C đã cố gắng rất nhiều để tránh làm. Đã không có một cơ hội tốt kể từ đó để thực hiện một sự thay đổi như vậy đối với ngôn ngữ. (Các nhà thiết kế của C++, chủ yếu là Bjarne Stroustrup, không quan tâm đến khả năng tương thích ngược với C.)
Dude - "đây là bài kiểm tra" là STRING LITERAL. Có nghĩa là nó là một mảng * READ ONLY * "của char". Bạn thậm chí có thể thoát khỏi với cố gắng sửa đổi nó mà không bị rơi trên các nền tảng nhất định. Nhưng nó chắc chắn là một không-không có trên nền tảng * BẤT CỨ :) – paulsm4