En C (ou C ++ d'ailleurs), les pointeurs sont spéciaux s'ils ont la valeur zéro: on me conseille de mettre les pointeurs à zéro après avoir libéré leur mémoire, car cela signifie que libérer à nouveau le pointeur n'est pas dangereux; quand j'appelle malloc, il renvoie un pointeur avec la valeur zéro s'il ne peut pas me procurer de mémoire; J'utilise if (p != 0)
tout le temps pour m'assurer que les pointeurs passés sont valides, etc.
Mais comme l'adressage mémoire commence à 0, 0 n'est-il pas seulement une adresse valide comme une autre? Comment utiliser 0 pour gérer les pointeurs nuls si tel est le cas? Pourquoi un nombre négatif n'est-il pas nul à la place?
Éditer:
Un tas de bonnes réponses. Je vais résumer ce qui a été dit dans les réponses exprimées comme mon propre esprit l'interprète et j'espère que la communauté me corrigera si je me trompe.
Comme tout le reste de la programmation, c'est une abstraction. Juste une constante, pas vraiment liée à l'adresse 0. C ++ 0x met l'accent sur cela en ajoutant le mot-clé
nullptr
.Ce n'est même pas une abstraction d'adresse, c'est la constante spécifiée par le standard C et le compilateur peut la traduire en un autre nombre tant qu'il s'assure qu'elle n'est jamais égale à une adresse "réelle", et égale d'autres pointeurs nuls si 0 n'est pas le meilleure valeur à utiliser pour la plate-forme.
Au cas où ce ne serait pas une abstraction, ce qui était le cas dans les premiers jours, l'adresse 0 est utilisée par le système et interdite au programmeur.
Ma suggestion de nombre négatif était un peu de brainstorming sauvage, je l'admets. L'utilisation d'un entier signé pour les adresses est un peu inutile si cela signifie qu'en dehors du pointeur nul (-1 ou autre), l'espace de valeurs est divisé également entre des entiers positifs qui font des adresses valides et des nombres négatifs qui sont juste gaspillés.
Si un nombre est toujours représentable par un type de données, il est 0. (Probablement 1 l'est aussi. Je pense à l'entier d'un bit qui serait 0 ou 1 s'il n'est pas signé, ou juste le bit signé s'il est signé, ou l'entier de deux bits qui serait [-2, 1]. Mais alors vous pourriez simplement choisir 0 étant nul et 1 étant le seul octet accessible en mémoire.)
Il y a toujours quelque chose qui n'est pas résolu dans mon esprit. Le pointeur de question de débordement de pile vers une adresse fixe spécifique me dit que même si 0 pour le pointeur nul est une abstraction, les autres valeurs de pointeur ne le sont pas nécessairement. Cela m'amène à publier une autre question Stack Overflow, pourrais-je jamais vouloir accéder à l'adresse zéro? .
if (p != 0)
pourif (p)
lequel est un idiome courant en C et C ++, même si vous devrez sortir de cette habitude si vous prenez Java.0xDEADBEEF
.Réponses:
2 points:
seule la valeur constante 0 dans le code source est le pointeur nul - l'implémentation du compilateur peut utiliser la valeur qu'elle veut ou dont elle a besoin dans le code en cours d'exécution. Certaines plates-formes ont une valeur de pointeur spéciale qui est «invalide» que l'implémentation peut utiliser comme pointeur nul. La FAQ C a une question, "Sérieusement, des machines réelles ont-elles vraiment utilisé des pointeurs nuls différents de zéro, ou des représentations différentes pour des pointeurs vers différents types?" , qui souligne plusieurs plates-formes qui ont utilisé cette propriété de 0 étant le pointeur nul dans la source C tout en étant représentée différemment au moment de l'exécution. La norme C ++ a une note qui indique clairement que la conversion "d'une expression constante intégrale avec la valeur zéro produit toujours un pointeur nul,
une valeur négative pourrait être tout aussi utilisable par la plate-forme qu'une adresse - le standard C devait simplement choisir quelque chose à utiliser pour indiquer un pointeur nul, et zéro a été choisi. Honnêtement, je ne sais pas si d'autres valeurs sentinelles ont été prises en compte.
Les seules exigences pour un pointeur nul sont:
la source
Historiquement, l'espace d'adressage commençant à 0 était toujours ROM, utilisé pour certains systèmes d'exploitation ou routines de gestion d'interruptions de bas niveau, de nos jours, puisque tout est virtuel (y compris l'espace d'adressage), le système d'exploitation peut mapper n'importe quelle allocation à n'importe quelle adresse, de sorte qu'il peut spécifiquement N'attribuez rien à l'adresse 0.
la source
IIRC, la valeur du "pointeur nul" n'est pas garantie égale à zéro. Le compilateur traduit 0 en n'importe quelle valeur «nulle» appropriée pour le système (qui en pratique est probablement toujours zéro, mais pas nécessairement). La même traduction est appliquée chaque fois que vous comparez un pointeur à zéro. Parce que vous ne pouvez comparer les pointeurs que les uns contre les autres et avec cette valeur spéciale-0, cela empêche le programmeur de savoir quoi que ce soit sur la représentation mémoire du système. Quant à savoir pourquoi ils ont choisi 0 au lieu de 42 ou quelque chose comme ça, je vais deviner que c'est parce que la plupart des programmeurs commencent à compter à 0 :) (De plus, sur la plupart des systèmes, 0 est la première adresse mémoire et ils voulaient que ce soit pratique, car dans la pratique des traductions comme je le décris a rarement lieu, la langue le permet).
la source
int* p = 0
) peut créer un pointeur contenant la valeur0xdeadbeef
ou toute autre valeur qu'elle préfère. 0 est un pointeur nul, mais un pointeur nul n'est pas nécessairement un pointeur vers l'adresse zéro. :)Vous devez mal comprendre la signification de la constante zéro dans le contexte du pointeur.
Ni en C ni en C ++ les pointeurs ne peuvent "avoir la valeur zéro". Les pointeurs ne sont pas des objets arithmétiques. Ils ne peuvent pas avoir de valeurs numériques comme "zéro" ou "négatif" ou quoi que ce soit de cette nature. Donc, votre déclaration sur les "pointeurs ... ont la valeur zéro" n'a tout simplement aucun sens.
En C & C ++, les pointeurs peuvent avoir la valeur de pointeur nul réservée . La représentation réelle de la valeur du pointeur nul n'a rien à voir avec les "zéros". Cela peut être absolument tout ce qui convient à une plate-forme donnée. Il est vrai que sur la plupart des plates-formes, la valeur du pointeur nul est représentée physiquement par une valeur d'adresse nulle réelle. Cependant, si sur une certaine plate-forme, l'adresse 0 est réellement utilisée dans un certain but (c'est-à-dire que vous devrez peut-être créer des objets à l'adresse 0), la valeur du pointeur nul sur cette plate-forme sera probablement différente. Elle peut être représentée physiquement comme
0xFFFFFFFF
valeur d'adresse ou comme0xBAADBAAD
valeur d'adresse, par exemple.Néanmoins, quelle que soit la façon dont la valeur du pointeur nul est représentée sur une plate-forme donnée, dans votre code, vous continuerez à désigner des pointeurs nulles par constante
0
. Afin d'attribuer une valeur de pointeur nul à un pointeur donné, vous continuerez à utiliser des expressions telles quep = 0
. Il est de la responsabilité du compilateur de réaliser ce que vous voulez et de le traduire dans la représentation de valeur de pointeur nul appropriée, c'est-à-dire de le traduire dans le code qui mettra la valeur d'adresse de0xFFFFFFFF
dans le pointeurp
, par exemple.En bref, le fait que vous utilisez
0
dans votre code sorce pour générer des valeurs de pointeur nul ne signifie pas que la valeur de pointeur nul est en quelque sorte liée à l'adresse0
. Le0
que vous utilisez dans votre code source n'est que du «sucre syntaxique» qui n'a absolument aucun rapport avec l'adresse physique réelle sur laquelle la valeur du pointeur nul «pointe».la source
(p1 - nullptr) - (p2 - nullptr) == (p1 - p2)
.NULL
n'a pas besoin explicitement d'être représentée par 0.Sur certains / nombreux / tous les systèmes d'exploitation, l'adresse mémoire 0 est spéciale d'une certaine manière. Par exemple, il est souvent mappé à une mémoire invalide / inexistante, ce qui provoque une exception si vous essayez d'y accéder.
Je pense que les valeurs de pointeur sont généralement traitées comme des nombres non signés: sinon, par exemple, un pointeur 32 bits ne pourrait adresser que 2 Go de mémoire, au lieu de 4 Go.
la source
Je suppose que la valeur magique 0 a été choisie pour définir un pointeur invalide car il pourrait être testé avec moins d'instructions. Certains langages machine définissent automatiquement les indicateurs zéro et signe en fonction des données lors du chargement des registres afin que vous puissiez tester un pointeur nul avec un simple chargement puis des instructions de branche sans faire une instruction de comparaison séparée.
(La plupart des ISA ne définissent des indicateurs que sur les instructions ALU, mais pas sur les charges. Et généralement, vous ne produisez pas de pointeurs via le calcul, sauf dans le compilateur lors de l'analyse de la source C. Mais au moins, vous n'avez pas besoin d'une constante de largeur de pointeur arbitraire pour comparer avec.)
Sur les Commodore Pet, Vic20 et C64, qui étaient les premières machines sur lesquelles j'ai travaillé, la RAM commençait à l'emplacement 0, il était donc totalement valide de lire et d'écrire en utilisant un pointeur nul si vous le vouliez vraiment.
la source
Je pense que c'est juste une convention. Il doit y avoir une valeur pour marquer un pointeur non valide.
Vous perdez juste un octet d'espace d'adressage, ce qui devrait rarement être un problème.
Il n'y a pas de pointeurs négatifs. Les pointeurs sont toujours non signés. De plus, s'ils pouvaient être négatifs, votre convention signifierait que vous perdez la moitié de l'espace d'adressage.
la source
char *p = (char *)1; --p;
. Puisque le comportement sur un pointeur nul n'est pas défini par la norme, ce système peut avoir enp
fait une adresse de lecture et d'écriture 0, un incrément pour donner l'adresse1
, etc.char x = ((char*)0);
lire l'adresse zéro et stocker cette valeur dans x. Un tel code produirait un comportement indéfini sur toute implémentation qui ne définissait pas son comportement, mais le fait qu'une norme dise que quelque chose est un comportement indéfini n'interdit en aucun cas aux implémentations d'offrir leurs propres spécifications pour ce qu'il fera.*(char *)0
. C'est vrai, mais selon ma suggestion, l'implémentation n'a pas besoin de définir le comportement de*(char *)0
ou de toute autre opération de pointeur nul.char *p = (char*)1; --p;
ne serait défini par la norme que si cette séquence avait été effectuée après qu'un pointeur vers autre chose que le premier octet d'un objet ait été converti en anintptr_t
, et que le résultat de cette conversion produisait la valeur 1 , et dans ce cas particulier, le résultat de--p
donnerait un pointeur vers l'octet précédant celui dont la valeur du pointeur, lors de la conversionintptr_t
, avait donné1
.Bien que C utilise 0 pour représenter le pointeur nul, gardez à l'esprit que la valeur du pointeur lui-même peut ne pas être un zéro. Cependant, la plupart des programmeurs n'utiliseront jamais des systèmes où le pointeur nul est, en fait, 0.
Mais pourquoi zéro? Eh bien, c'est une adresse que chaque système partage. Et souvent, les adresses basses sont réservées à des fins de système d'exploitation, ainsi la valeur fonctionne bien car elle est interdite aux programmes d'application. L'affectation accidentelle d'une valeur entière à un pointeur est aussi susceptible de finir par zéro que toute autre chose.
la source
Historiquement, la mémoire insuffisante d'une application était occupée par les ressources système. C'est à cette époque que zéro est devenu la valeur nulle par défaut.
Bien que ce ne soit pas nécessairement vrai pour les systèmes modernes, il est toujours une mauvaise idée de définir des valeurs de pointeur sur autre chose que l'allocation de mémoire vous a fourni.
la source
Concernant l'argument de ne pas définir un pointeur sur null après sa suppression afin que les suppressions futures "exposent les erreurs" ...
Si vous êtes vraiment, vraiment inquiet à ce sujet, une meilleure approche, qui est garantie de fonctionner, consiste à tirer parti de assert ():
Cela nécessite une saisie supplémentaire et une vérification supplémentaire pendant les versions de débogage, mais il est certain de vous donner ce que vous voulez: notez quand ptr est supprimé «deux fois». L'alternative donnée dans la discussion des commentaires, qui ne définit pas le pointeur sur null pour que vous obteniez un plantage, n'est tout simplement pas garantie de réussir. Pire, contrairement à ce qui précède, cela peut provoquer un crash (ou bien pire!) Sur un utilisateur si l'un de ces "bogues" parvient à l'étagère. Enfin, cette version vous permet de continuer à exécuter le programme pour voir ce qui se passe réellement.
Je me rends compte que cela ne répond pas à la question posée, mais je craignais que quelqu'un lisant les commentaires vienne à la conclusion qu'il est considéré comme une `` bonne pratique '' de NE PAS définir les pointeurs sur 0 s'il est possible qu'ils soient envoyés vers free () ou supprimer deux fois. Dans les rares cas où il est possible, il n'est JAMAIS recommandé d'utiliser le comportement indéfini comme outil de débogage. Personne qui n'a jamais eu à traquer un bogue qui a finalement été causé par la suppression d'un pointeur invalide ne le proposerait. Ces types d'erreurs prennent des heures à traquer et affectent presque toujours le programme d'une manière totalement inattendue qu'il est difficile voire impossible de retracer au problème d'origine.
la source
Une raison importante pour laquelle de nombreux systèmes d'exploitation utilisent tous les bits-zéro pour la représentation du pointeur nul, est que cela signifie
memset(struct_with_pointers, 0, sizeof struct_with_pointers)
et similaire définira tous les pointeurs à l'intérieurstruct_with_pointers
sur des pointeurs nuls. Ceci n'est pas garanti par le standard C, mais de très nombreux programmes l'assument.la source
Dans l'une des anciennes machines DEC (PDP-8, je pense), le runtime C protégerait la mémoire de la première page de mémoire de sorte que toute tentative d'accès à la mémoire dans ce bloc provoquerait le déclenchement d'une exception.
la source
Le choix de la valeur sentinelle est arbitraire, et ceci est en fait traité par la prochaine version de C ++ (informellement connue sous le nom de "C ++ 0x", plus susceptible d'être connue à l'avenir sous le nom d'ISO C ++ 2011) avec l'introduction du mot-clé
nullptr
pour représenter un pointeur de valeur nulle. En C ++, une valeur de 0 peut être utilisée comme expression d'initialisation pour tout POD et pour tout objet avec un constructeur par défaut, et elle a la signification particulière d'attribuer la valeur sentinelle dans le cas d'une initialisation de pointeur. Quant à savoir pourquoi une valeur négative n'a pas été choisie, les adresses vont généralement de 0 à 2 N-1 pour une valeur N. En d'autres termes, les adresses sont généralement traitées comme des valeurs non signées. Si la valeur maximale était utilisée comme valeur sentinelle, elle devrait alors varier d'un système à l'autre en fonction de la taille de la mémoire alors que 0 est toujours une adresse représentable. Il est également utilisé pour des raisons historiques, car l'adresse mémoire 0 était généralement inutilisable dans les programmes, et de nos jours, la plupart des systèmes d'exploitation ont des parties du noyau chargées dans la ou les pages inférieures de la mémoire, et ces pages sont généralement protégées de telle manière que si touché (déréférencé) par un programme (enregistrer le noyau) provoquera une erreur.la source
Il doit avoir une certaine valeur. Évidemment, vous ne voulez pas marcher sur des valeurs que l'utilisateur pourrait légitimement vouloir utiliser. Je suppose que, puisque le runtime C fournit le segment BSS pour les données initialisées à zéro, il est logique d'interpréter zéro comme une valeur de pointeur non initialisée.
la source
Un système d'exploitation vous permet rarement d'écrire à l'adresse 0. Il est courant de garder des éléments spécifiques au système d'exploitation dans une mémoire faible; à savoir, les IDT, les tables de pages, etc. (Les tables doivent être en RAM, et il est plus facile de les coller en bas que d'essayer de déterminer où se trouve le haut de la RAM.) Et aucun système d'exploitation sain d'esprit ne vous le permettra modifier les tables système bon gré mal gré.
Ce n'était peut-être pas dans l'esprit de K&R quand ils ont créé C, mais cela (avec le fait que 0 == null est assez facile à retenir) fait de 0 un choix populaire.
la source
La valeur
0
est une valeur spéciale qui prend différentes significations dans des expressions spécifiques. Dans le cas des pointeurs, comme cela a été souligné à maintes reprises, il est probablement utilisé parce qu'à l'époque c'était le moyen le plus pratique de dire «insérez ici la valeur sentinelle par défaut». En tant qu'expression constante, elle n'a pas la même signification que zéro au niveau du bit (c'est-à-dire que tous les bits sont mis à zéro) dans le contexte d'une expression de pointeur. En C ++, il existe plusieurs types qui n'ont pas de représentation zéro au niveau du bitNULL
comme le membre pointeur et le pointeur vers la fonction membre.Heureusement, C ++ 0x a un nouveau mot - clé « expression qui signifie un pointeur invalide connu qui ne correspond pas non plus au niveau du bit zéro pour les expressions intégrales »:
nullptr
. Bien qu'il existe quelques systèmes que vous pouvez cibler avec C ++ qui permettent le déréférencement de l'adresse 0 sans barfing, alors le programmeur se méfie.la source
Il y a déjà beaucoup de bonnes réponses dans ce fil; il y a probablement de nombreuses raisons différentes pour préférer la valeur
0
des pointeurs nuls, mais je vais en ajouter deux autres:la source
Cela dépend de l'implémentation des pointeurs en C / C ++. Il n'y a aucune raison spécifique pour laquelle NULL est équivalent dans les affectations à un pointeur.
la source
Il y a des raisons historiques à cela, mais il y a aussi des raisons d'optimisation à cela.
Il est courant que le système d'exploitation fournisse à un processus des pages de mémoire initialisées à 0. Si un programme veut interpréter une partie de cette page de mémoire comme un pointeur, alors il est à 0, il est donc assez facile pour le programme de déterminer que ce pointeur est pas initialisé. (cela ne fonctionne pas très bien lorsqu'il est appliqué à des pages flash non initialisées)
Une autre raison est que sur de nombreux processeurs, il est très très facile de tester l'équivalence d'une valeur à 0. C'est parfois une comparaison gratuite effectuée sans aucune instruction supplémentaire nécessaire, et peut généralement être effectuée sans avoir à fournir une valeur nulle dans un autre registre ou comme un littéral dans le flux d'instructions auquel comparer.
Les comparaisons bon marché pour la plupart des processeurs sont les signés inférieurs à 0 et égaux à 0. (les signés supérieurs à 0 et non égaux à 0 sont implicites par les deux)
Étant donné qu'une valeur sur toutes les valeurs possibles doit être réservée comme mauvaise ou non initialisée, vous pouvez aussi bien en faire celle qui a le test le moins cher d'équivalence à la mauvaise valeur. Ceci est également vrai pour les chaînes de caractères terminées par «\ 0».
Si vous deviez essayer d'utiliser plus ou moins de 0 à cette fin, vous finiriez par couper votre plage d'adresses en deux.
la source
La constante
0
est utilisée au lieu deNULL
parce que C a été faite par des hommes des cavernes il y a des billions d'années,NULL
,NIL
,ZIP
ouNADDA
aurait tout fait sens beaucoup plus que0
.En effet. Bien que de nombreux systèmes d'exploitation vous interdisent de mapper quoi que ce soit à l'adresse zéro, même dans un espace d'adressage virtuel (les gens ont réalisé que C est un langage non sécurisé, et reflétant que les bogues de déréférencement de pointeur nul sont très courants, a décidé de les «corriger» en interdisant le code de l'espace utilisateur à mapper vers la page 0; Ainsi, si vous appelez un rappel mais que le pointeur de rappel est NULL, vous ne finirez pas par exécuter du code arbitraire).
Car
0
utilisé en comparaison avec un pointeur sera remplacé par une valeur spécifique à l'implémentation , qui est la valeur de retour de malloc en cas de défaillance de malloc.Ce serait encore plus déroutant.
la source
int
n'avait pas seulement la même taille qu'un pointeur - dans de nombreux contextes, unint
et un pointeur pouvaient être utilisés de manière interchangeable. Si une routine attendait un pointeur et un autre passé dans un entier 57, la routine utiliserait une adresse avec le même motif binaire que le nombre 57. Sur ces machines particulières, le motif binaire pour désigner un pointeur nul était 0, donc en passant un int 0 passerait un pointeur nul.( Veuillez lire ce paragraphe avant de lire l'article.Je demande à toute personne intéressée par la lecture de cet article d'essayer de le lire attentivement, et bien sûr de ne pas le voter tant que vous ne l'avez pas compris complètement, merci. )
Il s'agit maintenant d'un wiki communautaire, en tant que tel, si quelqu'un n'est pas d'accord avec l'un des concepts, veuillez le modifier, avec une explication claire et détaillée de ce qui ne va pas et pourquoi, et si possible, veuillez citer des sources ou fournir des preuves qui peuvent être reproduites.
Répondre
Voici quelques autres raisons qui pourraient être les facteurs sous-jacents pour NULL == 0
if(!my_ptr)
place deif(my_ptr==NULL)
.Ici, je voudrais dire un mot sur d'autres réponses
Pas à cause du sucre syntaxique
Dire que NULL est nul à cause du sucre syntaxique n'a pas beaucoup de sens, si oui, pourquoi ne pas utiliser l'index 0 d'un tableau pour tenir sa longueur?
En fait, C est le langage qui ressemble le plus à l'implémentation interne, est-il logique de dire que C a choisi zéro juste à cause du sucre syntaxique? Ils préfèrent fournir un mot-clé null (comme le font de nombreux autres langages) plutôt que de mapper zéro à NULL!
En tant que tel, alors qu'à partir d'aujourd'hui, il pourrait simplement s'agir de sucre syntaxique, il est clair que l'intention initiale des développeurs de langage C n'était pas pour le sucre syntaxique, comme je le montrerai plus loin.
1) La spécification
Pourtant, s'il est vrai que la spécification C parle de la constante 0 comme pointeur nul (section 6.3.2.3), et définit également NULL comme étant défini par l'implémentation (section 7.19 dans la spécification C11 et 7.17 dans la spécification C99), le il n'en reste pas moins que dans le livre "The C Programming Language" écrit par les inventeurs de C, ce qui suit est indiqué dans la section 5.4:
Comme on peut le voir (à partir des mots "adresse zéro") au moins l'intention originelle des auteurs de C était de l'adresse zéro, et non de la constante zéro, il ressort d'ailleurs de cet extrait que la raison pour laquelle la spécification parle du la constante zéro n'est probablement pas d'exclure une expression évaluée à zéro, mais plutôt d'inclure la constante entière zéro comme étant la seule constante entière autorisée pour une utilisation dans un contexte de pointeur sans conversion.
2) Résumé
Alors que la spécification ne dit pas explicitement qu'une adresse zéro peut être traitée différemment de la constante zéro, elle ne dit pas que non, et le fait que lorsqu'elle traite de la constante de pointeur nul, elle ne prétend pas qu'elle est une implémentation définie comme elle fait par la constante définie NULL , prétend à la place qu'elle est zéro, montre qu'il pourrait y avoir une différence entre la constante zéro et l'adresse zéro.
(Cependant, si tel est le cas, je me demande simplement pourquoi NULL est défini par l'implémentation, puisque dans un tel cas, NULL peut également être la constante zéro, car le compilateur doit de toute façon convertir toutes les constantes zéro en l'implémentation réelle définie NULL?)
Cependant, je ne vois pas cela en action réelle, et dans les plates-formes générales, l'adresse zéro et la constante zéro sont traitées de la même manière et lancent le même message d'erreur.
De plus, le fait est que les systèmes d'exploitation actuels réservent en fait toute la première page (plage de 0x0000 à 0xFFFF), juste pour empêcher l'accès à l'adresse zéro à cause du pointeur NULL de C, (voir http://en.wikipedia.org/wiki/ Zero_page , ainsi que "Windows Via C / C ++ par Jeffrey Richter et Christophe Nasarre (publié par Microsoft Press)").
Ainsi, je demanderais à quiconque prétendant l'avoir réellement vu en action, de préciser la plate-forme, et le compilateur, et le code exact qu'il a réellement fait, (bien qu'en raison de la définition vague dans la spécification [comme je l'ai montré] tout compilateur et la plateforme est libre de faire ce qu'il veut).
Cependant, il semble apparemment que les auteurs de C n'avaient pas cela à l'esprit, et ils parlaient de "l'adresse zéro", et que "C garantit que ce n'est jamais une adresse valide", ainsi que "NULL est juste un mnémonique », montrant clairement que son intention initiale n'était pas de« sucre syntaxique ».
Pas à cause du système d'exploitation
Prétendant également que le système d'exploitation refuse l'accès à l'adresse zéro, pour plusieurs raisons:
1) Quand C a été écrit, il n'y avait pas de telle restriction, comme on peut le voir sur ce wiki http://en.wikipedia.org/wiki/Zero_page .
2) Le fait est que les compilateurs C ont accédé à l'adresse mémoire zéro.
Cela semble être le fait de l'article suivant de BellLabs ( http://www.cs.bell-labs.com/who/dmr/primevalC.html )
(En fait, à partir d'aujourd'hui (comme je l'ai cité ci-dessus dans les références de wikipedia et de microsoft press), la raison pour laquelle l'accès à l'adresse zéro est restreint est due aux pointeurs NULL de C! Donc, à la fin, il s'avère que c'est l'inverse!)
3) N'oubliez pas que C est également utilisé pour écrire des systèmes d'exploitation, et même des compilateurs C!
En fait, C a été développé dans le but d'écrire le système d'exploitation UNIX avec lui, et en tant que tel, il ne semble pas y avoir de raison pour laquelle ils devraient se limiter à partir de l'adresse zéro.
(Matériel) Explication sur la façon dont les ordinateurs sont (physiquement) capables d'accéder à l'adresse zéro
Il y a un autre point que je veux expliquer ici, comment est-il possible de référencer l'adresse zéro?
Pensez-y une seconde, les adresses sont récupérées par le processeur, puis envoyées sous forme de tensions sur le bus de mémoire, qui est ensuite utilisé par le système de mémoire pour accéder à l'adresse réelle, et pourtant une adresse de zéro signifiera pas de tension , alors comment le matériel physique du système de mémoire accède-t-il à l'adresse zéro?
La réponse semble être, que l'adresse zéro est la valeur par défaut, et en d'autres termes l'adresse zéro est toujours accessible par le système de mémoire lorsque le bus mémoire est complètement éteint, et en tant que telle, toute demande de lecture ou d'écriture sans spécifier une adresse réelle (qui est le cas avec l'adresse zéro) accède automatiquement à l'adresse zéro.
la source