Các chi tiết cụ thể của định nghĩa của một chuỗi trong C là gì?


10

Tôi phải trả lời một câu hỏi bài tập về nhà cho một trong các lớp học của tôi. Cụ thể, tôi phải nói nếu một số mảng nhất định trong C được coi là chuỗi hay không. Dựa trên bài viết này ( https://www.geekforgeek.org/strings-in-c-2/ ) Tôi biết rằng các chuỗi là một mảng các ký tự có dấu kết thúc null ở cuối.

Hangout chính của tôi là một phần của câu hỏi hỏi về một mảng trông như thế này:

char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };

Đây rõ ràng là một mảng các ký tự có ký tự kết thúc null ở cuối. Tuy nhiên, nó vẫn được coi là một chuỗi vì nó cũng có một ký tự kết thúc null ở giữa? Điều đó sẽ ảnh hưởng đến chuỗi như thế nào?

EDIT: Dựa trên ý kiến, tôi đã cung cấp từ ngữ thực tế của câu hỏi:

"Mảng nào sau đây có thể được coi là" chuỗi "cho mục đích sử dụng chúng làm đối số cho strcpy (), strncpy (), strcmp (), strncmp () và các hàm chuỗi tương tự (biểu thị tất cả các hàm áp dụng)?"

EDIT: Tôi đã gửi email cho giáo sư của tôi về nó vì câu hỏi dường như được nói một cách mơ hồ (như nhiều người đã chỉ ra). Nếu có ai tò mò, anh ấy nói với tôi "Vâng, đó là một chuỗi. Điều quan trọng là có một ký tự null. Nhưng tất nhiên điều đó sẽ ảnh hưởng đến bất kỳ hoạt động chuỗi nào; chuỗi kết thúc ở ký tự null."


4
Bạn có thể nói rằng đó là chuỗi "CS"có một vài byte rác được nối thêm (trong trường hợp đó, ký tự NUL cuối cùng không liên quan). Nhưng nó không phải là một chuỗi "như một toàn thể". - Tuy nhiên, cho ăn điều này để strcpyvv sẽ không làm cho máy tính của bạn phát nổ vì các chức năng này sẽ chỉ "nhìn thấy" "CS"một phần.
Hagen von Eitzen

2
c1 hoàn toàn có thể được sử dụng làm đối số strcmp(). Việc nó có thể được sử dụng làm đối số để đột biến các hàm chuỗi hay không phụ thuộc vào các yếu tố bổ sung không được cung cấp.
EOF

2
Nội dung của c1có thể thay đổi, vì vậy tôi không hiểu tại sao nó không thể là đối số đích hợp lệ cho strcpyhoặc tương tự, trừ khi vì nó không đủ lớn để chứa chuỗi nguồn. Điều đó sẽ không làm cho nó không phải là một chuỗi, chỉ là không phù hợp cho một mục đích nhất định.
John Bollinger

1
Nhìn chung, tôi đồng ý rằng câu hỏi được diễn đạt mơ hồ. Biểu thức c1sẽ đáp ứng các yêu cầu cơ bản cho các đối số chuỗi cho tất cả các hàm chuỗi (hẹp) của thư viện tiêu chuẩn, bao gồm tất cả các hàm được đặt tên cụ thể, nhưng hành vi có thể không phải là những gì người gọi mong đợi hoặc muốn (thậm chí bỏ qua các hành vi không xác định có thể được gợi ra).
John Bollinger

1
Lưu ý rằng loại không cần phải có char. Bất kỳ loại nhân vật sẽ làm.
chux - Tái lập Monica

Câu trả lời:


8

c1chủ yếu là [1] tương đương với &c1[0], đang giữ một chuỗi , "CS".

Có một chuỗi thứ hai ẩn trong đó, "324"bắt đầu từ lúc &c1[3]- nhưng miễn là bạn truy cập c1như c1, chuỗi "CS"là tất cả các chức năng strcpy()et al. sẽ thấy.


[1]: c1là một mảng, &c1[0]là một con trỏ.


Vì vậy, nó có thích hợp để sử dụng c1làm chuỗi đích trong một strcpy()lệnh không? Câu hỏi mơ hồ - tốt nhất.
Andrew Henle

1
Tất nhiên bạn có thể sử dụng c1như là một trong hai đối số strcpy(). Đó là một chuỗi hoàn toàn bình thường theo mọi nghĩa. Các chuỗi thông thường thường chứa rác còn sót lại sau khi kết thúc. Việc rác này được mã hóa cứng vào chương trình mang lại ấn tượng rằng tác giả dự định sử dụng c1theo cách không phải là chuỗi, nhưng đó không phải là một phần của câu hỏi.
Lee Daniel Crocker

" c1Tương đương với &c1[0]" đánh lạc hướng. c1là một mảng. &c1[0]là một con trỏ
chux - Phục hồi lại

2

Nếu bạn muốn biết chi tiết cụ thể về định nghĩa của một chuỗi trong C, hãy đi đến nguồn.

