Основни функционални параметри (argc, argv). Персонализирани функции в C

Тези уроци са за всеки, независимо дали сте нов в програмирането или имате богат опит в програмирането на други езици! Този материалза тези, които искат да научат езиците C/C++ от самите основи до най-сложните структури.

C++ е език за програмиране, познаването на този език за програмиране ще ви позволи да управлявате компютъра си Най-високо ниво. В идеалния случай ще можете да накарате компютъра да прави каквото искате. Нашият сайт ще ви помогне да овладеете езика за програмиране C++.

Инсталация /IDE

Първото нещо, което трябва да направите, преди да започнете да изучавате C++, е да се уверите, че имате IDE - интегрирана среда за разработка (програмата, в която ще програмирате). Ако нямате IDE, тогава можете. Когато решите за избор на IDE, инсталирайте го и практикувайте създаване на прости проекти.

Въведение в C++

Езикът C++ е набор от команди, които казват на компютъра какво да прави. Този набор от команди обикновено се извиква източникили просто код. Командите са или "функции", или " ключови думи" Ключовите думи (запазени думи на C/C++) са основни изграждащи блоковеезик. Функциите са сложни градивни елементи, защото са написани по отношение на повече прости функции- ще видите това в първата ни програма, която е показана по-долу. Тази структура от функции наподобява съдържанието на книга. Съдържанието може да показва главите на книгата, всяка глава в книгата може да има собствено съдържание, състоящо се от параграфи, всеки параграф може да има свои собствени подпараграфи. Въпреки че C++ предоставя много общи функцииИ запазени думи, които можете да използвате, все още има нужда да напишете свои собствени функции.

От коя част на програмата започва? Всяка програма в C++ има една функция, тя се нарича основна или основна функция, изпълнението на програмата започва с тази функция. от Главна функция, можете също така да извиквате всякакви други функции, независимо дали са тези, които сме написали или, както споменахме по-рано, предоставени от компилатора.

И така, как да получите достъп до тези стандартни функции? Влизам стандартни функции, които идват с компилатора, трябва да включите заглавния файл, като използвате директивата за препроцесор - #include. Защо това е ефективно? Нека разгледаме един пример работна програма:

#включи << "Моя первая программа на С++\n"; cin.get(); }

Нека разгледаме по-подробно елементите на програмата. #include е директива за "препроцесор", която казва на компилатора да постави кода от заглавния файл на iostream в нашата програма, преди да създаде изпълнимия файл. Като свържете заглавен файл към програма, получавате достъп до много различни функции, които можете да използвате във вашата програма. Например, операторът cout изисква iostream. Ред, използващ пространство от имена std; казва на компилатора да използва група функции, които са част от стандартната библиотека std. Този ред също позволява на програмата да използва оператори като cout. Точката и запетая е част от синтаксиса на C++. Той казва на компилатора, че това е краят на командата. След малко ще видите, че точката и запетая се използват за прекратяване на повечето команди в C++.

Следващият важен ред на програмата е int main(). Този ред казва на компилатора, че има функция, наречена main и че функцията връща цяло число. Къдрави скоби ( и ) означават началото (и края) на функция. Къдравите скоби се използват и в други блокове код, но те винаги показват едно нещо - съответно началото и края на блока.

В C++ обектът cout се използва за показване на текст (произнася се "C out"). Той използва символи<< , известные как «оператор сдвига», чтобы указать, что отправляется к выводу на экран. Результатом вызова функции cout << является отображение текста на экране. Последовательность \n фактически рассматривается как единый символ, который обозначает новую строку (мы поговорим об этом позже более подробно). Символ \n перемещает курсор на экране на следующую строку. Опять же, обратите внимание на точку с запятой, её добавляют в конец, после каждого оператора С++.

Следващата команда е cin.get(). Това е друго извикване на функция, което чете данни от входния поток от данни и чака да бъде натиснат клавишът ENTER. Тази команда предпазва прозореца на конзолата от затваряне, докато не бъде натиснат клавишът ENTER. Това ви дава време да видите резултата от програмата.

