Argumen fungsi utama dan jenis pulangan. Bagaimana untuk memanggil fungsi lain dari satu fungsi dalam C? Pengisytiharan fungsi dan definisi fungsi. Membuat perpustakaan anda sendiri

Fungsi utama.

Setiap program C dan C++ mesti mempunyai fungsi utama; dan terpulang kepada anda di mana anda meletakkannya. Sesetengah pengaturcara meletakkannya di awal fail, beberapa di penghujung. Walau bagaimanapun, tanpa mengira kedudukannya, anda perlu mengingati perkara berikut: Argumen kepada fungsi "utama". Prosedur permulaan Borland C++ menghantar tiga parameter (argumen) ke fungsi utama: argc, argv dan env. - argc, integer, ialah bilangan argumen baris arahan yang dihantar ke fungsi utama, - argv ialah tatasusunan penunjuk kepada rentetan (char *). Di bawah DOS 3.x dan lebih baru, argv ditakrifkan sebagai laluan penuh program yang akan dilancarkan. Apabila bekerja di bawah lebih versi terdahulu DOS argv menunjuk kepada rentetan null (""). argv menunjuk ke baris arahan pertama selepas nama program. argv menunjuk ke baris arahan kedua selepas nama program. argv menunjuk kepada hujah terakhir yang dihantar ke main. argv mengandungi NULL. - env ​​​​juga susunan penunjuk kepada rentetan. Setiap elemen env mengandungi rentetan bentuk ENVVAR=nilai. ENVVAR namanya pembolehubah persekitaran, seperti PATH atau 87.<значение>ini adalah nilai ini pembolehubah persekitaran, contohnya C:\DOS;C:\TOOLS (untuk PATH) atau YES (untuk 87). Walau bagaimanapun, ambil perhatian bahawa jika anda menentukan beberapa argumen ini, anda mesti menentukannya dalam susunan ini: argc, argv, env. Sebagai contoh, pengisytiharan hujah berikut adalah sah: main() main(int argc) /* sah tetapi tidak begitu baik */ main(int argc, char *argv) main(int argc, char *argv, char *env) Utama (int) declaration argc) tidak begitu mudah kerana mengetahui bilangan parameter, anda tidak mempunyai akses kepada mereka sendiri. Argumen env sentiasa boleh diakses melalui pembolehubah global persekitaran. Lihat pembolehubah persekitaran (dalam Bab 3) dan fungsi putenv dan getenv (dalam Bab 2). parameter argc dan argv juga boleh diakses melalui pembolehubah _argc dan _argv. Contoh atur cara menggunakan argc, argv dan env. Ini ialah program contoh ARGS.EXE yang menunjukkan cara paling mudah menggunakan hujah yang dihantar ke fungsi utama. /* Program ARGS.C */ #include #termasuk void main(int argc, char *argv, char *env) ( int i; printf("Nilai argc ialah %d\n\n",argc); printf("In baris arahan mengandungi %d parameter \n\n",argc); untuk (i=0; i<=argc; i++) printf(" argv[%d]: %s\n",i,argv[i]); printf("Среда содержит следующие строки:\n"); for (i=0; env[i] != NULL; i++) printf(" env[%d]: %s\n",i,env[i]); return 0; } Предположим, что вы запускаете программу ARGS.EXE со следующей командной строкой: C:>args first_arg "arg with blanks" 3 4 "last but one" stop! Ambil perhatian bahawa anda boleh menghantar hujah dengan ruang dengan melampirkannya petikan berganda, seperti yang ditunjukkan dengan "hujah dengan kosong" dan "terakhir tetapi satu" dalam contoh panggilan program. Hasil daripada menjalankan program, anda akan mendapat sesuatu seperti berikut: Nilai argc ialah 7 Baris arahan mengandungi 7 parameter argv: c:\turboc\testargs.exe argv: first_arg argv: arg dengan argv kosong: 3 argv : 4 argv: last but one argv: stop! Persekitaran mengandungi baris berikut: env: COMSPEC=C:\COMMAND.COM env: PROMPT=$p $g env: PATH=C:\SPRINT;C:\DOS;C:\BC Jumlah panjang maksimum baris arahan dihantar ke fungsi utama (termasuk ruang dan nama program itu sendiri), tidak boleh melebihi 128 aksara; Ini adalah had DOS. Aksara Melarikan Baris Perintah Hujah baris perintah boleh mengandungi aksara melarikan diri. Walau bagaimanapun, mereka boleh mengembangkan untuk semua nama fail yang sepadan dengan hujah dengan cara yang sama seperti yang dilakukan, contohnya, dengan arahan salinan DOS. Untuk menggunakan simbol melarikan diri, apabila memautkan program anda dengan pemaut, anda mesti memasukkan fail objek WILDARGS.OBJ yang disertakan dengan Borland C++. Jika fail WILDARGS.OBJ dilampirkan pada program anda, anda boleh menggunakan argumen seperti "*.*" pada baris arahan. Dalam kes ini, nama semua fail yang sepadan dengan topeng ini dimasukkan ke dalam tatasusunan argv. Saiz maksimum tatasusunan argv hanya bergantung pada volum kawasan dinamik ingatan. Jika tiada fail yang sesuai ditemui untuk topeng yang diberikan, maka hujah itu diluluskan dalam bentuk yang mana ia ditaip pada baris arahan. (Iaitu, fungsi utama diluluskan rentetan yang mengandungi aksara melarikan diri). Hujah yang disertakan dalam petikan berganda ("...") tidak dikembangkan. Contoh. Perintah berikut menyusun fail ARGS.C dan memautkannya ke modul WILDARGS.OBJ, dan kemudian jalankan program ARGS.EXE yang terhasil: bcc args wildarg.obj args C:\BORLANDC\INCLUDE\*.H "*.C" Apabila menjalankan ARGS. EXE, argumen pertama berkembang kepada nama semua fail dengan sambungan H dalam direktori Borland C++ INCLUDE. Ambil perhatian bahawa semua baris termasuk laluan penuh (contohnya C:\TC\INCLUDE\ALLOC.H). Hujah *.C tidak dikembangkan kerana ia disertakan dalam tanda petikan. Jika anda bekerja dalam Persekitaran Bersepadu (BC.EXE), maka anda hanya perlu menentukan nama dalam menu projek fail projek, yang sepatutnya mengandungi baris berikut: ARGS WILDARGS.OBJ Kemudian gunakan arahan "Run/Arguments" untuk menetapkan parameter baris arahan. Komen. Jika anda mahu pemprosesan watak melarikan diri sentiasa berlaku, i.e. Agar WILDARGS.OBJ dipautkan secara automatik oleh editor pautan, anda mesti mengubah suai perpustakaan C?.LIB standard anda untuk memasukkan fail WILDARGS.OBJ. Untuk melakukan ini, alih keluar SETARGV daripada pustaka dan tambah WILDARGS. Ini boleh dilakukan menggunakan arahan berikut (maksud kami perpustakaan standard dan WILDARGS.OBJ terkandung dalam direktori semasa): TLIB diterangkan dalam Bab 7 "Utiliti" Panduan Pengguna. tlib cs -setargv +wildargs tlib cc -setargv +wildargs tlib cm -setargv +wildargs tlib cl -setargv +wildargs tlib ch -setargv +wildargs Menyusun menggunakan suis -p (konvensyen panggilan Pascal) Jika anda menyusun atur cara anda menggunakan konvensyen panggilan Pascal (terperinci dalam Bab 9 "Mengantaramuka dengan languige pemasangan", "Panduan Pengaturcara" "), anda mesti ingat bahawa fungsi utama mesti diisytiharkan secara eksplisit sebagai fungsi C. Ini boleh dilakukan dengan kata kunci cdecl adalah seperti ini: cdecl main(int argc, char *argv, char *env) Nilai yang dikembalikan oleh fungsi utama. Fungsi utama mengembalikan nilai yang merupakan kod keluar program: ini ialah integer. Walau bagaimanapun, jika program anda menggunakan fungsi exit (atau _exit) untuk keluar, maka nilai pulangan akan menjadi hujah bagi fungsi tersebut. Contohnya, jika program anda mengandungi panggilan: exit(1) maka kod keluar ialah 1. Jika anda menggunakan persekitaran bersepadu Borland C++ (BC.EXE) untuk menjalankan program, maka anda boleh melihat nilai pulangan utama fungsi dengan memilih "Fail | Dapatkan Maklumat ".

