Dwa wyprosa za C :)

33 отговора 1457 прегледа
#1

Dwa wyprosa za C :)

Значи първият е :
for(;;){
int i; // С каква цел се декларира променливата в тялото на цикъла?
// т.е. как ще се изпълни това нещо?
...
}

и вторият:

for(;;) - защо толкова често се използва дази форма а не нещо от сорта на while (1 == 1) ?

Мерси за отделеното внимание и евентуално за отговорите :))

Отговор
в отговор на ceci_ #2

Re: Dwa wyprosa za C :)

ами първия случай - променивата ще е валидна само за тялото на цикъла, докато ако беше for(int i=.....) щеше да е валидна и след цикъла

втория - аз ползвам while(1) явно е въпрос на вкус

Отговор
в отговор на zaphod #3

Re: Dwa wyprosa za C :)

abe ne si suwsem praw mai w po edno wreme ansi standarta pisheshe
drugo. ama ne sym go chel skoro :)

Отговор
в отговор на zaphod #4

Re: Dwa wyprosa za C :)

1. Това че променливата е локална за тялото на цикъла и аз го предположих, защото тялото е отделено в отделен блок "{...}". Смущава ме това, че всъщност тази декларация ще се изпълнява многократно /колкото итерации направи цикъла/. Освен това сега опитах
следното

#include <stdio.h>

int main(void){
int i;
i = 2;
printf("%d\n", i);
int i;
i = 10;
printf("%d\n", i);

return 0;
}

Както и очаквах, даде грешка на втората декларация. Сега пробвах следното

#include <stdio.h>


int main(void){

for (;;){
int i;
printf("%d\n", i);
i ++;
}

return 0;
}

резултата е доста дълъг :)))))), но ето извадка:

1074971423
1074971424
1074971425
1074971426
1074971427
1074971428
1074971429
1074971430
1074971431
1074971432
1074971433
1074971434
1074971435
1074971436
1074971437
1074971438
1074971439
1074971440
1074971441
1074971442
1074971443
1074971444
1074971445

на мен ми прилича на случайно число в i което се установява само веднъж след което се инкрементира, т.е. след първта итерация декларацията, като че ли се подминава.
Обаче ако пробвам това:
#include <stdio.h>


int main(void){

for (;;){
int i=0;
printf("%d\n", i);
i ++;
}

return 0;
}
се получават само нули т.е. присвояването на нула явно се изпълнява всеки път.

2. :)

Отговор
в отговор на ceci_ #5

Re: Dwa wyprosa za C :)

omeshwash mnogo neshta
declaracia na promenliwa,
int i;
ako towa e w ramkite na niakakyw blok, i ne e inicializrana,
no niakoi kompilatori koito prawiat "debug versii" inicializrat
s opredelena stoinost.
ako e statichna ( t.e. izwyn wsiakaki funkcii ili obiawena kato static )
se inicializira awtomatichno s 0

inicializacia pri declarirane
int i=0;
inicializaciite sa ednokratni :)

priswoiawane
i=0;
kolkoto pyti mine ot tam tolkowa shte se izpylni :)

int i=0; ne e syshtoto kato
int i;
i = 0;

towa koeto te obyrkwa e lipsata na poniatie za "obhwat" (scope)
i jiznenia cikyl na promenliwite.

kupi si knijka !!!

Отговор
в отговор на hhh #6

Re: Dwa wyprosa za C :)

omeshwash mnogo neshta
declaracia na promenliwa,
int i;
Това мисля че правилно го споменах.

ako towa e w ramkite na niakakyw blok, i ne e inicializrana,
no niakoi kompilatori koito prawiat "debug versii" inicializrat
s opredelena stoinost.
Това хубаво, както дадох в примерчета по-горе, явно се вижда че при
in i; i - не е инициализирана с някаква определена стойност, за това казах че идва случайна стойност която се инкрементира.

ako e statichna ( t.e. izwyn wsiakaki funkcii ili obiawena kato static )
se inicializira awtomatichno s 0
Хубаво, с това не споря, но въобще не ставаше дума за това.

inicializacia pri declarirane
int i=0;
inicializaciite sa ednokratni :)
priswoiawane
i=0;
kolkoto pyti mine ot tam tolkowa shte se izpylni :)
супер, обаче и това не ме изненда:)))

int i=0; ne e syshtoto kato
int i;
i = 0;
мда разбира се.

towa koeto te obyrkwa e lipsata na poniatie za "obhwat" (scope)
i jiznenia cikyl na promenliwite.
Ужас просто. Всъшност аз написах точно какво не ми е ясно и явно не съм го намерил
другаде, но естествено търсенето продължава ;-).

kupi si knijka !!!
Мерси отивам.

А сега все пак да се върнем на въпроса
1. Защо това компилатора не го позволява:
#include <stdio.h>

int main(void){
int i;
i++;
printf("%d\n", i);
int i;
i++;
printf("%d\n", i);
return 0;
}
a towa:

#include <stdio.h>

int main(void){
for (;;){
int i;
printf("%d\n", i);
i++;
}
return 0;
}.
го позволява
2. Защо във втория пример, в първия случай, когато "int i;", то се получават последователни числа, а не да кажем просто някакви числа и зашо когато "int i=0;" то се получават винаги 0?

Отговор
в отговор на ceci_ #7

