Mà một trong những câu trả lời liên quan đến chức năng là không chính xác?


17

Vì vậy, trong khi tôi đang thực hiện một số biên dịch dài, tôi quyết định thực hiện bài kiểm tra chung C ++ trên ODesk và bắt gặp câu hỏi này.

Câu hỏi này

Nếu tôi không nhầm, đưa ra từ ngữ (hoặc thiếu từ đó), tất cả những điều này có thể đúng.

a.

int Foo() { }
int Foo(int bar) { }

b. Vâng, return void;sẽ không chính xác về mặt ngữ nghĩa nhưng các chức năng rõ ràng có thể có voidkiểu trả về.

void Foo() { }

c. Đây là định nghĩa của các hàm nội tuyến, vâng.

d. Không đi sâu vào chi tiết về vị trí của các yếu tố sau,

typedef void (*Func)(int);

Func functions[2];

void Foo(int bar) { }
void Bar(int foo) { }

functions[0] = &Foo;
functions[1] = &Bar;

Hơn nữa, bạn luôn có thể làm điều này bằng cách sử dụng lambdas và functor .

e.

void Foo(int& bar)
{
    ++bar;
}

int foobar = 5;
Foo(foobar);

f.

int bar = 5;

int& GetBar()
{
    return bar;
}

GetBar() = 6;

g.

int bar = 5;

int* GetBar()
{
    return &bar;
}

(*GetBar()) = 5;

Tôi không thấy câu hỏi này có câu trả lời thực sự sai ở đâu . Tui bỏ lỡ điều gì vậy?

Không cần phải nói tôi đã hết thời gian và thất bại toàn bộ. Tôi đoán tôi là một lập trình viên C ++ tồi. :


18
Đến đây để hét lên với một số đứa trẻ dán bài tập về nhà, đã ngạc nhiên thú vị.
Một số chú mèo con

Trên thực tế không phải tất cả các ngôn ngữ đều yêu cầu các chức năng nội tuyến được mở rộng. "nội tuyến" là một gợi ý trình biên dịch chứ không phải là một lệnh trong Delphi và C, C ++ có ngoại lệ . Vì vậy, "c" cũng có thể sai. Có thể sẽ thú vị hơn khi viết một câu trả lời cho thấy mỗi câu có thể sai như thế nào.
Móż

1
@ Nếu chỉ có một hộp văn bản. Tôi muốn quay lại và nhấn "Báo cáo vấn đề với câu hỏi này".
Qix

5
Đó không phải là một loạt các chức năng. Đó là một mảng các con trỏ hàm.
dùng253751

@immibis Đúng, nhưng câu hỏi không thực sự rõ ràng (ít nhất là với tôi nó đã không).
Qix

Câu trả lời:


21

Toàn bộ câu hỏi này là tinh ranh. Câu hỏi ngụ ý khả năng có nhiều lựa chọn, trong khi các nút radio cho biết một lựa chọn duy nhất.

Hơn nữa, b là khá đáng ngờ, vì các hàm void không trả về bất cứ thứ gì.

D cũng là nghi vấn, theo như tôi biết, bạn không thể có một loạt các chức năng. Chắc chắn, bạn có thể có một loạt các con trỏ hàm, nhưng đó không hoàn toàn giống nhau.


Đúng; D giống như hỏi nếu bạn có thể gọi một int. Chắc chắn, nếu bạn ném nó vào một con trỏ và con trỏ đó đề cập đến một chức năng ...
Qix

1
Tôi sẵn sàng đặt cược D là câu trả lời họ sẽ đưa ra, nhưng vâng, câu hỏi rất kém.
Gort Robot

Mặc dù các voidhàm không trả về bất kỳ giá trị nào , chúng vẫn trả về kiểu void . Do đó tôi nói B là đúng.
Thomas Eding

@ThomasEding Đó vẫn là từ ngữ thực sự xấu về phần của họ. Bạn không return void;, nhưng thay vào đó return;.
Qix

10

Đáp án c) cũng được cho là sai.

"Các hàm nội tuyến được mở rộng trong thời gian biên dịch để tránh phí cầu đường."

Đầu tiên, trình biên dịch C ++ được phép bỏ qua inlinegợi ý bằng cách không mở rộng các chức năng.

Thứ hai, "lý do" đã nêu để thực hiện mở rộng là một sự đơn giản hóa. Trong thực tế, lý do thực sự để thực hiện việc mở rộng (hoặc không) hoàn toàn nằm trong tay của người viết trình biên dịch.