Kemungkinan keluarga bahasa C benar-benar tidak terhad, bagaimanapun, dalam kebebasan ini terdapat juga kelemahan: pengaturcara sentiasa perlu mengawasi dan mengawal "limpahan penampan" supaya program tidak ranap kemudian. skrin biru"pada pelbagai jenis Versi Windows dan perkakasan daripada pengguna. Keropok dan pembalikan yang sama secara khusus mencari kelemahan dalam kod program C di mana mana-mana kod virus boleh ditanam; pengarang bercakap tentang perkara ini dengan lebih terperinci dalam kursus videonya. Saya belajar banyak di sana dan kini kod saya lebih selamat.

Fungsi utama.

Setiap program C dan C++ mesti mempunyai fungsi utama; dan terpulang kepada anda di mana anda meletakkannya. Sesetengah pengaturcara meletakkannya di awal fail, beberapa di penghujung. Walau bagaimanapun, tanpa mengira kedudukannya, anda perlu mengingati perkara berikut: Argumen kepada fungsi "utama". Prosedur permulaan Borland C++ menghantar tiga parameter (argumen) ke fungsi utama: argc, argv dan env. - argc, integer, ialah bilangan argumen baris arahan yang dihantar ke fungsi utama, - argv ialah tatasusunan penunjuk kepada rentetan (char *). Di bawah DOS 3.x dan lebih baru, argv ditakrifkan sebagai laluan penuh program yang akan dilancarkan. Apabila dijalankan di bawah versi DOS yang lebih awal, argv menunjuk kepada rentetan nol (""). argv menunjuk ke baris arahan pertama selepas nama program. argv menunjuk ke baris arahan kedua selepas nama program. argv menunjuk kepada hujah terakhir yang dihantar ke main. argv mengandungi NULL. - env ​​​​juga susunan penunjuk kepada rentetan. Setiap elemen env mengandungi rentetan bentuk ENVVAR=nilai. ENVVAR ialah nama pembolehubah persekitaran, seperti PATH atau 87.<значение>ini ialah nilai pembolehubah persekitaran yang diberikan, contohnya C:\DOS;C:\TOOLS (untuk PATH) atau YES (untuk 87). Walau bagaimanapun, ambil perhatian bahawa jika anda menentukan beberapa argumen ini, anda mesti menentukannya dalam susunan ini: argc, argv, env. Sebagai contoh, pengisytiharan hujah berikut adalah sah: main() main(int argc) /* sah tetapi tidak begitu baik */ main(int argc, char *argv) main(int argc, char *argv, char *env) Utama (int) declaration argc) tidak begitu mudah kerana mengetahui bilangan parameter, anda tidak mempunyai akses kepada mereka sendiri. Argumen env sentiasa boleh diakses melalui pembolehubah global persekitaran. Lihat pembolehubah persekitaran (dalam Bab 3) dan fungsi putenv dan getenv (dalam Bab 2). Parameter argc dan argv juga tersedia melalui pembolehubah _argc dan _argv. Contoh atur cara menggunakan argc, argv dan env. Ini ialah program contoh, ARGS.EXE, yang menunjukkan cara paling mudah untuk menggunakan argumen yang dihantar ke fungsi utama. /* Program ARGS.C */ #include #termasuk void main(int argc, char *argv, char *env) ( int i; printf("Nilai argc ialah %d \n\n",argc); printf("Baris arahan mengandungi %d parameter \n\ n" ,argc); untuk (i=0; i<=argc; i++) printf(" argv[%d]: %s\n",i,argv[i]); printf("Среда содержит следующие строки:\n"); for (i=0; env[i] != NULL; i++) printf(" env[%d]: %s\n",i,env[i]); return 0; } Предположим, что вы запускаете программу ARGS.EXE со следующей командной строкой: C:> args first_arg "arg with blanks" 3 4 "last but one" stop! Ambil perhatian bahawa anda boleh menghantar hujah dengan kosong dengan melampirkannya dalam petikan berganda, seperti yang ditunjukkan dalam contoh "argumen dengan kosong" dan "terakhir tetapi satu" dalam panggilan program. Hasil daripada menjalankan program, anda akan mendapat sesuatu seperti berikut: Nilai argc ialah 7 Baris arahan mengandungi 7 parameter argv: c:\turboc\testargs.exe argv: first_arg argv: arg dengan argv kosong: 3 argv : 4 argv: last but one argv: stop! Persekitaran mengandungi baris berikut: env: COMSPEC=C:\COMMAND.COM env: PROMPT=$p $g env: PATH=C:\SPRINT;C:\DOS;C:\BC Jumlah panjang maksimum baris arahan dihantar ke fungsi utama (termasuk ruang dan nama program itu sendiri), tidak boleh melebihi 128 aksara; Ini adalah had DOS. Aksara Melarikan Baris Perintah Hujah baris perintah boleh mengandungi aksara melarikan diri. Walau bagaimanapun, mereka boleh mengembangkan untuk semua nama fail yang sepadan dengan hujah dengan cara yang sama seperti yang dilakukan, contohnya, dengan arahan salinan DOS. Untuk menggunakan simbol melarikan diri, apabila memautkan program anda dengan pemaut, anda mesti memasukkan fail objek WILDARGS.OBJ yang disertakan dengan Borland C++. Jika fail WILDARGS.OBJ dilampirkan pada program anda, anda boleh menggunakan argumen seperti "*.*" pada baris arahan. Dalam kes ini, nama semua fail yang sepadan dengan topeng ini dimasukkan ke dalam tatasusunan argv. Saiz maksimum tatasusunan argv hanya bergantung pada saiz kawasan memori dinamik. Jika tiada fail yang sesuai ditemui untuk topeng yang diberikan, maka hujah itu diluluskan dalam bentuk yang mana ia ditaip pada baris arahan. (Iaitu, fungsi utama diluluskan rentetan yang mengandungi aksara melarikan diri). Hujah yang disertakan dalam petikan berganda ("...") tidak dikembangkan. Contoh. Perintah berikut menyusun fail ARGS.C dan memautkannya ke modul WILDARGS.OBJ, dan kemudian jalankan program ARGS.EXE yang terhasil: bcc args wildarg.obj args C:\BORLANDC\INCLUDE\*.H "*.C" Apabila menjalankan ARGS. EXE, argumen pertama berkembang kepada nama semua fail dengan sambungan H dalam direktori Borland C++ INCLUDE. Ambil perhatian bahawa semua baris termasuk laluan penuh (contohnya C:\TC\INCLUDE\ALLOC.H). Hujah *.C tidak dikembangkan kerana ia disertakan dalam tanda petikan. Jika anda bekerja dalam Persekitaran Bersepadu (BC.EXE), maka anda hanya perlu menentukan dalam menu projek nama fail projek, yang sepatutnya mengandungi baris berikut: ARGS WILDARGS.OBJ Kemudian, menggunakan "Run/Arguments ", anda harus menetapkan parameter baris arahan. Komen. Jika anda mahu pemprosesan watak melarikan diri sentiasa berlaku, i.e. Agar WILDARGS.OBJ dipautkan secara automatik oleh editor pautan, anda mesti mengubah suai perpustakaan C?.LIB standard anda untuk memasukkan fail WILDARGS.OBJ. Untuk melakukan ini, alih keluar SETARGV daripada pustaka dan tambah WILDARGS. Ini boleh dilakukan dengan arahan berikut (kami menganggap bahawa perpustakaan standard dan WILDARGS.OBJ terkandung dalam direktori semasa): TLIB diterangkan dalam Bab 7, Utiliti, Panduan Pengguna. tlib cs -setargv +wildargs tlib cc - setargv +wildargs tlib cm -setargv +wildargs tlib cl -setargv +wildargs tlib ch -setargv +wildargs Menyusun menggunakan suis -p (konvensyen panggilan Pascal) Jika anda menyusun atur cara anda menggunakan konvensyen panggilan Pascal (diterangkan secara terperinci dalam Bab 9 " Mengantaramuka dengan bahasa himpunan", "Panduan Pengaturcara"), anda mesti ingat bahawa fungsi utama mesti diisytiharkan secara eksplisit sebagai fungsi C. Ini boleh dilakukan menggunakan kata kunci cdecl seperti ini: cdecl main(int argc, char *argv, char *env) Nilai yang dikembalikan oleh fungsi utama. Fungsi utama mengembalikan nilai yang merupakan kod keluar program: ini ialah integer. Walau bagaimanapun, jika program anda menggunakan fungsi exit (atau _exit) untuk keluar, maka nilai pulangan akan menjadi hujah bagi fungsi tersebut. Contohnya, jika program anda mengandungi panggilan: exit(1) maka kod keluar ialah 1. Jika anda menggunakan persekitaran bersepadu Borland C++ (BC.EXE) untuk menjalankan program, maka anda boleh melihat nilai pulangan utama fungsi dengan memilih "Fail | Dapatkan Maklumat ".

