Zaloguj się, aby obserwować  
Bartuc

Język C / C++ / C# / Java - pytania, problemy...

1979 postów w tym temacie

Czy jest możliwe np. implementacja funkcji w utoworzoym przez siebie pliku z rozszeżeniem cpp ??
Bo jeśli w takim pliku napisze przykadową konstrukcje:

void nazwa();

To kompilator mi to przepuści, ale jeśli napisze

void nazwa() {
//kod funkjci
}

to wyskoczy mi błąd
multiple definition of `nazwa()''
first defined here
ld returned 1 exit status
Scieżka projektu [Build Error] [nazwa projektu.exe] Error 1

Bład wyskakuje nawet jesli program zawiera tylko ten kod i inny niezbędny do działania (pliki nagłowkowe i funkcje main), czyli na pewno jest to pierwsza implementacja tej funkcji. Błąd ten nie żalezy od kodu we wnetrzu funkcji (może być nawet pusta). Wyskakuje on we wnaetrzu pliku z rozszeżeniem cpp (oprócz pliku main.cpp), a np z rozszeżeniem h juz nie. Taki sam bład wyskuje też np z próbą stworzenia zmiennej wcześniej zadeklarowanego typu wyliczeniowego.

Używam komppilatora Dev-C++ 4.9.9.2 (nie wiem czy nie jest to wersja beta; być może tutaj leży źródło problemów)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 01.08.2007 o 15:00, dwiedzmin napisał:

Czy jest możliwe np. implementacja funkcji w utoworzoym przez siebie pliku z rozszeżeniem cpp
??

Tak, ale powinieneś to robić w ten sposób.

"mojafunkcja.h"
#ifndef MOJAFUNKCJA_H
#define MOJAFUNKCJA_H
void nazwa();
#endif

"mojafunkcja.cpp"
#include "mojafunkcja.h"
void nazwa(){
//kod funkcji
}

I tyle... do maina includujesz mojafunkcja.h i powinno ładnie działać.
#ifndef itd. to tzw. dozory łączenia, zapobiegają włączeniu tego pliku kilkakrotnie do programu. Bo inaczej plik h włączasz zarówno do pliku cpp z funkcją, jak i do maina.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 01.08.2007 o 19:17, dwiedzmin napisał:

Dzięki, działa. A jest coś takiego do zwykłych zmiennych (nie tych z typu wyliczeniowego)?
Bo mi raz dzialają, a raz wyskakuje ten błąd.

Może jestem trochę zmęczony, ale nie bardzo rozumiem. Mógłbyś podać przykład?

Co do samej zasady - pamiętaj, że #include oznacza po prostu wklejenie zawartości pliku - dlatego jak wkleisz kilka razy ten sam plik nagłówkowy to możesz mieć parę razy tę samą zmienną. ifndef, define po prostu definiują makro przy pierwszym wklejeniu, a jeśli jest już zdefiniowane, to nie robią nic.

Jeśli jeszcze nie próbowałeś, to spróbuj to zrobić tak samo jak z funkcjami (bo ten sposób nie służy konkretnie do funkcji, to po prostu zapobiega wielokrotnemu użyciu jednego pliku).

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 01.08.2007 o 20:17, Vel Grozny napisał:

Może jestem trochę zmęczony, ale nie bardzo rozumiem. Mógłbyś podać przykład?


Np.: pisze w pliku *.h

#ifndef MOJAFUNKCJA_H
#define MOJAFUNKCJA_H
void nazwa();
int zmienna1;
#endif

w pliku *.cpp
#include "*.h"
void nazwa(){
std::cin >> zmienna1;
std:: cout << zmienna1;
//kod funkcji
}

Nidgy nie mogę zapamietąć, w ktorą strone maja byc te sztrzałki, ale to i tutaj tak nue wązne. Jak mam w złą to kompilator pokażemi mi odpowiedni błąd i poprawie.

w pliku main.cpp
//odpowiednie pliki nagłówkowe
#include "*h"

void main(){
nazwa();
}

I kompilator mi to przepuści, albo i nie (nie wiem dlaczego sie tak dzieje). Ale np jak dopisze to system("PAUSE"); to moze juz zadziałać (albo tez i nie). Rożne kombinacje próbowałem. Przeklejałem komedne int zmienna1 poniżej dyrektywy #endifm, przeklejałem też do pliku *.cpp, próbowałem z kilkoma zmiennymi, próbwałem z tym system("PAUSE"); i bez niego. Raz dzaialało raz nie. Najlepsze, że w takiej samej postaci raz to kompilator przepuszaczał raz nie (ale tylko za pierwszym razem; to znaczy, że jak za pierwszym razem nie przepuscił, to juz do wykonaia jakieś modyfikacji kodu (też nie każdej) nie przepuścił ). Może to wina kompilatora??

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 01.08.2007 o 20:34, dwiedzmin napisał:

Może to wina kompilatora??

Hmmm... sam nie wiem. Wydaje się wszystko ok. Jeżeli się dzieją takie cuda przy kompilacji, to może i wina kompilatora (nie przejmuj się, że to beta - od paru lat nie wyszła nowsza wersja). Może ktoś inny zauważy błąd, albo sam go zauważysz, jak trochę odpoczniesz :)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

W C++ nie można definiować zmiennych w plikach nagłówkowych, gdyż w język tym żadna definicja nie może się powtórzyć więcej niż raz. Jeśli w pliku *.h umieścisz definicję zmiennej to w każdym pliku *.cpp będzie ona definiowana od nowa i linker zgłosi błąd.

Musisz zadeklarować tę zmienną w pliku nagłówkowym, a zdefiniować z pliku *.cpp. Wystarczy, że w nagłówku napiszesz extern int zmienna1 , a w pliku z implementacją int zmienna1.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 01.08.2007 o 20:41, rafikn napisał:

W C++ nie można definiować zmiennych w plikach nagłówkowych, gdyż w język tym żadna definicja
nie może się powtórzyć więcej niż raz. Jeśli w pliku *.h umieścisz definicję zmiennej to w
każdym pliku *.cpp będzie ona definiowana od nowa i linker zgłosi błąd.


No, ale tak zrobiłem. Deklaracja jest w pliku *.h, a jej użycie w pliku *.cpp. A jeśli ja przekleiłem do *.cpp to zrobiłem to przez wytnij wklei, także deklaracja występuje tutaj tylko raz.

Dnia 01.08.2007 o 20:41, rafikn napisał:

Musisz zadeklarować tę zmienną w pliku nagłówkowym, a zdefiniować z pliku *.cpp. Wystarczy,
że w nagłówku napiszesz extern int zmienna1 , a w pliku z implementacją int zmienna1.


Też próbowałem, dzieje sie tak samo. Za pierwszym razem skąpilowało noramalnie. Potem spróbowałem usunąć extern i deklaracje zmiennej z pliku *.cpp to wsykoczyło, że nie jakis błąd, dałem sytem("PAUSE"); jako komentarz to juz działalo dobrze, spróbowałem wtedy jeszcze raz z extern, taka samo jak za pierwszą próba i wyskoczył bład.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Dnia 01.08.2007 o 20:56, dwiedzmin napisał:

No, ale tak zrobiłem. Deklaracja jest w pliku *.h, a jej użycie w pliku *.cpp. A jeśli ja przekleiłem
do *.cpp to zrobiłem to przez wytnij wklei, także deklaracja występuje tutaj tylko raz.


Instrukcja int zmienna1 jest definicją tej zmiennej. Sama deklaracja to instrukcja extern int zmienna1.

Dnia 01.08.2007 o 20:56, dwiedzmin napisał:

Też próbowałem, dzieje sie tak samo. Za pierwszym razem skąpilowało noramalnie. Potem spróbowałem
usunąć extern i deklaracje zmiennej z pliku *.cpp to wsykoczyło, że nie jakis błąd, dałem sytem("PAUSE");
jako komentarz to juz działalo dobrze, spróbowałem wtedy jeszcze raz z extern, taka samo jak
za pierwszą próba i wyskoczył bład.


Miałem na myśli taki układ plików :

plik *.h:

#ifndef MOJAFUNKCJA_H
#define MOJAFUNKCJA_H

void nazwa();
extern int zmienna1;

#endif

-------------------------

plik *.cpp:

#include "*.h"
int zmienna1;

void nazwa(){
std::cin >> zmienna1;
std:: cout << zmienna1;
//kod funkcji
}

Radzę przeczytać jakąś dobrą książkę o C++ (polecam Symfonię C++ Standard lub Mexatutorial Xion''a ze strony http://www.gamedev.pl/tutorials.php .

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 01.08.2007 o 21:02, rafikn napisał:

Instrukcja int zmienna1 jest definicją tej zmiennej. Sama deklaracja to instrukcja extern
int zmienna1
.


No chyba, że tak.

Dnia 01.08.2007 o 21:02, rafikn napisał:

Miałem na myśli taki układ plików :

plik *.h:

#ifndef MOJAFUNKCJA_H
#define MOJAFUNKCJA_H

void nazwa();
extern int zmienna1;

#endif

-------------------------

plik *.cpp:

#include "*.h"
int zmienna1;

void nazwa(){
std::cin >> zmienna1;
std:: cout << zmienna1;
//kod funkcji
}


Właśnie taki układ zrobiłem. Na pocżtku działał, potem pozmieniałem, a na końcu wróciłęm do takiego ukladu i już nie działał.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

A jaki konkretnie błąd wypisuje ? Może kompilator nie zna nazw std::cin i std::cout , bo jeśli tak to dodaj linijkę #include <iostream> w pliku cpp.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 01.08.2007 o 21:32, rafikn napisał:

A jaki konkretnie błąd wypisuje ? Może kompilator nie zna nazw std::cin i std::cout , bo jeśli
tak to dodaj linijkę #include <iostream> w pliku cpp.


Blad wystepuje taki jak napisałemm pare postów wyżej:

multiple definition of `zmienna1()''
first defined here
ld returned 1 exit status
Scieżka projektu [Build Error] [nazwa projektu.exe] Error 1