При достигане на края на основната функция (затварящата фигурна скоба), нашата програма ще върне стойността 0 на операционната система. Тази върната стойност е важна, защото като я анализира, ОС може да прецени дали нашата програма е завършила успешно или не. Върната стойност 0 означава успех и се връща автоматично (но само за типа данни int; други функции изискват ръчно връщане на стойността), но ако искаме да върнем нещо друго, като 1, ще трябва да го направим ръчно.

#включи използване на пространство от имена std; int main() ( cout<<"Моя первая программа на С++\n"; cin.get(); return 1; }

За да консолидирате материала, въведете програмния код във вашата IDE и го стартирайте. След като програмата се изпълни и сте видели резултата, експериментирайте малко с израза cout. Това ще ви помогне да свикнете с езика.

Не пропускайте да коментирате вашите програми!

Добавете коментари към вашия код, за да го направите по-ясен не само за себе си, но и за другите. Компилаторът игнорира коментарите при изпълнение на код, което ви позволява да използвате произволен брой коментари, за да опишете действителния код. За да създадете коментар, използвайте или // , което казва на компилатора, че останалата част от реда е коментар, или /* и след това */ . Когато се учите да програмирате, е полезно да можете да коментирате части от кода, за да видите как се променя резултатът от програмата. Можете да прочетете подробно за техниката на коментиране.

Какво да правим с всички тези типове променливи?

Понякога може да бъде объркващо да имате множество типове променливи, когато някои типове променливи изглеждат излишни. Много е важно да използвате правилния тип променлива, тъй като някои променливи изискват повече памет от други. Освен това, поради начина, по който се съхраняват в паметта, числата с плаваща запетая, типовете данни float и double са „неточни“ и не трябва да се използват, когато трябва да се съхрани точна целочислена стойност.

Деклариране на променливи в C++

За да декларирате променлива, използвайте типа синтаксис<имя>; . Ето няколко примера за декларации на променливи:

Int num; овъглен характер; float num_float;

Допустимо е да се декларират няколко променливи от един и същи тип на един ред, като всяка от тях трябва да бъде разделена със запетая.

Int x, y, z, d;

Ако сте се вгледали внимателно, може да сте видели, че декларацията на променлива винаги е последвана от точка и запетая. Можете да научите повече за конвенцията „за именуване на променливи“.

Често срещани грешки при деклариране на променливи в C++

Ако се опитате да използвате променлива, която не е декларирана, вашата програма няма да се компилира и ще получите съобщение за грешка. В C++ всички ключови думи на езика, всички функции и всички променливи са чувствителни към главни и малки букви.

Използване на променливи

Така че сега знаете как да декларирате променлива. Ето примерна програма, демонстрираща използването на променлива:

#включи използване на пространство от имена std; int main() ( int число; cout<< "Введите число: "; cin >>номер; cin.ignore(); cout<< "Вы ввели: "<< number <<"\n"; cin.get(); }

Нека да разгледаме тази програма и да разгледаме нейния код ред по ред. Ключовата дума int показва, че числото е цяло число. Функцията cin >> чете стойността в число, потребителят трябва да натисне enter след въведеното число. cin.ignore() е функция, която чете знак и го игнорира. Организирали сме въвеждането си в програмата, след въвеждане на число натискаме клавиша ENTER, символ, който също се предава на входния поток. Не ни трябва, затова го изхвърляме. Имайте предвид, че променливата е декларирана като цяло число, ако потребителят се опита да въведе десетично число, то ще бъде съкратено (т.е. десетичната част от числото ще бъде игнорирана). Опитайте да въведете десетично число или поредица от знаци, когато стартирате примерната програма, отговорът ще зависи от въведената стойност.

Обърнете внимание, че при отпечатване от променлива не се използват кавички. Липсата на кавички казва на компилатора, че има променлива и следователно програмата трябва да провери стойността на променливата, за да замени името на променливата с нейната стойност при изпълнение. Множество изявления за смяна на един и същи ред са напълно приемливи и изходът ще бъде направен в същия ред. Трябва да разделите низовите литерали (низове, затворени в кавички) и променливите, давайки на всеки собствен оператор за смяна<< . Попытка поставить две переменные вместе с одним оператором сдвига << выдаст сообщение об ошибке . Не забудьте поставить точку с запятой. Если вы забыли про точку с запятой, компилятор выдаст вам сообщение об ошибке при попытке скомпилировать программу.

