zwracanie przez funkcję kilku wartości

zwracanie przez funkcję kilku wartości
F9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

cześć.
co prawda moją przygodę z C++ zacząłem kilka lat temu, ale robiłem mało i teraz mam zamiar wziąć się za to porządnie. jednym z problemów, jakie napotkałem, jest właśnie zwracanie przez funkcję kilku wartości. niby przewija się to w tematach, jakie znalazłem, ale nigdzie nie jest jasno opisane co i dalczego. domyślam się, że należy skorzystać z wskaźników. jednak tutaj moje pomysły się kończą. prosiłbym o możliwie szczegółową pomoc.

pozdrawiam serdecznie,
Filip.

NZ
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 8 lat
  • Postów:93
0

Jakie zwracanie wielu wartości?

Można to zrobić na pierdyliard różnych sposobów, ale w praktyce się po prostu definiuje strukturę na te wartości.

Kopiuj
struct StringWithLength
{
	const char* str;
	const size_t len;
};

StringWithLength getStringWithLength(const char* str)
{
	return {str, strlen(str)};
}

tuple<const char*, size_t> getStringWithLengthT(const char* str)
{
	return make_tuple(str, strlen(str));
}

void getStringWithLengthP(const char* str, const char** outputstr, size_t* len)
{
	*outputstr = str;
	*len = strlen(str);
}

void getStringWithLengthR(const char* str, const char*& outputstr, size_t& len)
{
	outputstr = str;
	len = strlen(str);
}
fasadin
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
  • Postów:4882
0

nikt w pracy nie zwraca kilku wartosciach poprzez wskazniki. Robi sie to poprzez klase/strukture. na zasadzie

Kopiuj
class Foo {
public:
  int x;
  int y;
}; 

Foo* func(){
  Foo *foo = new Foo();
  foo->x = 5;
  foo->y = 10;
  return foo;
}

int main(){
  Foo *anotherFoo = func();
  cout << anotherFoo->x << " " << anotherFoo->y;
  delete anotherFoo;
}

pisane z palca wiec moze nie dzialac. Chodzi o sama idee (kod nie jest najwyzszej jakosci, ale jest prosty do zrozumienia)

edytowany 2x, ostatnio: fasadin
Zobacz pozostałe 14 komentarzy
NZ
GCC 4.4 też to kompiluje -> https://goo.gl/Lgj0V5 Nie cofnę się w czasie, ani nie zaciągne wszystkich wersji gcc. Po prostu ten ficzer wszedł wcześniej. To nie jest tak, że nagle w 2011 kompilatory dostały wszystko...
gośćabc
dostały std::initializer_list i o to chodzi
NZ
Żeby było weselej, w C to się nawet kompiluje z -std=c89.
Azarien
bez C++11: Foo func() { Foo foo = {5,10}; return foo; }
satirev
@nz ten kod nie jest poprawny względem c++98/03 i starszych, bo initializer list (dla nie-agregatów) weszły dopiero w C++0x. Dowód: https://goo.gl/ZY6ISu Initializer list to co innego niż std::initializer_list - w tym miejscu odsyłam do standardu: 8.5.4 z szczególnym uwzględnieniem 8.5.4[2] oraz tego drafta: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1890.pdf (na 5 stronie macie nawet podobny przykład do tego z waszego kodu).
Zellus
  • Rejestracja:prawie 13 lat
  • Ostatnio:około 4 lata
  • Lokalizacja:Wrocław
  • Postów:474
0

Jeżeli zwracasz kilka wartości tego samego typu, wtedy zwracasz tablicę

Kopiuj
std::vector<int> foo(){
    return {1,2,3}
}

Jeżeli są różnego typu to strukturę

Kopiuj
struct abc{
    int id;
    std::string value;
};

abc foo() {
    return {1, "Hello World"};
}

To tak generalnie, ciężko powiedzieć coś więcej nie znając dokładnego przypadku.

Edit.
Czemu ja zawsze tak wolno piszę posty :/

edytowany 1x, ostatnio: Zellus
F9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

dzięki za pomoc. może podam przykład. wczytuję w funkcji dane z pliku do tablicy dynamicznej i określam ich liczbę, po czym chciałbym przekazać te dane (tzn. wartości kolejnych elementów tablicy i ich liczbę) do funkcji, która je jakoś zmodyfikuje, nie wiem, obliczy średnią wartość. problem w tym, że nie wiem, jak przekazać te wartości.

Kopiuj
 
