почему моя программа не компилируется
Я получаю сообщение об ошибке: Функция roll не может быть решена. Я не уверен, что это из-за объема, и если это так, как я могу это исправить?
#include #include using namespace std; int main() < roll(); >int playerSum = 0; int dice [5]; void roll() < for(int i =0;i<6;i++)< int randNum = rand()%600 + 1; dice[i]= randNum; cout<>
Решение
Попробуйте поставить ролл выше основного, прежде чем его назвать.
Кроме того, вы можете объявить void roll (); выше основного и определите его позже.
Другие решения
Компилятор не видел определения функции roll () до того, как увидел ссылку на нее в main (). Переместите главное объявление в конец файла.
1) Разместить предварительную декларацию void roll() прототип перед main сообщить комплиеру о roll.
2) int dice [5] это маленький, чтобы сохранить 6 элементов — это вызовет неопределенное поведение.
3) Нет необходимости использовать глобальный массив dice ,
Этапы компиляции на Си: предобработка, трансляция, компоновка
4) Вы можете захотеть seed генератор случайных чисел, в противном случае вы получаете одни и те же числа при каждом запуске программы.
#include #include using namespace std; void roll(); int main() < roll(); return 0; >void roll() < int dice[6]; int randNum; for(int i =0; i>
584 287 178 116 594 536
Я изначально предполагал, что этот вопрос будет дубликатом. К моему удивлению, я не смог найти дубликат с тегами C ++ в поиске StackOverflow. Поэтому я выкладываю ответ вместо.
Как минимум, компилятор C ++ должен видеть объявление функции в том же модуле компиляции ДО того, как он будет вызван первым.
Это означает, что до вызова roll() в main() , должна быть декларация roll() , Например;
void roll(); // declaration of roll() int main() < roll(); >void roll() // definition of roll() < // your code >
Этот подход (объявление, которое не является определением, помещается перед кодом, вызывающим функцию), имеет то преимущество, что определение roll() при желании может быть перемещен в другой модуль компиляции (также называемый исходным файлом) (при условии, конечно, что процесс сборки правильно компилирует все исходные файлы и при необходимости связывает объектные файлы).
Определение формально является типом объявления, поэтому альтернативой является перемещение main() в конец исходного файла.
void roll(); // declaration of roll() void roll() // definition of roll() < // your code >int main()
Технически, декларация roll() в этом случае может быть удалено, так как определение является типом объявления. Одним из недостатков этого является то, что, если кто-то впоследствии решит перенести определение roll() где-то еще (например, в другой исходный файл), тогда ВСЕ ЕЩЕ необходимо повторно ввести объявление roll() до main() ,
Источник: web-answers.ru
Как работает язык программирования(Компилятор)? Основы программирования.
Почему не компилируется любой C/C++ код в Visual Studio?
Пару дней назад установил Visual Studio 2022 на Windows 10 (все обновления). Сегодня создал первый проект, попытался запустить (скомпилировать), но получил десятки ошибок о том, что не удаётся открыть источник файл «имя_файла.h» (E1696) + другие ошибки. Всего ошибок почти 500.
Список ошибок при попытке компиляции консольного проекта C++: тык.
C# компилируется, не компилируется видимо только C++.
Я открыл проводник в том месте (C:Program FilesMicrosoft Visual Studio2022CommunityVCToolsMSVC14.33.31629include), где оно не может открыть эти «источник файл», и установил, что примерно треть всех файлов не имеют расширения (остальные файлы имеют расширение .h/.hpp).
- Вопрос задан 28 сент.
- 244 просмотра
7 комментариев
Простой 7 комментариев
Источник: qna.habr.com
Не компилируется программа на си
typedef void (*mdl)(double t, double* py, double* py1);
void init_rk(int N);
void done_rk();
void rkt4(double t, double dt, double* py, mdl model, int N_s);
void mod_obs(double t, double* py, double* py1);
double dto;
double Yout, eps;
rkt4(*tc,(*dt),Yobs,mod_obs,3);
Yout = Yobs[0]*c0+Yobs[1]*c1+Yobs[2]*c2;
eps=*Yt-Yout;
//для проверки наблюдателя в асинхронном режиме
fprintf(fx,»%f %f %f %f %f %f %fn»,*tc,Yst[0],Yobs[0],Yst[1],Yobs[1],Yst[2],Yobs[2]);
fprintf(fy,»%f %f %f n»,*tc,*Yt,Yout);
Yst[0]=Yobs[0];// Это работа наблюдателя
Yst[1]=Yobs[1];// Для отключения наблюдателя
Yst[2]=Yobs[2];// закомментировать
void term(int s) fclose(fx);
fclose(fy);
done_rk();
fprintf(stderr,»наблюдатель — завершение работыn»);
exit(0);
>
int main(int argc, char **argv)
fprintf(stderr,»Наблюдатель — запускn»);
signal(SIGTERM,term);
dsem=semget(SEM, 5, IPC_CREAT | S_IRUSR | S_IWUSR);
set_shmem(dmem,pmem);
//sm1=sem_open(«/sem1», O_RDWR | O_CREAT, 0660, 0);
//sm2=sem_open(«/sem2», O_RDWR | O_CREAT, 0660, 0);
mq1=mq_open(«/mq1», O_RDWR, 0660, 0);
mq2=mq_open(«/mq2», O_RDWR, 0660, 0);
*pobs=getpid();
smb.sem_num=0;
smb.sem_flg=0;
smb.sem_op=-1;
Yout = Yobs[0]*c0+Yobs[1]*c1+Yobs[2]*c2;
eps=*Yt-Yout;
fx=fopen(«state_var.dat»,»w»);//для проверки работы наблюдателя
fy=fopen(«observer.dat»,»w»); //в асинхрноом режиме
semop(dsem, //даем знать диспетчеру о готовности к работе
while(1) //sem_wait(sm1);//ждем освобождения семафора
mq_receive(mq1,(char*)prio);
observer(); //наблюдаем объект
//sem_post(sm2);//сообщаем о завершении работы
mq_send(mq2, (char*)
>
double* k[4], *py1, *pdy;
void mod_obs(double t, double* py, double* py1) double V=*Uo;
py1[0]=py[1]+K[0]*eps;
py1[1]=py[2]+K[1]*eps;
py1[2]=V-py[0]*z0-py[1]*z1-py[2]*z2+K[2]*eps;
>
void init_rk(int N) int i;
for (i=0; i k=(double*)calloc(N, sizeof(double));
py1=(double*)calloc(N, sizeof(double));
pdy=(double*)calloc(N, sizeof(double));
>
void done_rk() int i;
for (i=0; i delete[] k;
delete[] py1;
delete[] pdy;
>
При попытке скомпилировать программу, выводится следующее сообщение
/home/alexey/2011rt/obs.o||In function `main’:|
obs.cc.text+0x325)||undefined reference to `mq_open’|
obs.cc.text+0x34e)||undefined reference to `mq_open’|
obs.cc.text+0x465)||undefined reference to `mq_receive’|
obs.cc.text+0x490)||undefined reference to `mq_send’|
||=== Build finished: 4 errors, 0 warnings ===|
Помогите исправить, заранее благодарен
Источник: codeby.net
Почему программа C не компилируется без ошибок?
У меня нет ошибок. Почему это? Должны ли быть, по крайней мере, ошибки связи? Обратите внимание, что я просто говорю о компиляции файлов — не запуская их. Запуск дает ошибку сегментации.
спросил(а) 2020-03-19T18:01:15+03:00 2 года, 9 месяцев назад
добавить комментарий
пожаловаться
Должна ли быть ошибка компоновщика?
Краткий ответ на вопрос «Не должно быть, по крайней мере, связывать ошибки?» «Существует никаких гарантий, что будет ошибка связи». Стандарт C не предусматривает этого.
Как Раймонд Чен отметил в comment:
Ответ на языковой барьер заключается в том, что стандарт не требует диагностики для этой ошибки. Практический ответ заключается в том, что C не набирает шрифты с внешней связью, поэтому несоответствие типов не обнаружено.
Одна из причин, по которой С++ имеет тип-безопасную связь, заключается в том, чтобы избежать проблем с кодом, аналогичным этому (хотя основная причина заключается в том, чтобы разрешить перегрузку имен функций — разрешение такой проблемы, возможно, является более побочным эффектом).
В стандарте C говорится:
§6.9 Внешние определения ¶5 Внешнее определение — это внешнее объявление, которое также является определением функции (кроме встроенного определения) или объекта. Если идентификатор, объявленный с внешним linkage используется в выражении (кроме как в части операнда sizeof или _Alignof , результат которого является целочисленной константой), где-то во всем программы должно быть точно одно внешнее определение для идентификатора; в противном случае должно быть не более одного.
§5.1.1.1 Структура программы ¶1 Программа C не обязательно должна быть переведена одновременно. Текст программы хранится в единицах, называемых исходными файлами (или файлы предварительной обработки) в этом Международном стандарте.
Исходный файл вместе со всеми заголовками и исходными файлами, включенными в директиву предварительной обработки #include , известен как блок перевода предварительной обработки. После предварительной обработки блок перевода с предварительной обработкой называется единицей трансляции. Ранее переведенные единицы перевода могут сохраняться индивидуально или в библиотеках.
Отдельные единицы перевода программы связывают (например) вызовы функций, чьи идентификаторы имеют внешнюю связь, манипулирование объектами, чьи идентификаторы имеют внешнюю связь, или манипулирование файлами данных. Единицы перевода могут быть переведены отдельно, а затем связаны с созданием исполняемой программы. 5.1.1.2 Фазы перевода Все ссылки на внешние объекты и функции разрешены. Компоненты библиотеки связаны для удовлетворения внешних ссылок на функции и объекты, не определенные в текущем переводе. Все такие выходные данные переводчика собираются в образ программы, который содержит информацию, необходимую для выполнения в среде выполнения.
Связывание выполняется на основе имен внешних определений, а не типов объектов, идентифицируемых именем. Бремя зависит от программиста, чтобы гарантировать, что тип функции или объекта для каждого внешнего определения согласуется с тем, как он используется.
Избежать проблемы
В comment я сказал:
Этот [вопрос] является аргументом в пользу использования заголовков для обеспечения согласованности различных частей программы. Если вы никогда не объявляете внешнюю функцию в исходном файле, а только в заголовках, и используете заголовки везде, где используется или определен соответствующий символ (в данном случае weird ), код не будет компилироваться. Вы можете либо иметь функцию, либо строку, но не обе. У вас будет заголовок weird.h , который содержит либо extern char *weird; , либо extern int weird(int *p); (но не оба), и оба main.c и weird.c будут включать заголовок, и только один из них будет скомпилирован успешно.
Для чего пришел ответ:
Что я могу добавить к этим файлам, чтобы убедиться, что ошибка обнаружена и выбрана при компиляции main.c ?
Вы создали бы 3 исходных файла. Показанный здесь код немного сложнее, чем вы обычно использовали, поскольку он позволяет использовать условную компиляцию для компиляции кода либо с помощью функции, либо с помощью переменной «внешний идентификатор с внешней связью», называемой weird . Как правило, вы выбираете одно преднамеренное представление для weird и только разрешаете его открывать.
weird.h
#ifndef WEIRD_H_INCLUDED
#define WEIRD_H_INCLUDED
#ifdef USE_WEIRD_STRING
extern const char *weird;
#else
extern int weird(int *p);
#endif
#endif /* WEIRD_H_INCLUDED */
main.c
#include
#include «weird.h»
int main(void)
int x, *y;
y = (int *)7;
x = weird(y);
printf(«x = %dn», x);
return (0);
>
weird.c
#include «weird.h»
#ifdef USE_WEIRD_STRING
const char *weird = «weird»;
#else
int weird(int *p)
if (p == 0)
return 42;
else
return 99;
>
#endif
Допустимые последовательности компиляции
gcc -c weird.c
gcc -c main.c
gcc -o program weird.o main.o
gcc -o program -DUSE_WEIRD_FUNCTION main.c weird.c
Неверная последовательность компиляции
gcc -c -DUSE_WEIRD_STRING weird.c
gcc -c main.c
gcc -o program weird.o main.o
-
Либо компиляция завершилась неудачно, если файл содержал функцию, а -DUSE_WEIRD_STRING был установлен в командной строке,
Или компиляция завершится неудачно, если файл содержит строку, но вы не установили -DUSE_WEIRD_STRING .
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes
-Wold-style-definition -Wold-style-declaration …
-Wall и -Wextra подразумевают некоторые, но не все, другие параметры -W… , поэтому это не минимальный набор. И не все версии GCC поддерживают параметры -Wold-style-… . Но вместе эти параметры гарантируют, что функции будут иметь полное объявление прототипа перед использованием функции.
Источник: progi.pro