Anda boleh menghantar beberapa hujah kepada program C. Apabila main() dipanggil pada permulaan pengiraan, ia diluluskan tiga parameter. Yang pertama daripada mereka menentukan bilangan hujah arahan apabila mengakses program. Yang kedua ialah tatasusunan penunjuk kepada rentetan watak mengandungi hujah-hujah ini (satu hujah setiap baris). Yang ketiga juga merupakan tatasusunan penunjuk kepada rentetan aksara; ia digunakan untuk mengakses parameter sistem pengendalian (pembolehubah persekitaran).

Mana-mana baris tersebut diwakili sebagai:

pembolehubah = nilai\0

Baris terakhir boleh ditemui oleh dua sifar mengekor.

Mari namakan argumen fungsi main() dengan sewajarnya: argc, argv dan env (sebarang nama lain boleh dilakukan). Kemudian huraian berikut boleh diterima:

utama(int argc, char *argv)

utama(int argc, char *argv, char *env)

Mari kita anggap bahawa pada pemacu A: terdapat beberapa program prog.exe. Mari kita atasinya seperti berikut:

A:\>fail prog.exe1 fail2 fail3

Kemudian argv ialah penunjuk kepada baris A:\prog.exe, argv ialah penunjuk kepada baris file1, dsb. Hujah sebenar pertama ditunjukkan oleh argv, dan yang terakhir oleh argv. Jika argc=1, maka tiada parameter selepas nama program pada baris arahan. Dalam contoh kami, argc=4.