Najlepsze, ze nie odnosi wskazuje żadnej konkretnej lini kodu.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Ja ma problem z takim zadaniem ze Spoja (C++). Nie wiem, czy je dobrze zrozumiałem. Chodzi o to, aby program zakończył się po podaniu liczby 42, czy co? Kilka razy zgłaszałem rozwiązanie, ale za każdym razem wyświetlało mi błąd kompilacji. Jak to trzeba napisać?

Zadanie w systemie SPOJ
1. Life, the Universe, and Everything
Kod zadania: TEST
Your program is to use the brute-force approach in order to find the Answer to Life, the Universe, and Everything. More precisely... rewrite small numbers from input to output. Stop processing input after reading in the number 42. All numbers at input are integers of one or two digits.

[i]Example
Input:
1
2
88
42
99
Output:
1
2
88

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

[...]

Masz jakiś plik wejściowy i w nim podane liczby (każda w 1 linijce), czytasz tą liczbę i jeśli jest różna od 42 to dopisujesz ją do pliku wyjściowego jeśli jest równa 42 to kończysz program.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 20.09.2007 o 20:32, jaki of blade napisał:

Hej, mógłby ktoś polecić jakąć książke o programowaniu c++, tylko dla całkowitego nooba?


"Symfonia C++" Jerzego Grębosza jak dla mnie to czyta się to prawie jak książkę przygodową (czyli jest ciekawie i występuje syndrom jeszcze jednego rozdziału), a potem możesz spróbować "Pasja C++" tegoż samego autora.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Dnia 20.09.2007 o 20:45, jaki of blade napisał:

Dzięki, od jutra zaczynam kurs "Od zera do gier kodera", ciekawe co z tego wyjdzie

Powodzenia! Warto chociaż na początku może być trochę ciężko, ale nie poddawaj się!

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Dnia 20.09.2007 o 20:52, pretorianie napisał:


> Dzięki, od jutra zaczynam kurs "Od zera do gier kodera", ciekawe co z tego wyjdzie
Powodzenia! Warto chociaż na początku może być trochę ciężko, ale nie poddawaj się!

Nie poddam się, moim celem jest dostać się do ubisoftu, długa drog przede mną, ale jestem uparty. Ja to mówią "Damy rade" :)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Utwórz konto lub zaloguj się, aby skomentować

Musisz być użytkownikiem, aby dodać komentarz

Utwórz konto

Zarejestruj nowe konto na forum. To jest łatwe!


Zarejestruj nowe konto

Zaloguj się

Masz już konto? Zaloguj się.


Zaloguj się
Zaloguj się, aby obserwować