Промяна и сравняване на стойности

Разбира се, без значение какъв тип данни използвате, променливите не са много интересни без възможността да променяте стойността си. По-долу са показани някои оператори, използвани във връзка с променливи:

  • * умножение,
  • - изваждане,
  • + допълнение,
  • / деление,
  • = задание,
  • == равенство,
  • > още
  • < меньше.
  • != неравен
  • >= по-голямо или равно на
  • <= меньше или равно

Операторите, които изпълняват математически функции, трябва да се използват отдясно на знака за присвояване, за да се присвои резултатът на променливата отляво.

Ето няколко примера:

A = 4 * 6; // използвайте коментар за ред и точка и запетая, a е равно на 24 a = a + 5; // равно на сумата от първоначалната стойност и пет a == 5 // не присвоява пет, проверява дали е равно на 5 или не

Често ще използвате == в конструкции като условни изрази и цикли.

А< 5 // Проверка, a менее пяти? a >5 // Проверка, повече от пет ли е? a == 5 // Проверка, равно ли е на пет? a != 5 // Проверете, не е ли равно на пет? a >= 5 // Проверка дали a е по-голямо или равно на пет? а<= 5 // Проверка, a меньше или равно пяти?

Тези примери не показват много ясно използването на знаци за сравнение, но когато започнем да изучаваме операторите за избор, ще разберете защо това е необходимо.

9 отговора

Някои от функциите на езика C започват като хакове, които току-що проработиха.

Една от тези характеристики е множество подписи за основни, както и списъци с аргументи с променлива дължина.

Програмистите са забелязали, че могат да предадат допълнителни аргументи на функция и нищо лошо да не се случи с техния компилатор.

Това е вярно, ако конвенциите за извикване са такива, че:

  • Извикващата функция изчиства аргументите.
  • Най-левите аргументи са най-близо до горната част на стека или основата на рамката на стека, така че неверните аргументи не обезсилват адресирането.

Един набор от условни извиквания, които се подчиняват на тези правила, е предаване на параметри, базирано на стека, което кара повикващия да издава аргументи и те се поставят отдясно наляво:

;; псевдо-асемблен език ;; основен (argc, argv, envp); повикване, натискане на envp;; най-десният аргумент push argv ;; натиснете argc ;; най-левият аргумент завършва в горната част на извикване на стека main pop ;; повикващият почиства поп поп

В компилаторите, където този тип конвенция за извикване има значение, не трябва да се прави нищо специално, за да се поддържат два основни типа или дори допълнителни типове. main може да бъде функция без аргументи, в който случай тя не обръща внимание на елементи, които са били избутани в стека. Ако е функция с два аргумента, тя намира argc и argv като горните два елемента на стека. Ако това е специфичен за платформата вариант с три аргумента с указател на среда (общо разширение), това също ще работи: ще намери третия аргумент като третия елемент от върха на стека.

И така фиксираното повикване работи за всички случаи, позволявайки един фиксиран стартер да бъде свързан с програмата. Този модул може да бъде написан на C като функция, наподобяваща тази:

/* Добавям envp, за да покажа, че дори популярен специфичен за платформата вариант може да бъде обработен. */ extern int main(int argc, char **argv, char **envp); void __start(void) ( /* Това е истинската функция за стартиране на изпълнимия файл. Той изпълнява набор от инициализации на библиотеката */ /* ... */ /* И след това: */ exit(argc_from_somewhere, argv_from_somewhere, envp_from_somewhere));

С други думи, този първоначален модул винаги извиква главния аргумент с три аргумента. Ако main не приема никакви аргументи или само int, char ** работи добре, а също и ако не приема никакви аргументи поради конвенциите за извикване.

Ако правите такива неща във вашата програма, тя няма да бъде преносима и ще се счита за недефинирано поведение от ISO C: деклариране и извикване на функция по един начин и дефинирането й по друг. Но трикът за изпълнение на компилатора не трябва да бъде преносим; не следва правилата за преносими програми.