Rekursi

Rekursi ialah kaedah panggilan di mana fungsi merujuk kepada dirinya sendiri.

Perkara penting semasa mengarang program rekursif ialah organisasi output. Kesilapan yang mudah dilakukan di sini ialah fungsi itu akan memanggil dirinya secara berurutan selama-lamanya. Oleh itu, proses rekursif mesti, langkah demi langkah, memudahkan masalah supaya akhirnya penyelesaian bukan rekursif muncul untuknya. Menggunakan rekursi tidak selalu diingini, kerana ia boleh menyebabkan limpahan tindanan.

Fungsi perpustakaan

Dalam sistem pengaturcaraan, rutin untuk menyelesaikan masalah yang sering dihadapi digabungkan ke dalam perpustakaan. Tugas tersebut termasuk: mengira fungsi matematik, input/output data, pemprosesan rentetan, interaksi dengan alat sistem pengendalian, dll. Penggunaan rutin perpustakaan melegakan pengguna keperluan untuk membangunkan alat yang sesuai dan menyediakannya perkhidmatan tambahan. Fungsi yang disertakan dalam perpustakaan dibekalkan dengan sistem pengaturcaraan. Pengisytiharan mereka diberikan dalam fail *.h (ini dipanggil fail termasuk atau pengepala). Oleh itu, seperti yang dinyatakan di atas, pada permulaan program dengan fungsi perpustakaan harus ada baris seperti:

#termasuk<включаемый_файл_типа_h>

Sebagai contoh:

#termasuk

Terdapat juga kemudahan untuk mengembangkan dan mencipta perpustakaan baharu dengan program pengguna.

Pembolehubah global diperuntukkan tempat tetap dalam ingatan untuk keseluruhan tempoh program. Pembolehubah tempatan disimpan pada timbunan. Di antara mereka terdapat kawasan memori untuk peruntukan dinamik.

Fungsi malloc() dan free() digunakan untuk peruntukan dinamik ingatan bebas. Fungsi malloc() memperuntukkan memori, fungsi free() membebaskannya. Prototaip fungsi ini disimpan dalam fail pengepala stdlib.h dan kelihatan seperti:

void *malloc(saiz_t);

void *free(void *p);

Fungsi malloc() mengembalikan penunjuk taip void; Untuk kegunaan yang betul, nilai fungsi mesti ditukar kepada penunjuk kepada jenis yang sesuai. Jika berjaya, fungsi mengembalikan penuding kepada bait pertama memori percuma saiz saiz. Jika memori tidak mencukupi, nilai 0 dikembalikan. Untuk menentukan bilangan bait yang diperlukan untuk pembolehubah, gunakan operasi sizeof().

Contoh penggunaan fungsi ini:

#termasuk

#termasuk

p = (int *) malloc(100 * sizeof(int)); /* Peruntukkan memori untuk 100

integer */

printf("Memori tidak mencukupi\n");

untuk (i = 0; i< 100; ++i) *(p+i) = i; /* Использование памяти */

untuk (i = 0; i< 100; ++i) printf("%d", *(p++));

percuma(p); /* Memori percuma */

Sebelum menggunakan penuding yang dikembalikan oleh malloc(), anda mesti memastikan bahawa terdapat memori yang mencukupi (penunjuk bukan nol).

Prapemproses

Prapemproses C ialah program yang memproses input kepada pengkompil. Prapemproses melihat program sumber dan melakukan tindakan berikut: menyambungkan fail tertentu kepadanya, melakukan penggantian, dan juga mengawal keadaan kompilasi. Baris program bermula dengan simbol # bertujuan untuk prapemproses. Hanya satu arahan (arahan prapemproses) dibenarkan untuk ditulis pada satu baris.

Arahan

#define penggantian pengecam

menyebabkan pengecam yang dinamakan digantikan dalam teks program berikutnya dengan teks penggantian (perhatikan ketiadaan koma bertitik pada akhir arahan ini). Pada asasnya, arahan ini memperkenalkan definisi makro, dengan "pengecam" ialah nama definisi makro, dan "penggantian" ialah jujukan aksara yang mana prapemproses menggantikan nama yang ditentukan apabila ia menemuinya dalam teks program. Adalah menjadi kebiasaan untuk menaip nama definisi makro dalam huruf besar.

Mari lihat contoh:

