Agak memunculkan pertanyaan mengapa? Anda dapat mengakses vektor sebagai array. Apa yang dilakukan array yang tidak dimiliki oleh vektor?
Michael Dorgan
96
@Michael Kasus penggunaan umum yang saya miliki adalah menggunakan vektor dalam kode saya sendiri dan perlu memanggil fungsi pihak ketiga yang mengambil array
Michael Mrozek
7
Terminologi yang dilontarkan membingungkan. Pointer bukan sebuah array. Apakah kita ingin pointer ke elemen pertama array, atau array?
GManNickG
7
benar-benar pertanyaan nyata - cukup sederhana, mudah ditafsirkan, juga. tolong buka kembali.
dbliss
10
"Agak memohon pertanyaan mengapa?" - Pertama, penyalahgunaan frasa itu. Kedua, mengapa itu jelas berdarah.
Jim Balter
Jawaban:
533
Ada trik yang cukup sederhana untuk melakukannya, karena spec sekarang menjamin vektor menyimpan elemen-elemennya secara bersamaan:
@ganuke Anda tidak menyalin, Anda membuat pointer yang menunjuk ke array aktual yang digunakan vektor secara internal. Jika Anda ingin menyalin jawaban GMan, jelaskan caranya
Michael Mrozek
4
@ganuke: Apa itu "array"? Anda perlu memberikan informasi lebih lanjut. Apa gambaran besarnya?
GManNickG
6
@ganuke Anda tidak, Anda hanya perlu double*yang menunjuk ke data yang sama. Jawaban ini tepat untuk kasus itu
Michael Mrozek
6
@guneykayim Vektor memiliki memori itu, Anda tidak harus membebaskannya
Michael Mrozek
23
std::vector<double> v; double* a = v.data();
sinoTrinity
148
Untuk apa? Anda perlu mengklarifikasi: Apakah Anda memerlukan pointer ke elemen pertama array, atau array?
Jika Anda memanggil fungsi API yang mengharapkan yang pertama, Anda dapat melakukannya do_something(&v[0], v.size()), di mana vvektor doubles. Elemen-elemen vektor berdekatan.
Jika tidak, Anda hanya perlu menyalin setiap elemen:
Catatan: gunakan v.size () untuk mendapatkan jumlah elemen untuk array baru: double arr [v.size ()];
rbaleksandar
7
@rbaleksandar: Array tidak dapat memiliki ukuran ekspresi yang tidak konstan.
GManNickG
@ GMNickG: Berhasil tapi saya pikir ada beberapa kesalahpahaman di sini. Bayangkan berikut ini: Anda memiliki kelas dengan sekelompok pointer dari berbagai jenis yang harus menunjuk ke array, yang tidak diketahui pada saat Anda mendefinisikan kelas Anda dan yang kemudian dibuat dengan menyiram berbagai vektor dan menggunakan ukuran-parameternya untuk menentukan berapa banyak ruang yang akan digunakan. Contoh lain: fungsi void arrayTest sederhana (unsigned int arrSize), yang membuat sebuah array (arr [ukuran kecil];) di dalamnya dengan menggunakan parameter fungsi untuk ukuran.
rbaleksandar
1
@rbaleksandar. Tidak salah paham; dalam C ++ 11 dan sebelumnya, ukuran array harus ekspresi konstan integral. Contoh fungsi Anda adalah penggunaan umum untuk VLA di C, tetapi hanya didukung oleh ekstensi (tidak standar) di C ++. Ini mungkin datang ke C ++ 14: stackoverflow.com/a/17318040/87234 . Tetapi sampai sekarang, itu bukan pilihan standar.
GManNickG
1
@GManNickG Saya pikir @Jet mengatakan bahwa jika Anda ingin mengkonversi vektor ke array, dan Anda bermaksud untuk mengukur array menggunakan size()fungsi std:vectorAnda harus menggunakan newatau mallocuntuk melakukannya. Seperti yang sudah ditunjukkan (oleh Anda) itu double arr[v.size()]tidak valid. Menggunakan vektor di tempat yang baru adalah ide yang bagus, tetapi seluruh poin dari pertanyaan adalah bagaimana Anda dapat mengubah vektor menjadi sebuah array.
Ini dijamin untuk bekerja sesuai standar, namun ada beberapa peringatan: khususnya berhati-hati untuk hanya menggunakan thearraysaat thevectorberada dalam ruang lingkup.
Jika Anda memiliki fungsi, maka Anda mungkin perlu ini: foo(&array[0], array.size());. Jika Anda berhasil masuk ke situasi di mana Anda memerlukan array maka Anda perlu refactor, vektor pada dasarnya adalah array diperpanjang, Anda harus selalu menggunakannya.
Jawaban:
Ada trik yang cukup sederhana untuk melakukannya, karena spec sekarang menjamin vektor menyimpan elemen-elemennya secara bersamaan:
sumber
double*
yang menunjuk ke data yang sama. Jawaban ini tepat untuk kasus itustd::vector<double> v; double* a = v.data();
Untuk apa? Anda perlu mengklarifikasi: Apakah Anda memerlukan pointer ke elemen pertama array, atau array?
Jika Anda memanggil fungsi API yang mengharapkan yang pertama, Anda dapat melakukannya
do_something(&v[0], v.size())
, di manav
vektordouble
s. Elemen-elemen vektor berdekatan.Jika tidak, Anda hanya perlu menyalin setiap elemen:
Pastikan tidak hanya
arr
itu cukup besar, tetapi ituarr
akan terisi, atau Anda memiliki nilai yang tidak diinisialisasi.sumber
size()
fungsistd:vector
Anda harus menggunakannew
ataumalloc
untuk melakukannya. Seperti yang sudah ditunjukkan (oleh Anda) itudouble arr[v.size()]
tidak valid. Menggunakan vektor di tempat yang baru adalah ide yang bagus, tetapi seluruh poin dari pertanyaan adalah bagaimana Anda dapat mengubah vektor menjadi sebuah array.Untuk C ++ 11 ,
vector.data()
akan melakukan trik.sumber
Ini dijamin untuk bekerja sesuai standar, namun ada beberapa peringatan: khususnya berhati-hati untuk hanya menggunakan
thearray
saatthevector
berada dalam ruang lingkup.sumber
empty()
, jika tidak ini akan memanggil UB yang ditakuti.Vektor secara efektif adalah array di bawah kulit. Jika Anda memiliki fungsi:
Anda bisa menyebutnya seperti ini:
Anda seharusnya tidak perlu mengubah vektor menjadi instance array aktual.
sumber
f( &v[0] );
untuk kalimat terakhir AndaSeperti untuk
std::vector<int> vec
, vec untuk mendapatkanint*
, Anda dapat menggunakan dua metode:int * arr = & vec [0];
int * arr = vec.data ();
Jika Anda ingin mengkonversi semua jenis
T
vektor untukT* array
, hanya mengganti di atasint
untukT
.Saya akan menunjukkan kepada Anda mengapa dua di atas bekerja, untuk pengertian yang baik?
std::vector
adalah array dinamis pada dasarnya.Anggota data utama seperti di bawah ini:
The
range (start_, end_of_storage_)
adalah semua memori array yang vektor mengalokasikan;Ini
range(start_, finish_)
semua memori array yang digunakan vektor;Ini
range(finish_, end_of_storage_)
adalah memori array cadangan.Misalnya, untuk vec vektor. yang memiliki {9, 9, 1, 2, 3, 4} adalah pointer mungkin seperti di bawah ini.
Jadi
&vec[0]
= start_ (alamat.) (Start_ sama dengan int * array head)Di
c++11
dalamdata()
fungsi anggota hanya kembali start_sumber
Kita dapat melakukan ini menggunakan metode data (). C ++ 11 menyediakan metode ini.
Cuplikan Kode
sumber
sumber
Jika Anda memiliki fungsi, maka Anda mungkin perlu ini:
foo(&array[0], array.size());
. Jika Anda berhasil masuk ke situasi di mana Anda memerlukan array maka Anda perlu refactor, vektor pada dasarnya adalah array diperpanjang, Anda harus selalu menggunakannya.sumber
Anda dapat melakukan beberapa hal seperti ini
sumber