int *wczytanie()
{
	int tmp1 = 0;
	int *tab1 = new int[tmp1];


	ifstream plik1;
	plik1.open("liczby1.txt");
	while(!plik1.eof())
	{
		plik1 >> tab1[tmp1++];
	}
		
		plik1.close();
	
	
	return(tab1);
}

proszę, nie gańcie, jeśli kod jest nieprzyzwoity, to ostatnia wersja, nad którą się bawię. niewiele umiem.

pozdrawiam.

Azarien
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 8 godzin
1

Po pierwsze, trzeba pamiętać o zwolnieniu pamięci, a pisząc kod w ten sposób (zwracanie nowozaalokowanej pamięci) łatwo o delete zapomnieć.
Po drugie, alokujesz tablicę zera intów. Zwiększenie zmiennej tmp1 w żaden sposób nie powiększa tablicy.

Po trzecie, w miejscu użycia funkcji wczytanie() nie będziesz miał żadnej informacji, ile intów wczytano z pliku.

F9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

rozumiem.czy w takim razie mógłbyś podpowiedzieć, co i jak mam poprawić?
zmieniłem

Kopiuj
plik1 >> tab1[tmp1++];

na

Kopiuj
		plik1 >> tab1[tmp1];
		tmp1++; 

i zwraca mi wartości tej tablicy.

edytowany 2x, ostatnio: Filippo9669
fasadin
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
  • Postów:4882
0

ze co ;o?

0

sorry, pisałem o jednym, myślałem o drugim. po prostu przy wywołaniu i dodatniu do pętli cout wyświetla mi zawartość tablicy.

fasadin
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
  • Postów:4882
1

no fajnie ale w czym problem? Zanim wyslesz wiadomosc, pokaz komus czy zrozumie o co chodzi od poczatku do konca a nie wyrywkowo wysylasz dwie linijki kodu i mowisz "zwraca tablice" a pozniej "dodalem cout i wyswietla" no super ale ??? w czym problem?

edytowany 1x, ostatnio: fasadin
F9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

w tym problem.

Filippo9669 napisał(a):

dzięki za pomoc. może podam przykład. wczytuję w funkcji dane z pliku do tablicy dynamicznej i określam ich liczbę, po czym chciałbym przekazać te dane (tzn. wartości kolejnych elementów tablicy i ich liczbę) do funkcji, która je jakoś zmodyfikuje, nie wiem, obliczy średnią wartość. problem w tym, że nie wiem, jak przekazać te wartości.

Kopiuj
 
int *wczytanie()
{
	int tmp1 = 0;
	int *tab1 = new int[tmp1];


	ifstream plik1;
	plik1.open("liczby1.txt");
	while(!plik1.eof())
	{
		plik1 >> tab1[tmp1++];
	}
		
		plik1.close();
	
	
	return(tab1);
}

proszę, nie gańcie, jeśli kod jest nieprzyzwoity, to ostatnia wersja, nad którą się bawię. niewiele umiem.

pozdrawiam.

fasadin
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
  • Postów:4882
0

przeciez dostales odpowiedz i nawet napisales ze ROZUMIESZ... jak widac nie do konca

@Azarien

Po drugie, alokujesz tablicę zera intów. Zwiększenie zmiennej tmp1 w żaden sposób nie powiększa tablicy.

Po trzecie, w miejscu użycia funkcji wczytanie() nie będziesz miał żadnej informacji, ile intów wczytano z pliku.

wiec jak nie rozumiesz to nie pisz ze rozumiesz ;o

edytowany 1x, ostatnio: fasadin
F9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

nie rozumiem, dlaczego tablicę zera intów.

fasadin
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
  • Postów:4882
1

robisz dokladnie to. Wiec jaka liczbe ma tmp1?

Kopiuj
int tmp1 = 0;
    int *tab1 = new int[tmp1]; 
F9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

ok, prawda, masz rację, pozbyłem się tego.

F9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

okej, jeszcze raz. mam taki oto kod:

Kopiuj
int *wczytanie1()
{
	int tmp1;
	int *tab1 = new int[tmp1];
	int a;

	ifstream plik1;
	plik1.open("liczby1.txt");
	while(!plik1.eof())
	{
		plik1 >> tab1[tmp1];
		cout << tab1[tmp1] << endl;
		tmp1++;
	}
		
		plik1.close();
		
	a = sizeof(tab1);
	
	delete [] tab1;
	
	return(tab1);
}

	int najwiekszy()
	{
		int najw; /*zmienna do przechowywania najwiekszego elementu*/
		for(int i = 0; i < /*liczba wczytanych elementow w poprzedniej funkcji*/; i++)
		{
		if(/*kolejny element tablicy z poprzedniej funkcji*/ > najw) /*ten element*/ = najw;
		else najw;
                }

                return najw;

	}