Baris pertama menyebabkan atur cara menggantikan pengecam MAX dengan pemalar 25. Baris kedua membolehkan anda menggunakan perkataan BEGIN dalam teks dan bukannya pendakap kerinting pembukaan (().

Ambil perhatian bahawa memandangkan prapemproses tidak menyemak keserasian antara nama simbolik definisi makro dan konteks di mana ia digunakan, adalah disyorkan untuk mentakrifkan pengecam tersebut bukan dengan arahan #define, tetapi menggunakan kata kunci const dengan petunjuk eksplisit jenis (ini terpakai pada tahap yang lebih besar kepada C++):

const int MAX = 25;

(jenis int boleh diabaikan, kerana ia adalah lalai).

Jika arahan #define kelihatan seperti:

#define penggantian pengecam(pengecam, ..., pengecam).

dan tiada ruang antara pengecam pertama dan kurungan pembukaan, maka ini adalah definisi penggantian makro dengan hujah. Sebagai contoh, selepas baris seperti:

#define READ(val) scanf("%d", &val)

kenyataan BACA(y); diperlakukan sama seperti scanf("%d",&y);. Di sini val ialah hujah dan penggantian makro dengan hujah dilakukan.

Sekiranya terdapat definisi panjang dalam penggantian yang berterusan untuk baris seterusnya, pada penghujung baris seterusnya dengan kesinambungan simbol \ diletakkan.

Anda boleh meletakkan objek yang dipisahkan oleh ## ke dalam definisi makro, sebagai contoh:

#define PR(x, y) x##y

Selepas ini, PR(a, 3) akan memanggil penggantian a3. Atau, sebagai contoh, definisi makro

#define z(a, b, c, d) a(b##c##d)

akan mengakibatkan menggantikan z(sin, x, +, y) dengan sin(x+y).

Simbol # diletakkan sebelum argumen makro menunjukkan bahawa ia ditukar kepada rentetan. Sebagai contoh, selepas arahan

#define PRIM(var) printf(#var"= %d", var)

serpihan teks program berikut

ditukar seperti ini:

printf("tahun""= %d", tahun);

Mari kita terangkan arahan prapemproses lain. Arahan #include telah dilihat sebelum ini. Ia boleh digunakan dalam dua bentuk:

#include "nama fail"

#termasuk<имя файла>

Tindakan kedua-dua arahan adalah untuk memasukkan fail dengan nama yang ditentukan. Yang pertama daripada mereka memuatkan fail daripada direktori semasa atau direktori yang ditentukan sebagai awalan. Perintah kedua mencari fail di lokasi standard yang ditakrifkan dalam sistem pengaturcaraan. Jika fail yang namanya ditulis dalam petikan berganda tidak ditemui dalam direktori yang ditentukan, maka carian akan diteruskan dalam subdirektori yang ditentukan untuk arahan #include<...>. #include arahan boleh bersarang antara satu sama lain.

Kumpulan arahan seterusnya membolehkan anda menyusun bahagian program secara selektif. Proses ini dipanggil kompilasi bersyarat. Kumpulan ini termasuk arahan #if, #else, #elif, #endif, #ifdef, #ifndef. Bentuk asas menulis arahan #if kelihatan seperti ini:

#jika turutan_ungkapan malar_penyataan

Di sini nilai ungkapan malar disemak. Jika ia benar, maka urutan pernyataan yang ditentukan akan dilaksanakan, dan jika ia palsu, maka urutan pernyataan ini dilangkau.

Tindakan arahan #else adalah serupa dengan tindakan arahan else dalam bahasa C, sebagai contoh:

#jika ungkapan_malar

penyataan_urutan_2

Di sini, jika ungkapan malar adalah benar, maka operator_sequence_1 dilaksanakan, dan jika palsu, operator_sequence_2 dilaksanakan.

Arahan #elif bermaksud tindakan "jika lain". Bentuk asas penggunaannya ialah:

#jika ungkapan_malar

urutan_penyata

#ungkapan_malar_elif_1

penyataan_urutan_1

#ungkapan_malar_elif

urutan_kenyataan_n

Borang ini serupa dengan konstruk bahasa C: if...else if...else if...

Arahan

#ifdef pengecam

menentukan sama ada ia ditakrifkan dalam masa ini pengecam yang ditentukan, i.e. sama ada ia dimasukkan dalam arahan seperti #define. Rentetan borang

#ifndef pengecam

menyemak sama ada pengecam yang ditentukan pada masa ini tidak ditentukan. Mana-mana arahan ini boleh diikuti dengan bilangan baris teks yang sewenang-wenangnya, mungkin mengandungi pernyataan #else (#elif tidak boleh digunakan) dan berakhir dengan baris #endif. Jika syarat yang diperiksa adalah benar, maka semua baris antara #else dan #endif diabaikan, dan jika palsu, maka baris antara semak dan #else (jika tiada perkataan #else, maka #endif). Arahan #if dan #ifndef boleh bersarang antara satu sama lain.

Lihat arahan

#undef pengecam

menyebabkan pengecam yang ditentukan dianggap tidak ditentukan, i.e. tidak tertakluk kepada penggantian.

Mari lihat contoh. Tiga arahan berikut:

semak sama ada pengecam WRITE ditakrifkan (iaitu sama ada terdapat arahan seperti #define WRITE...), dan jika ya, maka nama WRITE mula dianggap tidak ditentukan, i.e. tidak tertakluk kepada penggantian.

Arahan

#define TULIS fprintf

menyemak sama ada pengecam WRITE tidak ditentukan, dan jika ya, pengecam WRITE ditentukan dan bukannya nama fprintf.

Arahan #error ditulis dalam bentuk berikut:

#error error_message

Jika ia berlaku dalam teks program, kompilasi berhenti dan mesej ralat dipaparkan pada skrin paparan. Perintah ini digunakan terutamanya semasa fasa nyahpepijat. Ambil perhatian bahawa mesej ralat tidak perlu disertakan dalam petikan berganda.

Arahan #line bertujuan untuk menukar nilai pembolehubah _LINE_ dan _FILE_ yang ditakrifkan dalam sistem pengaturcaraan C. Pembolehubah _LINE_ mengandungi nombor baris program yang dilaksanakan dalam masa ini masa. Pengecam _FILE_ ialah penunjuk kepada rentetan dengan nama program yang sedang disusun. Arahan #line ditulis seperti berikut:

#nombor baris "nama_fail"

Nombor di sini ialah sebarang integer positif yang akan diberikan kepada pembolehubah _LINE_, nama_fail ialah parameter pilihan yang mengatasi nilai _FILE_.

Arahan #pragma membolehkan anda menghantar beberapa arahan kepada pengkompil. Sebagai contoh, garisan

menunjukkan bahawa program C mengandungi rentetan bahasa himpunan. Sebagai contoh:

Mari lihat beberapa pengecam atau nama makro global (nama definisi makro). Lima nama sedemikian ditakrifkan: _LINE_, _FILE_, _DATE_, _TIME_, _STDC_. Dua daripadanya (_LINE_ dan _FILE_) telah pun diterangkan di atas. Pengecam _DATE_ mentakrifkan rentetan di mana tarikh siaran disimpan fail sumber ke dalam kod objek. Pengecam _TIME_ menentukan rentetan yang menyimpan masa fail sumber diterjemahkan ke dalam kod objek. Makro _STDC_ mempunyai nilai 1 jika nama makro yang ditetapkan standard digunakan. Jika tidak pembolehubah ini tidak akan ditakrifkan.

Program C++ minimum ialah

Int main() ( ) // program C++ yang minimum

Program ini mengandungi pengisytiharan fungsi utama yang tidak menerima sebarang hujah. Pendakap gigi mencerminkan pengelompokan dalam C++ dan dalam dalam kes ini menunjukkan badan fungsi utama. Iaitu, permulaan fungsi utama ialah kurungan terbuka, dan penghujung fungsi utama ialah kurungan penutup. Tanda miring dua kali menunjukkan permulaan ulasan. Komen diabaikan oleh pengkompil dan berfungsi untuk menjelaskan maklumat dalam kod.

Setiap program yang ditulis dalam C++ mempunyai fungsi utama(), dari mana program ini bermula. Fungsi utama(), sebagai peraturan, mengembalikan hasil pelaksanaannya, yang ditandakan oleh int(integer - integer), yang ditulis sebelum fungsi utama(). Setelah betul, berjaya disiapkan, fungsi utama() pulangan sebagai hasilnya 0 . Nilai hasil selain daripada sifar menandakan penamatan program yang tidak normal.

Nilai pulangan program setelah selesai boleh digunakan dalam sistem operasi untuk tujuan rasmi.

Contoh tipikal program pertama dalam mana-mana bahasa pengaturcaraan ialah output teks "Hai dunia!":

#termasuk int main() ( std::cout<< "Hello, World!\n"; }

Tetapi adakah semuanya begitu mudah dalam program ini? Secara umum, program kecil ini sahaja mengandungi lapisan maklumat yang sangat besar yang mesti difahami untuk dibangunkan dalam C++.

  1. Arahan #termasuk
    #termasuk
    memberitahu pengkompil bahawa adalah perlu untuk memasukkan fail pengepala tertentu, komponen yang dirancang untuk digunakan dalam fail di mana fungsi itu diisytiharkan utama() . iostream ialah perpustakaan I/O standard daripada STL. Iaitu, fungsi perpustakaan sudah digunakan di sini, walaupun ia adalah standard untuk bahasa. Dan titik terakhir ialah kurungan sudut di mana nama perpustakaan terletak, yang menunjukkan bahawa ini adalah kemasukan fail luaran dalam projek, dan bukan yang merupakan sebahagian daripada projek. Fail yang sama yang merupakan sebahagian daripada projek disertakan dikelilingi oleh petikan biasa, sebagai contoh #include "myclass.h". Sambungan perpustakaan ini adalah standard. Contohnya, dalam Studio Visual Kegagalan mematuhi piawaian ini akan mengakibatkan ralat.
  2. std ialah penggunaan ruang nama di mana pernyataan output terletak cout. Ruang nama telah diperkenalkan dalam C++ untuk mengalih keluar konflik nama antara perpustakaan dan projek pembangun jika terdapat fungsi pendua atau nama kelas di suatu tempat. Java menggunakan sistem pakej untuk menyelesaikan konflik nama.

    cout ialah operator keluaran yang mempunyai operator terlampau beban << untuk mengelak daripada menggunakan fungsi berasingan untuk mengeluarkan teks ke konsol.

Ini adalah tambahan kepada menulis fungsi utama mungkin mengambil bentuk yang berbeza, walaupun dua entri adalah standard:

  1. int utama()
  2. int utama(int argc, char* argv)

Anda juga boleh mencari rekod seperti batal utama() dan lain-lain. Tetapi ini adalah entri yang salah, walaupun dalam beberapa penyusun mereka akan menyusun, walaupun tanpa ralat dan amaran.

Dalam rakaman int utama(int argc, char* argv) hujah diluluskan:

  1. argc- menunjukkan bilangan hujah yang diluluskan. Sentiasa sekurang-kurangnya 1, kerana nama program sentiasa diluluskan
  2. argv- tatasusunan penunjuk kepada hujah yang diluluskan sebagai pembolehubah rentetan.

Jika argc lebih besar daripada 1, ini bermakna hujah tambahan telah diluluskan apabila program dilancarkan.

Cek mungkin kelihatan seperti ini:

#termasuk int main(int argc, char* argv) ( // Jika hujah tambahan telah diluluskan, jika (argc > 1) ( // maka kami akan cuba mencetak hujah yang diterima std::cout<< argv<

Secara umum, terdapat sejumlah besar mata yang perlu difahami dalam C++ walaupun untuk program kecil, tetapi ini hanya menjadikannya lebih menarik ;-)

9 jawapan

Beberapa ciri bahasa C bermula sebagai penggodaman yang baru sahaja berfungsi.

Salah satu ciri ini ialah berbilang tandatangan untuk senarai hujah panjang dan panjang boleh ubah.

Pengaturcara telah menyedari bahawa mereka boleh menghantar hujah tambahan kepada fungsi dan tiada perkara buruk berlaku kepada pengkompil mereka.

Ini benar jika konvensyen panggilan adalah seperti berikut:

  • Fungsi panggilan mengosongkan hujah.
  • Argumen paling kiri adalah paling hampir dengan bahagian atas tindanan atau pangkal bingkai tindanan, jadi argumen palsu tidak membatalkan pengalamatan.

Satu set panggilan bersyarat yang mematuhi peraturan ini ialah penghantaran parameter berasaskan tindanan, yang menyebabkan pemanggil mengeluarkan hujah dan ia diletakkan dari kanan ke kiri:

;; pseudo-assembly-bahasa ;; utama(argc, argv, envp); panggil push envp ;; hujah paling kanan tolak argv ;; tolak argc ;; hujah paling kiri berakhir di atas pop utama panggilan tindanan;; pemanggil membersihkan pop pop

Dalam penyusun di mana konvensyen panggilan jenis ini penting, tiada apa yang istimewa perlu dilakukan untuk menyokong dua jenis utama atau jenis tambahan. main boleh menjadi fungsi tanpa hujah, dalam hal ini ia tidak memberi perhatian kepada elemen yang telah ditolak ke dalam timbunan. Jika ia adalah fungsi dua hujah, ia mendapati argc dan argv sebagai dua elemen teratas timbunan. Jika ia merupakan varian tiga hujah khusus platform dengan penuding persekitaran (sambungan biasa), ini juga akan berfungsi: ia akan menemui hujah ketiga sebagai elemen ketiga dari bahagian atas tindanan.

Maka panggilan tetap berfungsi untuk semua kes, membenarkan satu, pelancar tetap dikaitkan dengan program. Modul ini boleh ditulis dalam C sebagai fungsi yang menyerupai ini:

/* Saya menambah envp untuk menunjukkan bahawa walaupun varian khusus platform yang popular boleh dikendalikan. */ extern int main(int argc, char **argv, char **envp); void __start(void) ( /* This ialah fungsi permulaan sebenar untuk boleh laku. Ia melakukan sekumpulan permulaan perpustakaan. */ /* ... */ /* Dan kemudian: */ exit(main(argc_from_somewhere, argv_from_somewhere, envp_from_somewhere)); )

Dalam erti kata lain, modul awal ini sentiasa memanggil hujah utama dengan tiga hujah. Jika main tidak mengambil sebarang hujah atau hanya int, char ** ia berfungsi dengan baik, dan juga jika ia tidak mengambil sebarang hujah kerana memanggil konvensyen.

Jika anda melakukan perkara sedemikian dalam program anda, ia tidak akan mudah alih dan akan dianggap sebagai tingkah laku tidak ditentukan oleh ISO C: mengisytiharkan dan memanggil fungsi dalam satu cara dan mentakrifkannya dengan cara lain. Tetapi muslihat pengkompil tidak boleh mudah alih; ia tidak mengikut peraturan untuk program mudah alih.

Tetapi anggaplah konvensyen panggilan sedemikian rupa sehingga mereka tidak boleh berfungsi seperti itu. Dalam kes ini, pengkompil mesti merawat utama secara khusus. Apabila ia menyedari bahawa ia sedang menyusun fungsi utama, ia boleh menjana kod yang serasi dengan, sebagai contoh, tiga argumen.

Jadi anda tulis ini:

Int utama(kosong) ( /* ... */ )

Tetapi apabila pengkompil melihat ini, ia pada dasarnya melakukan transformasi kod supaya fungsi yang dikompilkan kelihatan seperti ini:

Int main(int __argc_ignore, char **__argv_ignore, char **__envp_ignore) ( /* ... */ )

kecuali nama __argc_ignore tidak wujud secara literal. Nama sedemikian tidak dimasukkan ke dalam skop anda dan tidak akan ada amaran tentang hujah yang tidak digunakan. Menukar kod menyebabkan pengkompil mengeluarkan kod dengan pautan yang betul, yang tahu ia perlu mengosongkan tiga hujah.

Satu lagi strategi pelaksanaan adalah untuk pengkompil, atau mungkin penghubung, untuk menjana fungsi __start tersuai (atau apa sahaja namanya), atau sekurang-kurangnya memilih daripada beberapa alternatif yang telah dikompilasi. Fail objek boleh menyimpan maklumat tentang bentuk utama yang disokong digunakan. Komponen boleh melihat maklumat ini dan memilih versi pelancar yang betul yang mengandungi panggilan ke utama yang serasi dengan definisi program. Pelaksanaan C biasanya hanya mempunyai sebilangan kecil bentuk utama yang disokong, jadi pendekatan ini boleh dilakukan.

Penyusun untuk bahasa C99 mesti sentiasa merawat utama sedikit sebanyak untuk menyokong penggodaman bahawa jika fungsi selesai tanpa penyataan pulangan, tingkah laku itu seolah-olah pulangan 0 telah dilaksanakan. Ini, sekali lagi, boleh dilihat melalui transformasi kod. Pengkompil mendapati bahawa fungsi bernama utama telah disusun. Ia kemudian menyemak untuk melihat sama ada hujung badan berpotensi untuk dicapai. Jika ya, ia memasukkan pulangan 0;

Tiada bebanan utama walaupun dalam C++. Fungsi utama ialah titik masuk untuk program, dan hanya perlu ada satu definisi.

Untuk standard C

Untuk persekitaran yang dihoskan (biasa), piawaian C99 berkata:

5.1.2.2.1 Memulakan program

Fungsi yang dipanggil apabila program bermula dipanggil utama. Pelaksanaan tidak mengisytiharkan prototaip untuk fungsi ini. Ini mesti ditakrifkan dengan jenis pengembalian int dan tiada parameter:

Int utama(kosong) ( /* ... */ )

atau dengan dua parameter (dipanggil argc dan argv di sini, walaupun sebarang nama boleh digunakan asalkan ia adalah setempat kepada fungsi di mana ia diisytiharkan):

Int utama(int argc, char *argv) ( /* ... */ )

atau setara; 9) atau mana-mana kaedah pelaksanaan lain.

