Tôi luôn luôn nghĩ rằng argc
là cần thiết để đánh dấu sự kết thúc của argv
nhưng tôi chỉ biết rằng argv[argc] == NULL
theo định nghĩa. Tôi có nghĩ rằng argc
là hoàn toàn dư thừa? Nếu vậy, tôi luôn nghĩ rằng C
được tạo ra với sự dư thừa về tên hiệu quả. Giả định của tôi sai hay có lý do lịch sử đằng sau điều này? Nếu lý do là lịch sử, bạn có thể xây dựng?Tại sao chính (int argc, char * argv []) có hai đối số?
Trả lời
Lịch sử.
Harbison & thép (5th Edition, 9.9 "Các chương trình chính") nói như sau:
Chuẩn C đòi hỏi
argv[argc]
là một con trỏ null, nhưng nó không phải là như vậy trong một số triển khai lớn tuổi.
Sẽ rất hữu ích khi có một số dấu hiệu 'triển khai cũ hơn' không có 'argv [argc]' con trỏ - Tôi nghi ngờ H & S không cung cấp mức độ chi tiết đó. Họ sẽ phải khá già trong những ngày này. (Tôi đã không bao giờ đủ may mắn để đi qua một, nhưng có rất nhiều nền tảng bí truyền mà tôi đã không được lập trình trên.) –
FWIW Tôi quản lý để tìm một PDF quét của K & R 1st ed., Và theo như tôi có thể nói với họ không bao giờ đề cập đến một sentinel null tại 'argv [argc]' và tất cả các ví dụ sử dụng 'argc' để xác định anh ta kết thúc mảng' argv [] '. Phiên bản thứ 2 chỉ ra các sentinel null, nhưng không sử dụng nó trong bất kỳ ví dụ. –
Đây là lịch sử.
Trong ấn bản đầu tiên UNIX, trước đó C, exec lấy làm đối số tên tệp và địa chỉ của danh sách con trỏ tới chuỗi đối số được kết thúc bằng con trỏ NULL. Từ trang người đàn ông:
sys exec; name; args /exec = 11.
name: <...\0>
...
args: arg1; arg2; ...; 0
arg1: <...\0>
...
Kernel tính lên những lập luận và cung cấp hình ảnh mới với các tính arg theo sau là một danh sách các con trỏ đến các bản sao của chuỗi đối số, ở phía trên cùng của ngăn xếp. Từ trang người đàn ông:
sp--> nargs
arg1
...
argn
arg1: <arg1\0>
...
argn: <argn\0>
(Nguồn hạt nhân là here; Tôi đã không nhìn thấy nếu hạt nhân thực sự đã viết một cái gì đó sau khi con trỏ đến đối số cuối cùng.)
Tại một số điểm, tăng thông qua ấn bản thứ 6, tài liệu cho exec, execl và execv bắt đầu lưu ý rằng hạt nhân đã đặt một số -1
sau con trỏ arg. Man page nói:
argv là không trực tiếp sử dụng trong execv khác, vì argv [argc] là -1 và không 0.
Tại thời điểm này, bạn có thể tranh luận rằng argc
là dư thừa, nhưng các chương trình đã, trong một thời gian, đã sử dụng nó thay vì xem qua danh sách đối số cho -1
. Ví dụ, đây là sự khởi đầu của cal.c:
main(argc, argv)
char *argv[];
{
if(argc < 2) {
printf("usage: cal [month] year\n");
exit();
}
Trong ấn bản lần thứ 7, exec được thay đổi để thêm một con trỏ NULL sau chuỗi đối số, và điều này đã được theo sau bởi một danh sách các con trỏ đến chuỗi môi trường, và NULL khác . Man page nói:
argv là sử dụng trực tiếp trong execv khác vì argv [argc] là 0.
- 1. int argc, char * argv [] có nghĩa là gì?
- 2. Objective-c thói quen chính, những gì là: int argc, const char * argv []
- 3. argv [argc] ==?
- 4. Các đối số char * argv [] trong null chính có bị chấm dứt không?
- 5. Là argv [argc] bằng NULL Pointer
- 6. Initialize_main (& argc, & argv) làm gì?
- 7. Sử dụng argc và argv trong Eclipse?
- 8. Tại sao `execvp` lại lấy một` char * const argv [] `?
- 9. Làm cách nào để in đối số argv từ hàm chính trong C?
- 10. Làm thế nào để sử dụng iOS argc và argv?
- 11. Tại sao tham số argv để execvp không const?
- 12. Sao chép chuỗi từ argv sang mảng char trong C
- 13. char * const argv [] là gì?
- 14. Số đối số dòng lệnh không chính xác khi chuyển `*`
- 15. Tôi có thể sử dụng địa chỉ của argc chính là nguồn ngẫu nhiên không?
- 16. Tại sao "fopen" của C lại lấy "const char *" làm đối số thứ hai của C?
- 17. Tại sao không phải là đối số argv và envp để thực thi con trỏ đến const?
- 18. Trong C# lý do tại sao (char) (1) + (char) (2) kết quả trong int 3
- 19. Tại sao phải kiểm tra xem (* argv == NULL)?
- 20. So sánh tham số lệnh với argv [] không hoạt động
- 21. Tại sao `"% c "` tồn tại trong `printf` nếu` char` được chuyển thành `int`?
- 22. Tại sao char để int đúc công trình và không char để Integer trong Java
- 23. Tại sao mẫu với đối số mẫu mặc định không thể được sử dụng làm mẫu có đối số mẫu ít hơn trong Tham số mẫu mẫu
- 24. Int là int (int, char const * const *) cũng được hình thành?
- 25. Tại sao áp dụng() ở đây chỉ có một đối số thay vì hai đối số?
- 26. Tìm hiểu xem hai số có tương đối chính
- 27. Thêm char và int
- 28. Tại sao tôi không thể có mẫu và đối số mặc định?
- 29. Tại sao thêm '0' vào số int cho phép chuyển đổi thành char?
- 30. Tại sao một số không dấu int 1 thấp hơn char y -1?
Không thể 'NULL' là một yếu tố của 'argv'? Đó là, trước khi kết thúc thực tế của mảng. –
@AndrasDeak, tôi không nghĩ vậy. Một phần tử 'argv' có thể là một chuỗi rỗng, đó là một mảng chỉ một phần tử, một' 0'-byte. –
Có nó là dư thừa. Lý do là "lý do lịch sử" –