Saya relatif baru untuk C dan saya butuh bantuan dengan metode berurusan dengan array. Berasal dari pemrograman Java, saya terbiasa bisa mengatakan int [] method()
untuk mengembalikan array. Namun, saya telah menemukan bahwa dengan C Anda harus menggunakan pointer untuk array ketika Anda mengembalikannya. Menjadi seorang programmer baru, saya benar-benar tidak mengerti ini sama sekali, bahkan dengan banyak forum yang telah saya pelajari.
Pada dasarnya, saya mencoba menulis metode yang mengembalikan array char di C. Saya akan menyediakan metode (sebut saja returnArray) dengan sebuah array. Ini akan membuat array baru dari array sebelumnya dan mengembalikan pointer ke sana. Saya hanya butuh bantuan tentang cara memulai ini dan cara membaca pointer setelah dikirim keluar dari array. Setiap bantuan yang menjelaskan hal ini sangat dihargai.
Format Kode yang Diusulkan untuk Fungsi Pengembalian Array
char *returnArray(char array []){
char returned [10];
//methods to pull values from array, interpret them, and then create new array
return &(returned[0]); //is this correct?
}
Pemanggil Fungsi
int main(){
int i=0;
char array []={1,0,0,0,0,1,1};
char arrayCount=0;
char* returnedArray = returnArray(&arrayCount); ///is this correct?
for (i=0; i<10;i++)
printf(%d, ",", returnedArray[i]); //is this correctly formatted?
}
Saya belum menguji ini karena kompiler C saya tidak berfungsi saat ini tetapi saya ingin mencari tahu ini
Jawaban:
Anda tidak dapat mengembalikan array dari fungsi di C. Anda juga tidak dapat (tidak seharusnya) melakukan ini:
returned
dibuat dengan durasi penyimpanan otomatis dan referensi untuknya akan menjadi tidak valid begitu ia meninggalkan ruang lingkup yang menyatakan, yaitu, ketika fungsi kembali.Anda perlu secara dinamis mengalokasikan memori di dalam fungsi atau mengisi buffer yang telah dialokasikan sebelumnya yang disediakan oleh pemanggil.
Pilihan 1:
mengalokasikan memori di dalam fungsi secara dinamis (penelepon yang bertanggung jawab untuk melakukan deallocating
ret
)Sebut seperti ini:
Pilihan 2:
mengisi buffer yang telah dialokasikan sebelumnya yang disediakan oleh pemanggil (pemanggil mengalokasikan
buf
dan meneruskan ke fungsi)Dan menyebutnya seperti ini:
sumber
Perlakuan C pada array sangat berbeda dari Java, dan Anda harus menyesuaikan pemikiran Anda. Array dalam C bukan objek kelas satu (yaitu, ekspresi array tidak mempertahankannya "array-ness" dalam sebagian besar konteks). Dalam C, ekspresi tipe "N-element array
T
" akan secara implisit dikonversi ("decay") menjadi ekspresi tipe "pointer toT
", kecuali ketika ekspresi array adalah operan dari operatorsizeof
atau unary&
, atau jika ekspresi array adalah string literal yang digunakan untuk menginisialisasi array lain dalam deklarasi.Di antara hal-hal lain, ini berarti bahwa Anda tidak dapat meneruskan ekspresi array ke suatu fungsi dan menerimanya sebagai tipe array ; fungsi sebenarnya menerima tipe pointer:
Dalam panggilan ke
foo
, ekspresistr
dikonversi dari tipechar [6]
kechar *
, itulah sebabnya parameter pertamafoo
dideklarasikanchar *a
daripadachar a[6]
. Dalamsizeof str
, karena ekspresi array adalah operan darisizeof
operator, itu tidak dikonversi ke tipe pointer, sehingga Anda mendapatkan jumlah byte dalam array (6).Jika Anda benar - benar tertarik, Anda dapat membaca buku The Development of the C Dennis Ritchie untuk memahami dari mana perawatan ini berasal.
Hasilnya adalah bahwa fungsi tidak dapat mengembalikan tipe array, yang baik karena ekspresi array tidak dapat menjadi target penugasan, baik.
Metode teraman bagi penelepon untuk menentukan array, dan meneruskan alamat dan ukurannya ke fungsi yang seharusnya ditulis untuk itu:
Metode lain adalah untuk fungsi untuk mengalokasikan array secara dinamis dan mengembalikan pointer dan ukuran:
Dalam hal ini, pemanggil bertanggung jawab untuk membatalkan alokasi array dengan
free
fungsi perpustakaan.Perhatikan bahwa
dst
dalam kode di atas adalah penunjuk sederhanachar
, bukan penunjuk ke arraychar
. Pointer dan semantik array C sedemikian rupa sehingga Anda dapat menerapkan operator subskrip[]
ke ekspresi tipe array atau tipe pointer; keduanyasrc[i]
dandst[i]
akan mengaksesi
elemen larik array (walaupun hanyasrc
memiliki tipe larik).Anda dapat mendeklarasikan pointer ke array elemen-N
T
dan melakukan sesuatu yang serupa:Beberapa kekurangan dengan di atas. Pertama-tama, versi C yang lebih lama diharapkan
SOME_SIZE
sebagai konstanta waktu kompilasi, artinya fungsi hanya akan bekerja dengan satu ukuran array. Kedua, Anda harus melakukan dereferensi pointer sebelum menerapkan subskrip, yang mengacaukan kode. Pointer ke array bekerja lebih baik ketika Anda berurusan dengan array multi-dimensi.sumber
bar
menerima adalah pointer, bukan array. Dalam konteks deklarasi parameter fungsi,T a[N]
danT a[]
keduanya diperlakukan sebagaiT *a
.void returnArray(const char *srcArray, size_t srcSize, char *dstArray, char dstSize)
parameter terakhir harus dalamsize_t
tipe tidakchar
.Saya tidak mengatakan bahwa ini adalah solusi terbaik atau solusi pilihan untuk masalah yang diberikan. Namun, mungkin berguna untuk mengingat bahwa fungsi dapat mengembalikan struct. Meskipun fungsi tidak dapat mengembalikan array, array dapat dibungkus dengan struct dan fungsi dapat mengembalikan struct sehingga membawa array dengannya. Ini berfungsi untuk array panjang tetap.
Saya mengundang komentar tentang kekuatan dan kelemahan teknik ini. Saya tidak repot-repot melakukannya.
sumber
CHAR_ARRAY returned
di heap? Itu tentu tidak bisa di stack (dalam bingkai stackreturnArray()
kan?Bagaimana dengan implementasi kejahatan yang nikmat ini?
array.h
main.c
sumber
struct
wadah / objek array. Anggap saja seperti vektor C ++ std ::. Preprocessor akan memperluasint
versi ini kestruct intArray { int* contents; int size; };
.Dalam kasus Anda, Anda membuat array di stack dan setelah Anda meninggalkan ruang lingkup fungsi, array akan di-deallocated. Sebagai gantinya, buat array yang dialokasikan secara dinamis dan kembalikan pointer ke sana.
sumber
new
operator di C. Itu adalah C ++.sizeof(char)
dijamin1
, jadi dalam hal ini Anda dapat menjatuhkan bit itu darimalloc
.&arr
. Anda inginarr
menjadichar *
, dan meneruskannya dengan menggunakanarr
.Anda dapat melakukannya menggunakan memori tumpukan (melalui permintaan malloc () ) seperti jawaban lain yang dilaporkan di sini, tetapi Anda harus selalu mengelola memori (menggunakan fungsi bebas () setiap kali Anda memanggil fungsi Anda). Anda juga dapat melakukannya dengan array statis:
Anda dapat menggunakannya tanpa khawatir tentang manajemen memori.
Dalam contoh ini Anda harus menggunakan kata kunci statis dalam definisi array untuk mengatur ke aplikasi-panjang array seumur hidup, sehingga tidak akan hancur setelah pernyataan kembali. Tentu saja, dengan cara ini Anda menempati byte SIZE dalam memori Anda untuk seluruh umur aplikasi, jadi ukuranlah dengan benar!
sumber
Metode Anda akan mengembalikan variabel tumpukan lokal yang akan gagal parah. Untuk mengembalikan array, buat satu di luar fungsi, kirimkan dengan alamat ke fungsi, lalu modifikasi, atau buat array di heap dan kembalikan variabel itu. Keduanya akan berfungsi, tetapi yang pertama tidak memerlukan alokasi memori dinamis untuk membuatnya bekerja dengan benar.
sumber
Anda dapat menggunakan kode seperti ini:
Ketika Anda melakukan ini, memori nanti harus dibebaskan, dengan mengirimkan alamat tersebut menjadi bebas.
Ada opsi lain. Rutin mungkin mengembalikan pointer ke array (atau bagian dari array) yang merupakan bagian dari beberapa struktur yang ada. Penelepon mungkin melewati array, dan rutinitas hanya menulis ke dalam array, daripada mengalokasikan ruang untuk array baru.
sumber