9) Jadi int boleh digantikan dengan typedef yang ditakrifkan sebagai int , atau taip argv boleh ditulis sebagai char **argv , dan seterusnya.

Untuk standard C++:

3.6.1 Fungsi utama

1 Program mesti mengandungi fungsi utama global, iaitu permulaan program yang ditetapkan. [...]

2 Perlaksanaan tidak patut menentukan fungsi utama. Fungsi ini tidak boleh dibebankan. Ia mesti mempunyai jenis pulangan int, tetapi sebaliknya jenisnya ditakrifkan pelaksanaannya. Semua pelaksanaan mesti membenarkan kedua-dua takrif utama berikut:

Int main() ( /* ... */ )

Int utama(int argc, char* argv) ( /* ... */ )

Piawaian C++ secara eksplisit menyatakan: "Ia [fungsi utama] mesti mempunyai jenis pengembalian int, tetapi sebaliknya jenisnya ditentukan oleh pelaksanaan" dan memerlukan dua tandatangan yang sama seperti piawaian C.

DALAM persekitaran yang dihoskan(persekitaran C yang turut menyokong perpustakaan C) - Sistem pengendalian memanggil main .

DALAM persekitaran yang tidak dihoskan(satu adalah untuk aplikasi terbenam) anda sentiasa boleh menukar titik masuk (atau titik keluar) program anda menggunakan arahan pra-pemproses seperti

