2010-03-28 25 views
10
int main() { 
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! 
    system("pause"); 
    return main(); 
} 

Các công trình trên, nhưng đã được mã hóa cứng main(), có biến kỳ diệu nào để có được hàm chạy hiện tại không?Gọi chính() trong C++?

+0

Nếu bạn muốn có được một con trỏ hàm hoặc một cái gì đó để các chức năng hiện tại, tôi không nghĩ rằng đó là có thể. –

+0

Đó là đệ quy vô hạn ... nó có thể biên dịch, nhưng "công trình" không hoàn toàn đúng. –

+22

Là một sang một bên, XIN không bình luận những điều rõ ràng. Nó sẽ được rõ ràng rằng dòng in! Xin chào thế giới !!! – Joe

Trả lời

10

Tiêu chuẩn C++ cho biết bạn không thể gọi chính() từ mã của riêng bạn. Như để nhận được tên của hàm hiện tại, bạn có thể sử dụng __FUNCTION__ vĩ mô, nhưng một lần nữa đây không phải là tiêu chuẩn:

#include <iostream> 
using namespace std; 

void foo() { 
    cout << __FUNCTION__ << endl; 
} 

int main() { 
    foo(); 
} 

nên in "foo" hoặc một cái gì đó tương tự nếu __FUNCTION__ được hỗ trợ.

+0

@Neil, \ _ \ _ FUNCTION \ _ \ _ sẽ là chuỗi ... nó không thể được gọi. –

+0

@Michael Tôi biết. Tôi không rõ ràng (không phải lần đầu tiên) những gì @Mask đã thực sự hỏi về. Ở trên là về tốt như bạn sẽ nhận được liên quan đến siêu dữ liệu chức năng. –

+4

Về siêu dữ liệu, \ _ \ _ func \ _ \ _ sẽ sớm trở thành tiêu chuẩn. –

0

Nói chung, không. Bây giờ nó sẽ là đủ để bạn biết rằng trình biên dịch cần biết hàm chính xác mà bạn đang gọi vào thời gian biên dịch. Bạn không thể làm điều kỳ diệu như vậy, giả sử

func = "my_function"; 
func(); 

nếu tên hàm được gọi sẽ thay đổi trong thời gian chạy. (Có những ngoại lệ và cách thức xung quanh điều đó, nhưng bạn không cần điều đó).

Đừng nghĩ về điều đó như một trường hợp mã hóa cứng: không phải vậy. Nếu bạn cần gọi hàm, thì bạn chỉ cần viết tên của nó, và không cố gắng trừu tượng nó, hoặc một cái gì đó.

Ngoài ra, bây giờ sẽ là một cách hay để tìm hiểu về các vòng lặp while, vòng lặp vô hạn và viết không có chức năng gọi ở tất cả, ví dụ

int main() 
{ 
    while (1) { 
     cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! 
     system("pause"); 
    } 
} 
10

là nó cho phép trong "C++"? Số

Trong thực tế, bạn có thể gọi main() không? Vâng.

Bất kể chuẩn C++ nói gì, điều đó không ngăn trình biên dịch Linux g ++ biên dịch mã với main() trong main().

#include <cstdlib> 
#include <iostream> 
using namespace std; 
int main() 
{ 
int y = rand() % 10; // returns 3, then 6, then 7 
cout << "y = " << y << endl; 
return (y == 7) ? 0 : main(); 
} 

nào cho phép chúng ta làm:

> g++ g.cpp; ./a.out 
y = 3 
y = 6 
y = 7 

Nhìn ở với đại chúng, chúng ta thấy rằng chính được gọi là giống như bất kỳ chức năng khác sẽ là:

main: 
     ... 
     cmpl $7, -12(%rbp) 
     je  .L7 
     call main 
     ... 
.L7: 
     ... 
     leave 
     ret 

Không phải là hành vi này được đảm bảo, nhưng có vẻ như g ++ dường như không thực sự quan tâm đến tiêu chuẩn, ngoài cảnh báo châm biếm này với -pedantic

g.cpp:8: error: ISO C++ forbids taking address of function '::main' 
2

Nếu triển khai cụ thể cho phép điều này, nó không hoạt động chính xác (a)). Trạng thái chuẩn khá rõ ràng trong C++14, 3.6.1 Main function /3:

Chức năng main không được sử dụng trong chương trình.


(a) Hãy ghi nhớ rằng việc triển khai nhiều làm theo một số bộ phận của tiêu chuẩn lỏng lẻo, thích quyền lực đối với tính nghiêm minh.Điều đó có thể có tác dụng phụ không may rằng mã của bạn có thể không được di chuyển sang các trình biên dịch khác hoặc thậm chí các phiên bản khác của cùng một trình biên dịch.

Nhiều triển khai cũng sẽ cho phép bạn quan sát nghiêm ngặt hơn, chẳng hạn như sử dụng g++ -std=c++11 -Werror=pedantic để nắm bắt vấn đề cụ thể được mua trong câu hỏi này, cũng như một số vấn đề khác. Nó là "chế độ" dịch thuật cho phép triển khai để tự xưng là phù hợp với tiêu chuẩn, theo 1.4 Implementation compliance:

Nếu một chương trình chứa một vi phạm bất kỳ quy tắc có thể chẩn đoán ..., một thực hiện phù hợp ban hành tại ít nhất một thông báo chẩn đoán.

Bạn sẽ thấy vẫn có thể cho phép mã biên dịch và chạy trong trường hợp đó, vì "thông báo chẩn đoán" có thể có nghĩa là cảnh báo chứ không phải là lỗi.

-2

một chức năng không thể gọi chính nó nhưng chúng ta có thể thực hiện một thủ thuật

#include<iostream> 
int main() 
{ 
int r=6; 
//we here can make a loop for the program to repeat itself with do{}while(r=6). 
do{ 
int a; 
cin>>a; 
if(a>5) 
cout<<"hi i repeat myself"; 
}while(r==6); 
return 0; 
} 
+4

Một hàm _can_ gọi nó là tự, nó được gọi là 'đệ quy'. Và C++ đã đệ quy. – YoYoYonnY