Но да предположим, че конвенциите за извикване са такива, че не могат да работят по този начин. В този случай компилаторът трябва да третира специално main. Когато забележи, че компилира основната функция, той може да генерира код, който е съвместим например с три аргумента.

Така че пишете това:

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

Но когато компилаторът види това, той по същество извършва трансформация на код, така че функцията, която компилира, да изглежда по следния начин:

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

освен че имената __argc_ignore не съществуват буквално. Такива имена не се въвеждат във вашия обхват и няма да има предупреждения за неизползвани аргументи. Преобразуването на кода кара компилатора да излъчва код с правилната връзка, който знае, че трябва да изчисти три аргумента.

Друга стратегия за внедряване е компилаторът или може би линкерът да генерира по избор функцията __start (или както се нарича) или поне да избира от няколко предварително компилирани алтернативи. Обектният файл може да съхранява информация за това коя от поддържаните форми на main се използва. Компонентът може да разгледа тази информация и да избере правилната версия на програмата за стартиране, която съдържа извикване на main, което е съвместимо с дефиницията на програмата. C реализациите обикновено имат само малък брой поддържани основни форми, така че този подход е възможен.

Компилаторите за езика C99 винаги трябва да третират main до известна степен, за да поддържат хака, че ако дадена функция завърши без израз за връщане, поведението е така, сякаш return 0 е било изпълнено. Това отново може да се види чрез трансформация на код. Компилаторът забелязва, че е компилирана функция с име main. След това проверява дали краят на тялото е потенциално достъпен. Ако е така, той вмъква return 0;

Няма претоварване на main дори в C++. Основната функция е входната точка за програмата и трябва да има само една дефиниция.

За стандарт C

За хоствана среда (обикновена) стандартът C99 казва:

5.1.2.2.1 Стартиране на програмата

Функцията, извикана при стартиране на програмата, се нарича main. Реализацията не декларира прототип за тази функция. Това трябва да се дефинира с връщащ тип int и без параметри:

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

или с два параметъра (наричани тук argc и argv, въпреки че могат да се използват всякакви имена, стига да са локални за функцията, в която са декларирани):

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

или еквивалентно; 9) или всеки друг метод на изпълнение.

9) Така int може да бъде заменено с typedef, дефинирано като int, или type argv може да бъде записано като char **argv и т.н.

За стандартен C++:

3.6.1 Основна функция

1 Програмата трябва да съдържа глобална основна функция, която е указаното начало на програмата. [...]

2 Изпълнение не трябвапредопределят основната функция. Тази функция не трябва да се претоварва. Трябва да има връщащ тип int, но в противен случай неговият тип е дефиниран от изпълнението. Всички реализации трябва да приемат и двете от следните дефиниции на main:

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

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

Стандартът C++ изрично заявява: „Тя [основната функция] трябва да има тип на връщане int, но в противен случай типът й се определя от изпълнението“ и изисква същите два подписа като стандарта C.

IN хоствана среда(C среда, която също поддържа C библиотеки) - Операционната система извиква main .

IN нехоствана среда(единият е за вградени приложения) винаги можете да промените входната точка (или изходната точка) на вашата програма, като използвате предпроцесорни директиви като

#pragma стартиране #pragma изход

Ако приоритетът е незадължителен интегрален номер.

Стартовата прагма изпълнява функцията преди основната (приоритетна), а изходната прагма изпълнява функцията след основната функция. Ако има повече от една директива за стартиране, приоритетът определя коя ще бъде изпълнена първа.

Това е една от странните асиметрии и специални правила на езика C и C++.

Според мен тя съществува само по исторически причини и зад нея няма реална сериозна логика. Обърнете внимание, че main е специален и по други причини (например main в C++ не може да бъде рекурсивен и не можете да вземете адреса му, а в C99/C++ можете да пропуснете крайния оператор return).

Имайте предвид, че дори в C++ това не е претоварващо... или програмата има първата форма, или има втората форма; той не може да има и двете.

Необичайното за main не е, че може да се дефинира по повече от един начин, а само по един от двата начина.

основна - потребителска функция; изпълнението не декларира прототип за него.

Същото важи и за foo или bar, но можете да дефинирате функции с тези имена, както желаете.