#pragma startup #pragma exit

Jika keutamaan ialah nombor kamiran pilihan.

Pragma permulaan melaksanakan fungsi sebelum utama (keutamaan) dan pragma keluar melaksanakan fungsi selepas fungsi utama. Jika terdapat lebih daripada satu arahan permulaan, keutamaan menentukan yang akan dilaksanakan dahulu.

Ini adalah salah satu asimetri aneh dan peraturan khas bahasa C dan C++.

Pada pendapat saya, ia hanya wujud atas sebab sejarah, dan tidak ada logik yang serius di sebaliknya. Ambil perhatian bahawa utama adalah istimewa untuk sebab lain juga (contohnya, utama dalam C++ tidak boleh rekursif dan anda tidak boleh mengambil alamatnya, dan dalam C99/C++ anda boleh meninggalkan penyata pulangan akhir).

Ambil perhatian bahawa walaupun dalam C++ ini tidak membebankan... sama ada program mempunyai bentuk pertama atau ia mempunyai bentuk kedua; dia tidak boleh mempunyai kedua-duanya.

Apa yang luar biasa tentang main bukanlah kerana ia boleh ditakrifkan dalam lebih daripada satu cara, ia hanya boleh ditakrifkan dalam satu daripada dua cara.

utama - fungsi pengguna; pelaksanaan tidak mengisytiharkan prototaip untuknya.

