2013-08-28 35 views
38

Mọi nơi tôi nhìn thấy "nó là thực tế giống hệt nhau", hoặc một cái gì đó tương tự ...getc() vs fgetc() - Sự khác biệt chính là gì?

Từ The GNU C Programming Tutorial:

Có một chức năng trong thư viện GNU C gọi fgetc. Nó giống hệt với getc ở hầu hết các khía cạnh, ngoại trừ việc getc thường được thực hiện như một hàm macro và được tối ưu hóa cao, vì vậy là thích hợp hơn trong hầu hết các tình huống. (Trong trường hợp bạn đọc từ đầu vào tiêu chuẩn, getc nhanh bằng fgetc, vì con người gõ chậm so với tốc độ đọc máy tính của họ, nhưng khi bạn đọc từ luồng không được tạo ra bởi con người, fgetc có lẽ tốt hơn.)

Sự khác biệt khác là gì? Tôi đã nghe nói rằng họ từng có một thực hiện khác nhau (và một có thể được sử dụng như là một vĩ mô) nhưng, những gì làm cho họ soo khác nhau (hoặc đủ khác nhau) cho họ được cả hai trong thư viện Standard C (hoặc đặc điểm kỹ thuật)?

+1

Thông tin tốt tại đây: http://stackoverflow.com/questions/5186457/c-fgets-versus-fgetc-for-reading-line – dcaswell

+3

@ user814064, liên kết của bạn đã tham chiếu 'fgets' so với' fgetc', OP đang hỏi về 'getc' vs' fgetc' –

+0

getc() được đề cập ở liên kết đó, cũng như những ưu điểm của nó. – dcaswell

Trả lời

38

Từ Advanced Programming in Unix Environment:

...

Sự khác biệt giữa getcfgetcgetc có thể thực hiện như một vĩ mô, trong khi fgetc không thể được thực hiện như một vĩ mô. Điều này có nghĩa là ba điều:

  • Đối số cho getc không được là biểu hiện có phản ứng phụ.
  • fgetc được đảm bảo là chức năng, chúng tôi có thể lấy địa chỉ của nó. Điều này cho phép chúng tôi chuyển địa chỉ của fgetc làm đối số đến một chức năng khác.
  • Các cuộc gọi đến fgetc có thể mất nhiều thời gian hơn các cuộc gọi đến getc, vì thường mất nhiều thời gian hơn để gọi một hàm.

...

+0

Tôi +1, nhưng: tại sao có cả hai người trong số họ trong thư viện Chuẩn? tại sao cả hai không thể là một vĩ mô? –

+1

Vậy làm thế nào 'getc' được định nghĩa là macro? Bất kỳ con trỏ cho điều đó? – day

+0

@ngày bạn có nghĩa là "cách" như trong "chi tiết triển khai" là gì hoặc trong "cách bạn có thể thực hiện điều đó (về mặt đạo đức hoặc kỹ thuật)"? –

2

Về cơ bản giống nhau (hoặc tương tự, đủ để không làm phiền). Bạn nên xem xét triển khai của họ: GNU libcMUSL libc là các triển khai phần mềm miễn phí. Và giờ đây, chúng có thể được triển khai dưới dạng hàm nội tuyến (nhanh như macro).

Và tôi sẽ không bận tâm nhiều đến thế. Trong thực tế, I/O chủ yếu bị hạn chế bởi phần cứng (ví dụ: thời gian truy cập đĩa).

13

Có vẻ như sự khác biệt là, trong 99,9% các trường hợp, vô nghĩa.

Một điểm có thể tạo sự khác biệt - The man page nói getc() may be implemented as a macro which evaluates stream more than once.

Nó có thể dẫn đến hành vi kỳ lạ trong một số trường hợp (không phải là rất hữu ích), ví dụ .:

FILE *my_files[10] = {...}, *f=&my_files[0]; 
for (i=0; i<10; i++) { 
    int c = getc(f++); // Parameter to getc has side effects! 
} 

Nếu getc đánh giá f++ nhiều hơn một lần, nó sẽ thúc đẩy f nhiều hơn một lần mỗi lần lặp.Để so sánh, fgetc là an toàn trong các tình huống như vậy.

Các vấn đề liên quan