Разликата е, че main се извиква от изпълнението (времето за изпълнение), а не само от вашия собствен код. Реализацията не е ограничена от обичайната семантика на извикване на C функция, така че може (и трябва) да работи с множество възможности, но не е необходимо да обработва безкрайно много възможности. Формата int main(int argc, char *argv) приема аргументи от командния ред, а int main(void) в C или int main() в C++ е просто удобство за прости програми, които не изискват обработка на аргументи от командния ред.

Що се отнася до това как компилаторът се справя с това, зависи от изпълнението. Повечето системи вероятно имат конвенции за извикване, които правят двете форми ефективно съвместими и всички аргументи, предадени на main, които са дефинирани без параметри, се игнорират. В противен случай би било лесно за компилатора или линкера да третира специално main. Ако се интересувате как работи това на вашата система, може да искате да разгледате някои списъци с компилации.

И като много неща в C и C++, детайлите са до голяма степен резултат от историята и произволни решения, взети от дизайнерите на езиците и техните предшественици.

Имайте предвид, че както C, така и C++ позволяват други дефинирани от имплементацията дефиниции за main , но рядко има основателна причина да ги използвате. А за самостоятелни реализации (като вградени системи без операционна система), входната точка на програмата е дефинирана от имплементацията и дори не е задължително да се нарича main.

main е просто името за началния адрес, определено от линкера, където main е името по подразбиране. Всички имена на функции в една програма са началните адреси, където започва функцията.

Възможностите на семейството на езиците C са наистина неограничени, но в тази свобода има и недостатъци: програмистът винаги трябва да следи и да контролира „препълването на буфера“, така че по-късно програмата да не се срине в „ син екран” на много различни версии на Windows и потребителски хардуер. Същите кракери и реверсъри специално търсят уязвимости в кода на C програмите, където може да бъде поставен всеки вирусен код; авторът говори за това по-подробно в своя видео курс. Научих много там и сега кодът ми е много по-сигурен.

Основна функция.

