Bản nháp C99 N1256
Có hai cách sử dụng khác nhau của chuỗi ký tự:
Bạn đang xem: Char là gì *
-
Khởi tạo ký tự[]:
char c[] = “Abc”;
Đây là “kỳ diệu hơn” và được mô tả tại 6.7.8 / 14 “Khởi tạo”:
Một mảng kiểu ký tự có thể được khởi tạo bằng một chuỗi ký tự, tùy chọn được đặt trong dấu ngoặc nhọn. Các ký tự liên tiếp của chuỗi chữ theo nghĩa đen (bao gồm cả ký tự null kết thúc nếu còn chỗ hoặc nếu mảng có kích thước không xác định) khởi tạo các phần tử của mảng.
Vì vậy, đây chỉ là một phím tắt cho:
char c[] = {‘a’, ‘b’, ‘c’, ”};
Giống như bất kỳ mảng thông thường nào khác, c có thể được sửa đổi.
-
Ở mọi nơi khác: nó tạo ra:
- không tên
- mảng char Kiểu trong chuỗi C và C ++ là gì?
- với bộ nhớ tĩnh
- cung cấp cho UB nếu được sửa đổi
Vì vậy, khi bạn viết:
char * c = “abc”;
Điều này tương tự như:
/ * __unname là ma thuật bởi vì sửa đổi nó mang lại UB. * / static char __unname[] = “Abc”; char * c = __unname;
Xem thêm: Có nên nghỉ việc để làm freelancer thiết kế? – Xem xét một cách kĩ lưỡng
Lưu ý diễn viên ngầm từ char[]thành char *, luôn luôn hợp pháp.
Sau đó, nếu bạn sửa đổi c[0]bạn cũng sửa đổi __unname, đó là UB.
Điều này được ghi lại trong 6.4.5 “Chuỗi”:
5 Trong giai đoạn dịch 7, một byte hoặc mã có giá trị 0 được thêm vào mỗi chuỗi ký tự nhiều dòng kết quả từ một chuỗi ký tự hoặc chuỗi ký tự theo nghĩa đen. Sau đó, chuỗi ký tự multibyte được sử dụng để khởi tạo một mảng thời lượng và độ dài lưu trữ tĩnh vừa đủ để giữ chuỗi. Đối với các ký tự chuỗi, các phần tử mảng có kiểu char và được khởi tạo bằng các byte riêng lẻ của chuỗi ký tự nhiều dòng […]
6 Không biết liệu các mảng này có khác biệt hay không miễn là các phần tử của chúng có các giá trị phù hợp. Nếu chương trình cố gắng sửa đổi một mảng như vậy, hành vi đó là không xác định.
6.7.8 / 32 “Khởi tạo” đưa ra một ví dụ trực tiếp:
VÍ DỤ 8: Tuyên bố
định nghĩa các đối tượng mảng char “đơn giản” s và t có các phần tử được khởi tạo bằng chuỗi ký tự.
Tuyên bố này giống với
Nội dung của các mảng có thể sửa đổi được. Mặt khác, tuyên bố
Xem thêm: Attack on Titan: Sức mạnh của tộc Ackerman và khả năng nào cho Levi có thể biến hình thành Titan
định nghĩa p với kiểu “con trỏ tới char” và khởi tạo nó để trỏ đến một đối tượng kiểu “mảng char” có độ dài 4 có các phần tử được khởi tạo bằng một chuỗi ký tự. Nếu cố gắng sử dụng p để sửa đổi nội dung của mảng, hành vi đó là không xác định.
ELF GCC 4,8 x86-64. Triển khai
Chương trình:
#bao gồm
Biên dịch và dịch ngược:
gcc -ggdb -std = c99 -c main.c objdump -Sr main.o
Đầu ra chứa:
char * s = “abc”; 8: 48 c7 45 f8 00 00 00 movq $ 0x0, -0x8 (% rbp) f: 00 c: R_X86_64_32S .rodata
Kết luận: GCC lưu trữ char * nó trong phần .rodata, không phải trong .text.
Nếu chúng ta làm tương tự cho char[]:
char s[] = “Abc”;
Chúng tôi đạt được:
17: c7 45 f0 61 62 63 00 movl $ 0x636261, -0x10 (% rbp)
vì vậy nó được lưu trữ trong ngăn xếp (liên quan đến% rbp).
Tuy nhiên, lưu ý rằng tập lệnh ràng buộc mặc định đặt .rodata và .text trong cùng một phân đoạn, phân đoạn này thực thi nhưng không có quyền ghi. Điều này có thể được quan sát với:
readelf -l a.out
bao gồm:
Xem thêm: PC là viết tắt của gì? PC có thực sự là một máy tính để bàn?
Ánh xạ phần tới phân đoạn: Các phần của phân đoạn… 02 .text .rodata
Category: wiki