Re: Dwa wyprosa za C :)

така, първият случай е отявленна грешка - ползваш в един блок две променливи с едно име
вторият случай е по-интересен. значи при декларация на глобална променлива по стандарт тя се инициализира с 0 или нули. но при локалните няма такова нещо - смята се че е неопределена стойност. обаче ако типа на променливата има конструктор, то той се извиква при декларацията. така че в този случай, ако i беше сложен тип конструктора ще се вика всеки път мисля.

Отговор
в отговор на zaphod #8

Re: Dwa wyprosa za C :)

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

Отговор
в отговор на ceci_ #9

Re: Dwa wyprosa za C :)

Не. Някой май вече спомена, че когато променливата е декларирана в блок {}, извън него тя е out of scope и все едно не е била декларирана.

Обаче това не обяснява increment-ването на произволната стойност от примера.
Нито го обяснява и поста на hhh, който само ни каза че не знаем какво е scope и ни прати за книжки.

Може би ако бъде така добър да ни обясни? Или може той е повече по библиотечното дело отколкото по програмирането

SKINHEADS - MORE HAIR THAN BRAIN
Отговор
в отговор на ceci_ #10

Re: Dwa wyprosa za C :)

Не, няма да стане!
"int i;" в тялото на цикъла е дефиниране на стек променлива - без да и е
зададена начална стойност. Което значи, че компилатора ще и задели един път място в паметта. Т.е., това i ще си има вече адрес в паметта. Щом е така -
това i ще има някаква стойност - стойността, която е записана в тоя адрес
на паметта. тази стойност може да е случайна, може да е определена от компилатора (някои го правят в debug mode).
Е, нататъка е лесно: i++ просто ще я увеличава тази стойност всеки път, когато се изпълнява тялото на цикъла.
Това, че променливата е декларирана в цикъла, не значи, че тя ще заеме N
адреса в паметта, ако N са итерациите на цикъла.
Това значи, че просто тя е видима само в тялото на цикъла и не е достъпна извън цикъла.

Отговор
в отговор на Vroomfundel #11

Re: Dwa wyprosa za C :)

Мерси за отговора, вече мисля че ми стана ясно ;-)
Всеки път като започва цикъла, започва нов блок, в който напълно коректно е да се декларира променлива с това име. От друга страна страничният ефект, явно идва от това, че всеки път, за i се отделя същата памет и тъй като не се инициа лизира, остава предишната стойност :))

мда, пак мерси :))

Отговор
в отговор на Zelen #12

10x

Мерси и на теб за разясненията

Отговор
в отговор на zaphod #13

Re: Dwa wyprosa za C :)

> ами първия случай - променивата ще е валидна само за тялото на цикъла,
> докато ако беше for(int i=.....) щеше да е валидна и след цикъла

Според стандарта на C++ който имам (ISO/IEC 14882, first edition), това не е вярно (раздел 6.5.3 The for statement). Грубо казано декларацията е валидна в тялото на цикъла, плюс изразите във for оператора.

Отговор
в отговор на ceci_ #14

Re: Dwa wyprosa za C :)

Твоите въпроси за С или за С++ са?

Отговор
в отговор на hhh #15

Re: Dwa wyprosa za C :)

За ANSI не знам, ама в CppBook на Bjarne Stroustrup наистина пишеше, че ако имаш:

for (int i=0; i<Chislo; i++)
{
...
}

то i ще има зона на действие само тялото на цикъла, а след това няма да е дефинирано... загадка.

Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Отговор
в отговор на zaphod #17

Re: Dwa wyprosa za C :)

Баси, живял съм в заблуда.

Досега аз пък си мислех, че

for (...;...;...)
{
int i=Value;
}

ще изпълни присвояването на стойност сам първия път.

Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Отговор
в отговор на Duncan Griffin #18

Re: Dwa wyprosa za C :)

ne e zagadka.
MS VC 6 ne spazva standarta i 'i'-to prodyljava da e validno sled for-a.

MS VC 7 i Borland C++ imat opciq specialno za tova dali da e spored standarta ili da e spored VC6....

Отговор
в отговор на ceci_ #19

Re: Dwa wyprosa za C :)

emi za C nqmash problem.

i-to vaji v bloka v kojto e deklarirano.

for (int i =...) ne e legalno C.

dali for (;;) ili while(1) - vypros na vkus.

imashe edni coding guidelines, v koito ne se preporychvashe

#define FOREVER for(;;)

ama inache e bez znachenie

Отговор
в отговор на ceci_ #20

Re: Dwa wyprosa za C :)

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

1. for(;;) {}
2. while (true) {}
3. do {} while (true);

се генерира еднакъв код. Аз лично предпочитам втория вариант. Третият е прекалено екстравагантен, и можа да се ползва ако искаш да тормозиш тоя който ще ти чете л.....а. Особено ако тялото на цикъла е по-дългичко.

Първият вариант обаче се препоръчва от писачите на книги, понеже било асоциативно:

for (;;) // == "forever"
{
}

На мен обаче хич не ми звучи така, и затова си карам как си знам...

Tip of the night: Ако искаш да създадеш истинско главоболие на тоя след теб, можеш да направиш цикъла и така:

label1:
...
if (condition) goto label2;
...
goto label1;
label2:

Не съм сигурен, че така машинния код пак ще е същия, но пък е по-весело.

Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Отговор