Từ tiêu chuẩn C90 :

7 thư viện

7.1 Giới thiệu

7.1.1 Định nghĩa các thuật ngữ
Một chuỗi là một chuỗi các ký tự liền kề được kết thúc bởi và bao gồm ký tự null đầu tiên. Một con trỏ tới một chuỗi là một con trỏ tới ký tự ban đầu (địa chỉ thấp nhất) của nó. Độ dài của một chuỗi của một chuỗi là số lượng ký tự đứng trước ký tự null và giá trị của nó là một chuỗi các giá trị của các ký tự được chứa theo thứ tự.

(Không có thay đổi liên quan trong các tiêu chuẩn sau này.)

Như vậy c1 chứa hai chuỗi liên tiếp, "CS" và "324", nhưng bản thân nó không phải là một chuỗi.

Nếu chúng ta truyền một mảng cho một hàm, nó sẽ phân rã thành một con trỏ tới phần tử đầu tiên của nó, do đó +c1trỏ đến một chuỗi (chuỗi đầu tiên), đủ tốt cho bất kỳ hàm nào mong đợi một con trỏ thành chuỗi. Nó không trỏ đến một chuỗi "CS \ 0324", nhưng điều đó có lẽ đủ tốt cho câu hỏi của người hướng dẫn của bạn, điều này không rõ ràng.


4
Tôi sẽ lập luận rằng ngay cả theo định nghĩa này, c1 rõ ràng là chuỗi "CS". Giai đoạn = Stage. Thực tế là nó có thể chứa các byte khác không sau khi bộ kết thúc không liên quan - nhiều chuỗi sẽ giống như vậy trong suốt cuộc đời của chúng.
Lee Daniel Crocker

+c1trỏ đến một chuỗi, bởi vì c1bắt đầu bằng một chuỗi. Điều đó không theo bất kỳ cách nào, hình dạng hoặc hình thức tạo thành c1một chuỗi mặc dù.
Ded repeatator

2
Đó là địa chỉ của một phần bộ nhớ có chứa một số ký tự được chấm dứt bởi một byte số không. Nếu printf () chỉ tốt với% s, nó sẽ cung cấp một số hoàn toàn tốt được truyền cho strlen (), sẽ hoạt động nếu được chuyển cho strcpy (), v.v. Nghe có vẻ như một chuỗi đối với tôi.
Lee Daniel Crocker


Tất nhiên. Nhưng mảng chắc chắn có thể là chuỗi.
Lee Daniel Crocker

0

Thêm vào câu trả lời của @ DevSolar, một điều tôi đã khám phá ra sau khi chơi đùa với chuỗi đã cho, nếu nó là:

char c1[] = { 'C', 'S', '\\0', '3', '2', '4', '\\0' };

Nếu bạn xuất chuỗi này, bạn sẽ nhận được CS03240và kích thước của chuỗi này là 7. Theo như sự hiểu biết của tôi, \\0được sử dụng để biểu thị ký tự null ( nghĩa là \0 ). Nếu bạn làm:

printf("\0");

Bạn không thấy bất cứ điều gì trên nhật ký đầu ra, nhưng nếu bạn làm:

printf("\\0");

Bạn thấy một \0, một cái gì đó được mong đợi bởi vì để xuất các ký tự đặc biệt như dấu gạch chéo ngược hoặc dấu ngoặc kép, bạn cần sử dụng \cùng với chúng.

Một cái gì đó đánh đố tôi là đầu ra CS03240và nó có kích thước 7. Người ta thường hiểu rằng kích thước của một chuỗi là số lượng ký tự trong đó cộng với một ký tự (đối với ký tự null). Ngoài ra, kích thước là 7 ngay cả đối với chuỗi , char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };.

Vì vậy, có thể theo dõi câu hỏi này, những gì đang xảy ra ở đây?


1
'\\0'không phải là một nhân vật null . Đó là một hằng số đa ký tự. Nó có một giá trị được xác định chắc chắn nằm ngoài phạm vi char. c1[]không phải là một chuỗi vì nó thiếu một ký tự null . "bạn xuất chuỗi này" có thể dẫn đến hành vi không xác định .
chux - Phục hồi lại

Tôi đã không chính xác có được bạn mặc dù tôi đã tìm kiếm hằng số nhân vật. Nếu c1 [] không phải là một chuỗi vì cuối cùng nó không có ký tự null, thì tại sao kích thước lại xuất hiện là 7 trong trường hợp ban đầu như được đăng bởi OP?
rasengan__

char c1[] = { 'C', 'S', '\0', '3', '2', '4', '\0' };là kích thước 7 vì nó được khởi tạo với 7 giá trị. Nó có kích thước không có gì để làm với chuỗi . char c1[] = { 1, 2, 3, 4, 5, 6, 7 };vẫn sẽ làm cho nó có kích thước 7.
chux - Tái lập lại

Như mảng c1có chứa một sting? Đó là một vấn đề riêng biệt. Xem cũng
Chux - Khôi phục Monica
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.