funkcja wczytująca dane z pliku do tablicy dynamicznej i przekazująca tę tablicę do drugiej funkcji, która np. będzie wyszukiwać i zwracać jej największy element. trudność, jaką mam, to przekazanie tej tablicy z funkcji wczytanie do funkcji najwiekszy.

twonek
  • Rejestracja:ponad 10 lat
  • Ostatnio:prawie 2 lata
  • Postów:2500
2
Kopiuj
int tmp1;
int *tab1 = new int[tmp1];

Ile elementów Twoim zdaniem ma tab1?

Kopiuj
delete [] tab1;
return(tab1);

Najpierw usuwasz tę "tablicę", a potem ją przekazujesz dalej. Gdzie logika, gdzie sens?

przekazanie tej tablicy z funkcji wczytanie do funkcji najwiekszy

Kopiuj
int main()
{
    int* tab = wczytanie();
    int mymax = najwiekszy(tab);
    // pamiętaj o usuwaniu tab, ale tylko raz
}
edytowany 2x, ostatnio: twonek
F9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

dzięki! czy ten kod jest ok?

Kopiuj
int *wczytanie1()
{
	int tmp1;
	int *tab1 = new int[tmp1];
	int i = 0;

	ifstream plik1;
	plik1.open("liczby1.txt");

    
    
	while(!plik1.eof())
	{
		plik1 >> tab1[i];
		cout << tab1[i] << endl;
		i++;
	}
	tmp1 = i;
		
		plik1.close();
	
	
	return(tab1);
}


int najwiekszy(int tab[])
{
    int najw; /*zmienna do przechowywania najwiekszego elementu*/
    najw = tab[0];
    for( int i = 0; i <= sizeof(tab); i++ )
    {
        if(tab[i] > najw ) najw = tab[i];
        else najw;    
    }
    
    
    return najw;
}

int main()
{
	int	*tab1 = wczytanie1();
	int mymax = najwiekszy(tab1);
	
	cout << endl << endl << "najwieksza liczba to: " << mymax << endl << endl;
	system("pause");
	return 0;
} 
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0
Kopiuj
int tmp1;
int *tab1 = new int[tmp1];

Jaka będzie wielkość utworzonej tablicy tab1?

Kopiuj
sizeof(tab)

To nie działa tak jak myślisz.

Kopiuj
else najw;

Co to ma Twoim zdaniem robić?


edytowany 5x, ostatnio: Patryk27
F9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0

tutaj mam problem, bo chciałbym, aby jej rozmiar był zdefiniowany przez liczbę elementów znajdujących się w moim pliku.

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

Wykorzystaj zatem std::vector, a nie zgaduj.


F9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:16
0
Kopiuj
int tmp1;
int *tab1 = new int[tmp1];

Jaka będzie wielkość utworzonej tablicy tab1?

tak, tu mam problem, wiem. nie mam pojęcia, jak policzyć liczbę elementów w moim pliku i potem utworzyć tablicę dynamiczną o takiej wielkości.

Kopiuj
sizeof(tab)

To nie działa tak jak myślisz.

tak, wiem, pozbyłem się tego.

Kopiuj
else najw;

Co to ma Twoim zdaniem robić?

jeśli wartość tablicy jest mniejsza od wcześniejszej (bądź zdefiniowanej na początku dla tab[0]), wtedy nie zmienia się wartość zmiennej przechowującej największy element.

edytowany 2x, ostatnio: Filippo9669
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

tak, tu mam problem, wiem. nie mam pojęcia, jak policzyć liczbę elementów w moim pliku i potem utworzyć tablicę dynamiczną o takiej wielkości.

Nie musisz nic liczyć - wykorzystaj std::vector.

jeśli wartość tablicy jest mniejsza od wcześniejszej (bądź zdefiniowanej na początku dla tab[0]), wtedy nie zmienia się wartość zmiennej przechowującej największy element.

Nie, pytam specyficznie co instrukcja najw; ma Twoim zdaniem robić i po co tam to else tak właściwie.


edytowany 3x, ostatnio: Patryk27
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)