Fonction data de C++ <vector>
dataest une fonction très spéciale dans vector, elleretourne un pointeur vers le tableau sous-jacent., ce qui vous permet d'utiliser vector comme un tableau C.
dataest une fonction membre des classes conteneurs, utilisée pourretourner un pointeur vers le stockage interne des données du conteneur. Cela permet à vector d'interopérer avec des API de style C ou d'autres codes nécessitant des pointeurs bruts.
datafournit un pont entre vector et le code en langage C, reflétant la puissante compatibilité de vector.
Définitions de mots: datasignifie "data", indiquant l'obtention d'un pointeur vers les données sous-jacentes.
Syntaxe de base et paramètres
dataest une fonction membre de la classe conteneur, et son appel ne nécessite aucun paramètre.
Format de syntaxe
T* data(); const T* data() const;
Description des paramètres
- Paramètre: Aucun paramètre
datane prend aucun argument.
Description de la fonction
- Valeur de retour: Renvoie un pointeur vers le tableau sous-jacentPointeur. Si le conteneur est const, il renvoie un pointeur const.
- Effet: Le pointeur renvoyé pointe vers le premier élément du conteneur, équivalent à
&operator[](0)。 - Remarque: Si le conteneur est vide, le pointeur renvoyé est indéfini (mais généralement pas un pointeur nul).
Exemple
Maîtrisons à fond à travers une série d'exemplesdataUtilisation.
Exemple 1 : Utilisation de base - obtention du pointeur vers le tableau sous-jacent
Exemple
#include <vector>
int main() {
// 1. Créer un vector
std::vector<int> numbers = {10, 20, 30, 40, 50};
std::cout << "La taille du vecteur est : " << numbers.size() << std::endl;
// 2. Utiliser data pour obtenir le pointeur vers le tableau sous-jacent
int* ptr = numbers.data();
std::cout << "Accès via le pointeur : " << std::endl;
for(size_t i = 0; i < numbers.size(); ++i) {
std::cout << "ptr[" << i << "] = " << ptr[i] << std::endl;
}
return 0;
}
Sortie attendue :
vector的大小是: 5 通过指针访问: ptr[0] = 10 ptr[1] = 20 ptr[2] = 30 ptr[3] = 40 ptr[4] = 50
Analyse du code :
numbers.data()Renvoie un pointeur vers le premier élément.- Grâce au pointeur renvoyé, tous les éléments sont accessibles en utilisant la syntaxe d'indice de tableau.
Exemple 2 : Modification d'éléments via un pointeur
dataLe pointeur renvoyé peut être utilisé pour modifier des éléments.
Exemple
#include <vector>
int main() {
std::vector<int> numbers = {10, 20, 30};
std::cout << "Avant modification : ";
for(int n : numbers) {
std::cout << n << " ";
}
std::cout << std::endl;
// Obtenir le pointeur via data() et modifier des éléments
int* ptr = numbers.data();
ptr[0] = 100;
ptr[1] = 200;
ptr[2] = 300;
std::cout << "Après modification : ";
for(int n : numbers) {
std::cout << n << " ";
}
std::cout << std::endl;
return 0;
}
Sortie attendue :
修改前: 10 20 30 修改后: 100 200 300
Analyse du code :
- Via
data()Le pointeur renvoyé peut modifier directement les données internes du vector.
Exemple 3 : Interaction avec des API de style C
dataL'un de ses principaux usages est d'interagir avec des fonctions C qui nécessitent des pointeurs de tableau.
Exemple
#include <vector>
#include <cstring> // pour memset
// Une fonction hypothétique de style C qui calcule la somme d'un tableau
int sumArray(const int* arr, size_t size) {
int sum = 0;
for(size_t i = 0; i < size; ++i) {
sum += arr[i];
}
return sum;
}
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
// Utiliser data() pour passer le vector à une fonction de style C
int total = sumArray(numbers.data(), numbers.size());
std::cout << "Éléments du tableau : ";
for(int n : numbers) {
std::cout << n << " ";
}
std::cout << std::endl;
std::cout << "Somme : " << total << std::endl;
return 0;
}
Sortie attendue :
数组元素: 1 2 3 4 5 总和: 15
Analyse du code :
numbers.data()Passez le pointeur de tableau interne du vector aux fonctions acceptantconst int*de la fonction.- Cela démontre la capacité du vector à interagir de manière transparente avec du code C.
Exemple 4 : Utilisation de memset pour manipuler la mémoire
Peut être accessible viadata()Manipulez directement la mémoire sous-jacente du vector.
Exemple
#include <vector>
#include <cstring> // pour memset
int main() {
std::vector<int> numbers = {10, 20, 30, 40, 50};
std::cout << "Avant l'effacement : ";
for(int n : numbers) {
std::cout << n << " ";
}
std::cout << std::endl;
// Utiliser memset pour définir tous les octets à 0
// Remarque : Cela ne fonctionne que pour les types entiers ; les types complexes peuvent poser problème
std::memset(numbers.data(), 0, numbers.size() * sizeof(int));
std::cout << "Après effacement : ";
for(int n : numbers) {
std::cout << n << " ";
}
std::cout << std::endl;
return 0;
}
Sortie attendue :
清零前: 10 20 30 40 50 清零后: 0 0 0 0 0
Analyse du code :
data()Permet une manipulation directe de la mémoire sous-jacente du vector.- Utilisation
memsetVous pouvez rapidement mettre tous les éléments à zéro. - Remarque : cette méthode n'est pas applicable aux types d'objets qui ont des constructeurs.
Exemple 5 : Utilisation sûre du pointeur renvoyé
Lorsque la mémoire du vector est réallouée, les pointeurs précédemment obtenus deviennent invalides.
Exemple
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3};
// Obtenir le pointeur de données
int* ptr = numbers.data();
std::cout << "Valeur pointée par le pointeur brut : " << *ptr << std::endl;
// L'ajout d'éléments peut entraîner une réallocation de mémoire
numbers.push_back(4);
numbers.push_back(5);
numbers.push_back(6);
numbers.push_back(7);
numbers.push_back(8);
numbers.push_back(9);
numbers.push_back(10);
// Attention : ptr peut déjà être invalide !
// Dans les implémentations modernes, elle n'est généralement pas réallouée, mais vous ne devez pas compter dessus.
std::cout << "Valeur pointée par data() après l'ajout d'un élément : " << *(numbers.data()) << std::endl;
// Bonne pratique : obtenir un nouveau pointeur avec data() à chaque fois.
ptr = numbers.data();
std::cout << "Après avoir récupéré à nouveau le pointeur : " << *ptr << std::endl;
return 0;
}
Analyse du code :
- Lorsque la capacité du vector est insuffisante,
push_backCela provoquera une réallocation de mémoire. - Après la réallocation, le pointeur d'origine
data()le pointeur renvoyé devient invalide (devient un pointeur suspendu). - Bonne pratique : l'appeler à nouveau chaque fois que vous l'utilisez.
data(), ou utilisezreserve()Préallouez suffisamment d'espace.
autres extensions