Perkara yang sama berlaku untuk foo atau bar , tetapi anda boleh menentukan fungsi dengan nama tersebut dengan cara yang anda suka.

Perbezaannya ialah utama dipanggil oleh pelaksanaan (masa jalan) dan bukan hanya oleh kod anda sendiri. Pelaksanaannya tidak dikekang oleh semantik panggilan fungsi C biasa, jadi ia boleh (dan harus) menangani pelbagai kemungkinan, tetapi tidak perlu mengendalikan banyak kemungkinan yang tidak terhingga. Borang int main(int argc, char *argv) menerima hujah baris arahan, dan int main(void) dalam C atau int main() dalam C++ hanyalah kemudahan untuk atur cara mudah yang tidak memerlukan pemprosesan argumen baris arahan.

Mengenai bagaimana pengkompil mengendalikan ini, ia bergantung kepada pelaksanaan. Kebanyakan sistem mungkin mempunyai konvensyen panggilan yang menjadikan kedua-dua borang itu serasi dengan berkesan, dan sebarang hujah yang dihantar ke utama yang ditakrifkan tanpa parameter diabaikan. Jika tidak, mudah bagi pengkompil atau penghubung untuk merawat utama secara khusus. Jika anda berminat dengan cara ini berfungsi pada sistem anda, anda mungkin ingin melihat beberapa senarai binaan.

Dan seperti banyak perkara dalam C dan C++, butirannya sebahagian besarnya adalah hasil sejarah dan keputusan sewenang-wenangnya yang dibuat oleh pereka bahasa dan pendahulunya.

Ambil perhatian bahawa kedua-dua C dan C++ membenarkan takrifan yang ditentukan pelaksanaan lain untuk main , tetapi jarang ada sebab yang baik untuk menggunakannya. Dan untuk pelaksanaan kendiri (seperti sistem terbenam tanpa OS), titik masuk program ditakrifkan pelaksanaan dan tidak semestinya dipanggil main .

main hanyalah nama untuk alamat permulaan yang diputuskan oleh pemaut, di mana utama ialah nama lalai. Semua nama fungsi dalam program adalah alamat permulaan di mana fungsi bermula.