en c++, la fonction principale est le point d'entrée du programme comment je peux la changer en une autre fonction?
M'a demandé une question d'entrevue pour changer le point d'entrée d'un programme C ou C++ à partir de main()
pour toute autre fonction. Comment est-il possible?
- Vous n'avez pas. Il doit être
main
, ou de certains de la mise en œuvre définies par point d'entrée. Il n'y a pas de manière standard. - Dépend de votre compilateur/linker.
- Le point d'entrée d'un programme est l'endroit où il commence à s'exécuter à la machine au niveau du code. C'est rarement, sinon jamais,
main
; au lieu de cela, la fonction de point d'entrée fait un peu de tâches d'initialisation et puis, pour un programme C ou C++, les appelsmain
. Donc, la question n'a pas de sens. Êtes-vous sûr que c'était exactement la question? - Pas une bonne question d'entrevue. La meilleure réponse sera "je Ne Sais pas".
- haha j'ai répondu la même chose 🙂
- Ma réponse (si elle ne peut pas me faire du travail) serait "puis-je avoir un peu de ce que vous étiez de fumer lorsque vous réfléchi à cette question?" 🙂
Vous devez vous connecter pour publier un commentaire.
Dans la norme C (et, je crois, C++), vous ne pouvez pas, du moins pas pour un environnement hébergé (mais voir ci-dessous). La norme précise que le point de départ pour le code C est
main
. La norme c99) ne laisse pas beaucoup de portée pour l'argument:Que c'est. Ensuite, il gaufres sur un peu plus sur les paramètres et valeurs de retour mais il n'y a pas vraiment de marge de manœuvre il pour en changer le nom.
C'est pour un environnement hébergé. La norme permet également un autoportant de l'environnement (c'est à dire, pas d'OS, pour des choses comme les systèmes embarqués). Pour un autoportant environnement:
Vous pouvez utiliser la "supercherie" dans C implémentations de sorte que vous pouvez le faire paraître comme
main
n'est pas le point d'entrée. C'est en fait ce qu'au début de Windows cas de déviation a fait à marque deWinMain
comme point de départ.Première façon: un éditeur de liens peuvent inclure des pré-démarrage principal code dans un fichier, comme
start.o
et c'est ce morceau de code qui s'exécute pour configurer l'environnement en C alors appelmain
. Il n'y a rien pour vous empêcher de vous le remplacer avec quelque chose qui appellebob
à la place.Deuxième façon: certains linkers fournir cette option même avec un commutateur de ligne de commande de sorte que vous pouvez le modifier sans avoir à recompiler le code de démarrage.
Troisième voie: vous pouvez lier avec ce morceau de code:
et puis, votre point d'entrée pour votre code est apparemment
bob
plutôt quemain
.Cependant, tout cela, alors que peut-être d'un intérêt académique, ne change pas le fait que je ne peux pas penser une seule solitaire situation dans mes nombreuses décennies de la coupe de code, où ce serait nécessaire ou souhaitable.
Je serait de demander à l'enquêteur: pourquoi voudriez-vous voulez pour ce faire?
main
appelez simplement quelque chose d'autre. C'est la plus simple et la croix-plate-forme de méthode pour accomplir cette.Le point d'entrée est en fait le
_start
fonction (mise en œuvre en crt1.o) .La
_start
fonction permet de préparer les arguments de ligne de commande, puis appellemain(int argc,char* argv[], char* env[])
,vous pouvez changer le point d'entrée de
_start
àmystart
par la fixation d'un éditeur de liens paramètre:De sûr, c'est un remplacement pour le point d'entrée
_start
de sorte que vous n'obtiendrez pas les arguments de ligne de commande:Noter que global/variables statiques qui ont les constructeurs ou destructeurs doit être initialisé au début de l'application et détruit à la fin. Gardez cela à l'esprit si vous envisagez de le contourner la valeur par défaut du point d'entrée qui le fait automatiquement.
À partir de C++ standard docs 3.6.1 Fonction Principale,
Donc, il ne dépendent sur votre compilateur/linker...
shall
est normalement un mot qui signifie doit l'être. Il semble donc quemain
doit exister, même pour les indépendants. Quelqu'un peut plus de C++Standard-fu que moi à comprendre cela? Pouvez-vous pour unmain
sans qu'il soit nécessaire de le définir??main
🙂main
pour une interface graphique sous-programme. C'est peut-être ce que l'intervieweur demandait environ. Mais dans ce cas il n'est pas sur la définition d'une autre fonction de démarrage (appelé "point d'entrée" par les gens d'ici), mais plutôt sur la définition de la norme de démarrage de la fonction, MS linker optionentry:mainCRTStartup
(de peur que le MS de l'éditeur de liens se plaignent d'un manqueWinMain
🙂 ). Cheers & hth.,Si vous êtes sur VS2010, cette pourrait vous donner une idée
Comme il est facile à comprendre, ce n'est pas prescrite par la norme C++ et tombe dans le domaine de la "mise en oeuvre spécifique de comportement'.
Ce n'est que spéculation, mais vous pouvez avoir un initialiseur statique à la place de principal:
Vous pourriez même en faire "Java-like', en mettant les choses dans un constructeur:
Maintenant. L'intervieweur peut avoir pensé à ce sujet, mais je serais personnellement de ne jamais les utiliser. Les raisons sont:
Cela dit, je l'ai vu utilisé dans la production, au lieu de
init()
pour les initialiseurs de la bibliothèque. Le problème, c'est, sur windows, (de l'expérience) votre statique dans une DLL peut ou peut ne pas obtenir de initialisé en fonction de l'utilisation.Modifier le crt objet qui appelle la
main()
fonction, ou de fournir votre propre (n'oubliez pas de désactiver la liaison de la normale).Avec gcc, déclarer la fonction d'attribut((constructeur)) et mettra l'exécution de cette fonction avant tout autre code, y compris le principal.
Pour le système Solaris, j'ai trouvé cette. Vous pouvez utiliser le
.init
section pour toutes les plates-formes, je suppose:Source:
C'est très simple:
Que vous devez savoir lorsque vous utilisez les constantes en c, le compilateur exécuter une sorte de "macro" de changer le nom de la constante de la valeur correspondante.
simplement inclure un
#define
argument au début de votre code avec le nom de la fonction suivi du nommain
:Exemple:
Je pense qu'il est facile de supprimer les indésirables main() symbole de l'objet avant de les lier.
Malheureusement l'option de point d'entrée pour g++ ne fonctionne pas pour moi(le binaire se bloque avant d'entrer dans le point d'entrée). Donc, je bande indésirable du point d'entrée de fichier de l'objet.
Supposons que nous avons deux sources qui contiennent de la fonction de point d'entrée.
Après la compilation(g++ -c en option) on peut obtenir les fichiers d'objet suivants.
Nous pouvons donc utiliser la objcopy à la bande indésirables fonction main ().
Nous pouvons redéfinir la testmain() dans main() à l'aide de objcopy trop.
Et l'on peut ensuite relier les deux d'entre eux en binaire.
Cela fonctionne pour moi. Maintenant, quand nous courons
our_binary.bin
le point d'entrée estour_code.o:main()
symbole qui fait référence àour_code.c::testmain()
fonction.Sur windows il y a une autre (peu orthodoxe) de manière à changer le point d'entrée d'un programme:
TLS
. Regardez ici pour plus d'explications: http://isc.sans.edu/diary.html?storyid=6655Oui,
On peut changer le nom de la fonction principale de tout autre nom, par exemple. Démarrer, bob, rem etc.
Comment le compilateur sait qu'il est à la recherche pour le main() dans le code entier ?
Rien n'est automatique dans la programmation.
quelqu'un a fait un peu de travail à faire, il semble automatique pour nous.
de sorte qu'il a été défini au début du fichier, le compilateur doit rechercher principal().
nous pouvons changer le nom du principal à autre chose par exemple. Bob et puis le compilateur sera la recherche de Bob() seulement.
Modification d'une valeur dans l'éditeur de liens Paramètres remplacent le point d'entrée. c'est à dire, les applications MFC utiliser une valeur de 'Windows (/sous-système:WINDOWS)' pour changer de point d'entrée main() de CWinApp::WinMain().
...
Des avantages très pratiques pour la modification de point d'entrée:
MFC est un cadre qui nous en profitons pour écrire des applications Windows en C++. Je sais que c'est ancien, mais mon entreprise dispose de l'un pour des raisons d'héritage! Vous ne trouverez pas de main() dans le code MFC. MSDN dit le point d'entrée est WinMain(), à la place. Ainsi, vous pouvez remplacer le WinMain() de votre base objet CWinApp. Ou, la plupart des gens substituer CWinApp::InitInstance() parce que la base de WinMain() va appeler.
Avertissement: j'utilise des parenthèses vides pour désigner une méthode, sans s'occuper combien d'arguments.