Тонкости C/C++

Тема в разделе "LANGS.C", создана пользователем Nafanya, 5 фев 2011.

  1. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Момент 1
    int func(); Си++ воспринимает это как функцию не принимающую аргументов, а для С это функция с произвольным количеством и типами аргументов. Собственно если для Си количество аргументов произвольное, то примет ли это Си компилятор:

    Код (Text):
    1. int func();//объявление - функция с произвольным количеством аргументов
    2. ........................
    3. int func (int i, int j)//определение , задал имена аргументов
    4. {return(i+j);}
    Нет си компилятора под рукой, только С++ компилятор. Естественно, что для С++ это ошибка. Если это неправильно и для СИ, то как тогда понимать функция с произвольным количеством и типами аргументов? Как обращаться к этим аргументам без имени? Приведите пожалуйста примерчик.

    Если написать:
    Код (Text):
    1. int func (int i, int j);
    2. ..............................
    3. int func (int i, int j)
    4. {return(i+j);}
    То это конечно правильно и проще намного, только вот на собеседованиях задают каверзные вопросы по синтаксису.
     
  2. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    естественно... так как в с++ это две разные функции, для линкера их "украшенные" имена различны... это называется полиморфизм функций... в си недоступен полиморфизм, так как имена не украшаются... по поводу ошибки в си - лень смотреть, но скорее всего будет ошибка, так как функция с двумя аргументами и функция с произвольным числом аргументов - две разные вещи... когда вы объявляете функцию без тела - вы просто объявляете имя (символ), чтобы оно было видно тому коду, что находится под объявлением...

    o_O
     
  3. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
  4. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Ясно. Ща из командной строки попробую скомпилить...
     
  5. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    даааа... из командной строки... если ты не можешь в настройки проекта зайти и найти там "Compile as C code"...
     
  6. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Действительно оказалось правдой. cl без ошибок компилирует СИ-код:
    Код (Text):
    1. #include <stdio.h>
    2. int func ();
    3.  
    4. int main(void)
    5. {
    6. int a=2,b=3;
    7. printf("%d",func(a,b));
    8. scanf("%d",&a);
    9. return 0;
    10. }
    11.  
    12. int func (int i,int j)
    13. {i=i+j;return(i);}
    Следовательно Си-компилятор воспринимает объявление int func(); как объявление функции с произвольным количеством и типами аргументов. Это ж какой опыт надо иметь, чтоб такое знать...
     
  7. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    И этот человек заявляет

     
  8. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    _DEN_
    И что из этого. Разработал же систему кластеризации на плюсах, тему топика прочитай - тонкости C/C++. Ты просто похоже не понимаешь о чем речь, а речь о том что компилятор СИ и компилятор Си++ по разному воспримут строку int func();.
     
  9. GRRRLPower

    GRRRLPower New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    46
    _DEN_, +1 :)

    Nafanya, насчет СИ, Вы, может быть, и правы. Функция имеет cdecl-конвенцию по умолчанию, стек за собой не чистит сама, а чистит за ней вызывающая программа, вот у Вас всё и работает. Если написать код так:
    Код (Text):
    1. #include <stdio.h>
    2. int func (){return 1;}
    3.  
    4. int main(void)
    5. {
    6. int a=2,b=3;
    7. printf("%d",func(a,b));
    8. return 0;
    9. }
    то компилироваться и работать будет, но если так:
    Код (Text):
    1. #include <stdio.h>
    2. int _stdcall func (){return 1;} //STDCALL теперь
    3.  
    4. int main(void)
    5. {
    6. int a=2,b=3;
    7. printf("%d",func(a,b));
    8. return 0;
    9. }
    то уже нет.

    А теперь насчет C++... Вы когда-нибудь слышали о такой вещи, как "перегрузка функций"?

    Вы в своей теме про "ищу легальную работу" выложили пример своего кода (правда, убрали потом, но я себе сохранил), где есть функция с переменным числом аргументов. Это, получается, не Ваш код был, если сейчас такие вопросы задаете?
    Вот он:
    Код (Text):
    1. Aggregator::Aggregator(int number,Generator * pgen,...)
    2. {
    3.  NOSP=number;
    4.  Generator ** p;
    5.  p=&pgen;
    6.  pGeneratorsList=new list <Generator *>;
    7.  pSamplesVector=new vector <Sample>;
    8.  while(*p!=0)
    9.     {
    10.     pGeneratorsList->push_back(*p);
    11.     p++;
    12.     }
    13.  return;
    14. }
     
  10. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Nafanya

    Ну и какие же это тонкости. Я изучаю C/C++ уже три месяца, и с этими вопросам разобрался в первую же неделю. Так что я понимаю о чем речь.
     
  11. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    GRRRLPower
    Код весь мой был. Но заметьте в том коде у функции с переменным числом аргументов Aggregator::Aggregator(int number,Generator * pgen,...) есть именной аргумент pgen, указатель на объект-генератор. Затем я брал адрес этого указателя (p - указатель на указатель) и когда производил инкремент p, то он двигался по списку аргументов функции.

    Меня сначала удивило, что в функции с переменным числом аргументов int func(); нет именного аргумента, соответственно как двигаться по списку аргументов не ясно!!! (Как вы предложите двигаться?) Потом я подумал, что это скорее всего объявление функции, которое не совпадет с определением... Что Вы думаете по этому поводу?
     
  12. GRRRLPower

    GRRRLPower New Member

    Публикаций:
    0
    Регистрация:
    17 авг 2010
    Сообщения:
    46
    У функции с переменным числом аргументов всегда есть именной аргумент, хотя бы один, который позволяет определить, сколько еще аргументов передано функции. А теперь еще прочитайте пару моих примеров кода и изучите, что такое конвенция вызовов.
     
  13. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    _DEN_
    Прям два языка параллельно учишь:) И в первую неделю изучения разбираешь функции с переменным числом аргументов:)
    Сынок, тебе предстоит долгий и нелегкий путь, не мешай взрослым дядям разговаривать о Си++:)
     
  14. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Nafanya

    Ну а что, разница-то небольшая. Си с классами просто. Я между прочим перед каникулами занял второе место у нас в школе на олимпиаде по программированию.
     
  15. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Nafanya
    Для этого нужно изучить язык Си - портируемый ассемблер. Могу открыть ещё одну страшную тайну и на типы агрументов Си тоже наплевать.
     
  16. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    Еще раз. Язык СИ. В учебнике написано, что int func(); - функция с переменным числом аргументов (Кто знает почему?). Ведь функция с переменным числом аргументов должна иметь синтаксис void func (char *pointer, ...).
     
  17. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Nafanya

    Ну может там опечатка. А функции с переменным числом аргументов могут быть и без первого параметра. Например void func (...);
     
  18. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    _DEN_
    Как ты к этим аргументам обратишься в теле функции, если нет именного параметра? Наверное автор учебника был немного в угаре...
     
  19. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Nafanya

    Ну можно взять указатель на параметры из регистра EBP.
     
  20. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    смотрите реализацию va_list'ов... параметры лежат на стеке...

    именно... можно вообще говоря и без ассемблера обойтись.. intrin.h

    вроде переменное число параметров в принципе возможно только при cdecl... или нет? в смысле функция же не знает, насколько ей стек очищать, то есть при использовании функции с переменным числом аргументом стек должен чистить ее вызывающий...