Всяка C и C++ програма трябва да има основна функция; и от вас зависи къде ще го поставите. Някои програмисти го поставят в началото на файла, други в края. Въпреки това, независимо от нейната позиция, трябва да запомните следното: Аргументи към функцията "main". Процедурата за стартиране на Borland C++ изпраща три параметъра (аргумента) към основната функция: argc, argv и env. - argc, цяло число, е броят на аргументите на командния ред, изпратени към основната функция, - argv е масив от указатели към низове (char *). Под DOS 3.x и по-нови, argv се дефинира като пълния път на програмата, която трябва да бъде стартирана. Когато работи под по-стари версии на DOS, argv сочи към нулев низ (""). argv сочи към първия ред на командния ред след името на програмата. argv сочи към втория ред на командния ред след името на програмата. argv сочи към последния аргумент, изпратен на main. argv съдържа NULL. - env ​​​​е също масив от указатели към низове. Всеки елемент env съдържа низ във формата ENVVAR=стойност. ENVVAR е името на променлива на средата, като PATH или 87.<значение>това е стойността на дадена променлива на средата, например C:\DOS;C:\TOOLS (за PATH) или YES (за 87). Имайте предвид обаче, че ако посочите някои от тези аргументи, трябва да ги посочите в следния ред: argc, argv, env. Например следните декларации на аргументи са валидни: main() main(int argc) /* валиден, но не много добър */ main(int argc, char *argv) main(int argc, char *argv, char *env) Main (int) декларация argc) не е много удобно, защото знаейки броя на параметрите, вие сами нямате достъп до тях. Аргументът env винаги е достъпен чрез глобалната променлива environ. Вижте променливата environ (в глава 3) и функциите putenv и getenv (в глава 2). Параметрите argc и argv също са достъпни чрез променливите _argc и _argv. Примерна програма, използваща argc, argv и env. Това е примерна програма, ARGS.EXE, която демонстрира най-простия начин за използване на аргументите, предадени на основната функция. /* ARGS.C програма */ #include #включи void main(int argc, char *argv, char *env) ( int i; printf("Стойността на argc е %d \n\n",argc); printf("Командният ред съдържа %d параметъра \n\ n" ,argc);<=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 с празни места" 3 4 "предпоследен" стоп! Обърнете внимание, че можете да изпратите аргумент с празни места, като го поставите в двойни кавички, както е показано в примера „аргумент с празни места“ и „предпоследен“ в извикването на програмата. В резултат на стартиране на програмата ще получите нещо подобно: Стойността на argc е 7 Командният ред съдържа 7 параметъра argv: c:\turboc\testargs.exe argv: first_arg argv: arg с празно argv: 3 argv: 4 argv: предпоследен argv: спри! Средата съдържа следните редове: env: COMSPEC=C:\COMMAND.COM env: PROMPT=$p $g env: PATH=C:\SPRINT;C:\DOS;C:\BC Максималната обща дължина на командата редът, изпратен към основната функция (включително интервалите и името на самата програма), не може да надвишава 128 знака; Това са ограничения на DOS. Символи за екраниране на командния ред Аргументите на командния ред могат да съдържат символи за екраниране. Те обаче могат да се разширяват за всички имена на файлове, които съответстват на аргумента, по същия начин, както се прави например с командата за копиране на DOS. За да използвате екраниращи символи, когато свързвате вашата програма с линкера, трябва да включите обектния файл WILDARGS.OBJ, който идва с Borland C++. Ако файлът WILDARGS.OBJ е прикачен към вашата програма, можете да използвате аргументи като "*.*" в командния ред. В този случай имената на всички файлове, отговарящи на тази маска, се въвеждат в масива argv. Максималният размер на масива argv зависи само от размера на областта на динамичната памет. Ако не са намерени подходящи файлове за дадена маска, тогава аргументът се предава във формата, в която е въведен в командния ред. (Тоест на основната функция се предава низ, съдържащ екраниращи знаци). Аргументите, оградени в двойни кавички („...“), не се разширяват. Пример. Следните команди компилират файла ARGS.C и го свързват с модула WILDARGS.OBJ и след това стартират получената програма ARGS.EXE: bcc args wildarg.obj args C:\BORLANDC\INCLUDE\*.H "*.C" Когато стартирате ARGS, първият аргумент се разширява до имената на всички файлове с разширение H в директорията Borland C++. Имайте предвид, че всички редове включват пълния маршрут (например C:\TC\INCLUDE\ALLOC.H). Аргументът *.C не е разширен, защото той е ограден в кавички. Ако работите в интегрирана среда (BC.EXE), тогава просто трябва да посочите в менюто на проекта името на файла на проекта, който трябва да съдържа следните редове: ARGS WILDARGS.OBJ След това, като използвате "Run/Arguments ", трябва да зададете параметрите на командния ред. Коментирайте. Ако искате обработката на екраниращи символи да се извършва винаги, т.е. За да може WILDARGS.OBJ да бъде автоматично свързан от редактора на връзки, трябва да промените вашата стандартна библиотека C?.LIB, за да включите файла WILDARGS.OBJ. За да направите това, премахнете SETARGV от библиотеката и добавете WILDARGS. Това може да се направи със следните команди (предполагаме, че стандартните библиотеки и WILDARGS.OBJ се съдържат в текущата директория): TLIB е описано в Глава 7, Помощни програми, на Ръководството на потребителя tlib cs -setargv +wildargs tlib cc -. setargv +wildargs tlib cm -setargv +wildargs tlib cl -setargv +wildargs tlib ch -setargv +wildargs Компилиране с помощта на превключвателя -p (Конвенция за извикване на Pascal) Ако компилирате програмата си с помощта на конвенцията за извикване на Pascal (описана подробно в Конвенцията за извикване на Pascal ). Глава 9 "Взаимодействие с асемблер", "Ръководство за програмиста"), трябва да запомните, че основната функция трябва да бъде изрично декларирана като функция C. Това може да се направи с помощта на ключовата дума cdecl, нещо подобно: cdecl main(int argc , char *argv, char *env) Стойността, върната от основната функция. Основната функция връща стойност, която е изходният код на програмата: това е цяло число. Ако обаче вашата програма използва функцията exit (или _exit) за изход, тогава върнатата стойност ще бъде аргументът на тази функция. Например, ако вашата програма съдържа извикване: exit(1), тогава кодът за изход ще бъде 1. Ако използвате интегрираната среда на Borland C++ (BC.EXE), за да стартирате програмата, тогава можете да видите върнатата стойност на main функция, като изберете "Файл | Получаване на информация ".

