J'avais un pari suppose que, pour être concis, c'était simplement une décision de conception. Plus précisément, si vous voulez vraiment savoir pourquoi, vous devez travailler à partir de la base.
Pensons à C en premier. Dans le langage C, il existe une distinction claire entre le "passage par référence" et de "passage par valeur". Pour les traiter à la légère, le nom d'un tableau en C est vraiment juste un pointeur. Pour toutes fins utiles, la différence (en général), revient à l'allocation. Le code
int array[n];
serait de créer 4*n octets de mémoire (sur un système 32 bits) sur la pile de corrélation à la portée de n'importe quel bloc de code fait la déclaration. À son tour,
int* array = (int*) malloc(sizeof(int)*n);
serait de créer la même quantité de mémoire, mais sur le tas. Dans ce cas, qu'est-ce que dans cette mémoire n'est pas attaché à la portée, seule la référence À la mémoire est limitée par la portée. C'est ici que le passage par valeur et le passage par référence venir. Passage par valeur, comme vous le savez probablement, cela signifie que lorsque quelque chose est passé ou renvoyée par une fonction, la "chose" qui est transmis est le résultat de l'évaluation de la variable. En d'autres termes,
int n = 4;
printf("%d", n);
imprime le numéro 4, car la construction n
évalue à 4 (désolé si c'est élémentaire, je tiens juste à couvrir toutes les bases). Ce 4 n'a absolument aucune incidence ou de la relation à l'espace mémoire de votre programme, c'est juste un littéral, et donc, une fois que vous quittez la portée de qui que 4 a contexte, vous le perdez. Ce sujet passage par référence? Le passage par référence n'est pas différent dans le contexte d'une fonction; il vous suffit d'évaluer la construction qui est transmis. La seule différence est que, après l'évaluation de la "chose", vous utilisez le résultat de l'évaluation comme une adresse mémoire. Une fois, j'ai eu un particulier cynique CS instructeur qui aimait qu'il n'y a pas une telle chose comme le passage par référence, juste un moyen de passer intelligent valeurs. Vraiment, il est juste. Alors maintenant, nous pensons au sujet de la portée en termes d'une fonction. Faire semblant que vous pouvez avoir un tableau de type de retour:
int[] foo(args){
result[n];
// Some code
return result;
}
Le problème ici est que le résultat donne l'adresse de l'0e élément du tableau. Mais lorsque vous essayez d'accéder à cette mémoire de l'extérieur de cette fonction (par l'intermédiaire de la valeur de retour), vous avez un problème parce que vous tentez d'accéder à la mémoire qui n'est pas dans le champ d'application avec laquelle vous travaillez (l'appel de la fonction de la pile). Donc, la façon dont nous obtenons, c'est avec la norme "passage par référence" jiggery-pokery:
int* foo(args){
int* result = (int*) malloc(sizeof(int)*n));
// Some code
return result;
}
Nous obtenons toujours une adresse de mémoire pointant vers le 0e élément du Tableau, mais maintenant nous avons accès à cette mémoire.
Quel est mon point? En Java, il est commun d'affirmer que "tout est passage par valeur". Ce qui est vrai. La même cynique instructeur à partir de ci-dessus a également eu ceci à dire au sujet de Java et de la programmation orientée objet en général: Tout ce qui est un pointeur. Et il est aussi en droit. Tout en tout en Java est en fait le passage par valeur, presque toutes ces valeurs sont en fait des adresses de mémoire. Donc, en Java, le langage permet de retourner un tableau ou une Chaîne de caractères, mais il le fait en tournant dans la version avec des pointeurs pour vous. Il gère également votre mémoire pour vous. Et gestion automatique de la mémoire, bien qu'utile, n'est pas efficace.
Cela nous amène à C++. La raison pour laquelle l'ensemble C++ a été inventé était parce que Bjarne Stroustrup avait fait des expériences avec Simula (essentiellement l'original OOPL) au cours de son travail de thèse, et pensait que c'était fantastique sur le plan conceptuel, mais il a remarqué qu'il a effectué, plutôt terriblement. Et donc, il a commencé à travailler sur ce qui a été appelé C avec des Classes, qui a été renommé en C++. Ce faisant, son objectif était de faire un langage de programmation qui a eu les meilleures fonctionnalités de Simula, mais est restée puissante et rapide. Il a choisi d'étendre C en raison de sa légendaire de la performance, et un compromis a été qu'il a choisi de ne pas implémenter la gestion automatique de la mémoire ou de déchets de la collecte d'une telle ampleur, comme d'autres OOPL de l'. Retourner un tableau à partir de l'une des classes de modèle fonctionne parce que, eh bien, vous êtes à l'aide d'une classe. Mais si vous voulez retourner un C tableau, vous avez à faire c'est de la C moyen. En d'autres termes, C++ prend en charge le retour d'un tableau EXACTEMENT de la même manière que Java n'; il n'a tout simplement pas le faire tout le travail pour vous. Parce qu'un danois mec pensais que ça serait trop lent.