Fonction data de C++ <vector>

Classe conteneur 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 <iostream>
#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 :

  1. numbers.data()Renvoie un pointeur vers le premier élément.
  2. 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 <iostream>
#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 :

  • Viadata()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 <iostream>
#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 <iostream>
#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.
  • UtilisationmemsetVous 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 <iostream>
#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'originedata()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.

Classe conteneur C++ <vector>

autres extensions