Страница 53 от 85

1.5.3. Предаване на параметри към основната функция

Основната функция, която започва изпълнението на C програма, може да бъде дефинирана с параметри, които се предават от външната среда, например от командния ред. Външната среда има свои собствени правила за представяне на данни, или по-скоро всички данни се представят под формата на символни низове. За да предадат тези низове към основната функция, се използват два параметъра, като първият параметър се използва за предаване на броя низове, които трябва да бъдат предадени, а вторият се използва за предаване на самите низове. Общите (но не задължителни) имена за тези параметри са argc и argv. Параметърът argc е от тип int, стойността му се формира от анализ на командния ред и е равна на броя думи в командния ред, включително името на извиканата програма (дума е всеки текст, който не съдържа интервал характер). Параметърът argv е масив от указатели към низове, всеки от които съдържа една дума от командния ред. Ако една дума трябва да съдържа знак за интервал, тя трябва да бъде оградена в кавички, когато я записвате в командния ред.

Основната функция може да има и трети параметър, който обикновено се нарича argp и служи за прехвърляне към основната функция на параметрите на операционната система (средата), в която се изпълнява програмата на езика за програмиране C.

Заглавката на основната функция изглежда така:

Ако например командният ред на програма на езика за програмиране C изглежда така:

A:\>cprog работи "C програма" 1

тогава аргументите argc, argv, argp са представени в паметта, както е показано на диаграмата на фиг. 1.

Argc[4]
argv --> -->
-->
-->
-->
argp --> -->
-->
-->
-->
Фиг. 1. Оформление на параметрите на командния ред

Операционната система поддържа предаване на стойности за параметрите argc, argv, argp и е отговорност на потребителя да предава и използва действителните аргументи към основната функция.

Следващият пример е програма, която отпечатва действителните аргументи, предадени на основната функция от операционната система и параметрите на операционната система.

Пример:
int main (int argc, char *argv, char *argp)
( int i=0;
printf("\nИме на програмата %s", argv);
за (i=1; i>=argc; i++)
printf("\n аргумент %d е %s", argv[i]);
printf("\nНастройки на операционната система:");
докато (*argp)
( printf ("\n %s",*argp);
argp++;
}
връщане (0);
}

Параметрите на операционната система могат да бъдат достъпни и чрез функцията на библиотеката geteuv, нейният прототип изглежда така:

char *geteuv (const char *varname);

Аргументът на тази функция указва името на параметъра на средата, указател към стойността на който ще бъде върнат от функцията geteuv. Ако зададеният параметър в момента не е дефиниран в средата, върнатата стойност е NULL.

С помощта на указателя, получен от функцията geteuv, можете само да прочетете стойността на параметъра на операционната система, но не можете да го промените. Функцията puteuv се използва за промяна на стойността на системен параметър.

Компилаторът на езика за програмиране C конструира C програма по такъв начин, че в началото на програмата се извършва известна инициализация, включително, наред с други неща, обработка на аргументите, предадени на основната функция, и предаване на стойностите на параметрите на средата. Тези действия се извършват от библиотечните функции _setargv и _seteuv, които винаги се поставят преди основната функция от компилатора.

Ако програма на езика за програмиране C не използва предаването на аргументи и стойности на параметрите на операционната система, тогава е препоръчително да се забрани използването на библиотечните функции _setargv и _seteuv чрез поставяне в програмата C на езика за програмиране, преди основната функция, функции със същите имена, но които не извършват никакви действия (stubs). Началото на програмата в този случай ще изглежда така:

setargv()
}
-seteuv()
( return ; /* празна функция */
}
int main()
( /* основна функция без аргументи */
...
...
връщане (0);
}

В горната програма, при извикване на библиотечните функции _setargv и _seteuv, функциите, поставени в програмата от потребителя, ще бъдат използвани и няма да извършват никакви действия. Това значително ще намали размера на получения exe файл.