Bạn đã đúng, nhưng tôi đã suy nghĩ về nó theo nghĩa 'được rồi, trình biên dịch đã xác định rằng nó không muốn nội tuyến một hàm' hơn là inlinegợi ý.
Qix

Vâng, trình biên dịch không thể hoàn toàn bỏ qua gợi ý. Ít nhất đó là hiệu ứng bắt buộc, tạo một ngoại lệ cho ODR.
Ded repeatator

@Ded repeatator - Có nó có thể. "Bất kể bạn chỉ định một hàm là nội tuyến như thế nào, đó là một yêu cầu mà trình biên dịch được phép bỏ qua: trình biên dịch có thể mở rộng nội tuyến một số, tất cả hoặc không có nơi nào bạn gọi một hàm được chỉ định là nội tuyến." - nguồn isocpp.org/wiki/faq/Inline-Fifts
Stephen C

@StephenC: Yêu cầu mở rộng nội tuyến có thể bị bỏ qua, vâng. Tôi chỉ nói rằng ngoại lệ rõ ràng với ODR không thể.
Ded repeatator

Tôi hiểu rồi. Tôi đã cập nhật từ ngữ cho câu trả lời của mình
Stephen C

7

c. Đây là định nghĩa của các hàm nội tuyến, vâng.

Điều đó không hoàn toàn đúng.
Mặc dù tên của nó, từ khóa inlinekhông đảm bảo rằng một chức năng sẽ được nội tuyến. Điều duy nhất mà bạn có thể chắc chắn là trình biên dịch sẽ không phàn nàn nếu nó nhìn thấy định nghĩa của hàm nội tuyến nhiều lần.

Vì vậy, nói đúng ra, tùy chọn C không chính xác, nhưng tôi không nghĩ đó là câu trả lời mà các tác giả của bài kiểm tra mong đợi, bởi vì có một câu trả lời thậm chí còn sai hơn.

d. Không đi sâu vào chi tiết về vị trí của các yếu tố sau,

typedef void (*Func)(int);

Func functions[2];

void Foo(int bar) { }
void Bar(int foo) { }

functions[0] = &Foo;
functions[1] = &Bar;

Hơn nữa, bạn luôn có thể làm điều này bằng cách sử dụng lambdas và functor.

Trong ví dụ của bạn, functionslà một mảng các con trỏ tới các hàm và không phải là một mảng các hàm. Tương tự, lambdas và functor cũng không thực sự hoạt động. Chúng là các lớp đáp ứng với toán tử gọi hàm, nhưng điều đó không làm cho chúng hoạt động theo con mắt của định nghĩa ngôn ngữ C ++.

Các chức năng trong C ++ hơi giống với công dân hạng hai. Bạn có thể định nghĩa và gọi chúng, nhưng ngay khi bạn cố gắng làm một cái gì đó khác với một loại hàm (như tạo một mảng của chúng), bạn có thể gặp lỗi hoặc chúng âm thầm tự chuyển đổi trong một con trỏ.


Tôi đồng ý với bit D, nhưng tôi đã đọc cnhư các hàm đã được đánh dấu tích cực để nội tuyến, so với inlinechính từ khóa. Tôi hiểu inlinelà một gợi ý.
Qix

4

Nếu bất cứ điều gì, nó sẽ phải là b . Bạn không thể returna void, nhưng bạn có thể trả lại a null. Không có khai báo hàm nên có để thông báo cho trình biên dịch về việc thiếu giá trị trả về.

Loại trống

Trong C và C ++

Hàm có kiểu kết quả void kết thúc bằng cách đến cuối hàm hoặc bằng cách thực hiện câu lệnh return không có giá trị trả về. Kiểu void cũng có thể xuất hiện dưới dạng đối số duy nhất của nguyên mẫu hàm để chỉ ra rằng hàm không có đối số. Lưu ý rằng mặc dù tên, trong tất cả các tình huống này, loại khoảng trống đóng vai trò là loại đơn vị, không phải là loại không hoặc loại dưới cùng, mặc dù không giống như loại đơn vị thực sự là loại đơn, loại khoảng trống được cho là bao gồm một sản phẩm nào tập hợp các giá trị và ngôn ngữ không cung cấp bất kỳ cách nào để khai báo một đối tượng hoặc biểu thị một giá trị với kiểu void.


2
-1: Mặc dù các voidhàm không trả về bất kỳ giá trị nào , chúng vẫn trả về kiểu void . Do đó tôi nói B là đúng.
Thomas Eding

Trả lại khoảng trống được cho phép trong một số trường hợp. Xem tại đây .
Josh Kelley
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.