Jak zwrócić tablicę z funkcji?

2

Bo masz: uint32_t funkcja(...
zaś ma być: kxw funkcja(...

#include <iostream>
using namespace std;

struct kxw { uint32_t k,x,w; };

kxw funkcja(uint32_t k, uint32_t x)
{
    uint32_t s = k | 1;
    uint32_t w = 0;

    for (int i = 0; i < 32; i++)
    {
        k += x;
        x = x * k;
        x ^= (w += s);
    }

    return kxw { k,x,w };
}

int main()
{
    uint32_t k_init = 1; 
    uint32_t x_init = 12345;

    kxw x=funkcja(k_init,x_init);
    
    return 0;
}
0

@MarekR22: można by jeszcze wspomnieć o RVO (Return Value Optimalization):

#include <array>
#include <iostream>

std::array<uint32_t, 3> funkcja(uint32_t k, uint32_t x) {
    uint32_t                s = k | 1;
    uint32_t                w = 0;
    std::array<uint32_t, 3> wynik;

    std::cout << "address of wynik   = " << &wynik << std::endl;

    for (int i = 0; i < 32; i++) {
        k += x;
        x = x * k;
        x ^= (w += s);
    }

    wynik[0] = k;
    wynik[1] = x;
    wynik[2] = w;

    return wynik;
}

int main() {
    auto tablica = funkcja(3, 3);
    std::cout << "address of tablica = " << &tablica << std::endl;

    return 0;
}

wynik działania:

address of wynik   = 0xad643ffe04
address of tablica = 0xad643ffe04

widać, że kompilator zastosował RVO i uniknął zbędnego kopiowania obiektu.

1
AnyKtokolwiek napisał(a):
Tomasz_D napisał(a):

Próbuję zwrócić tablicę w funkcji i użyć jej elementu. W Pythonie coś takiego zadziała, w c++ nie działa.

Po pierwsze, to nie jest C++, a jedziesz prawie niezmienione C.

https://4programmers.net/Forum/C_i_C++/364571-suma_elementow_dynamicznej_tablicy_jednowymiarowej?p=1876794#id1876794

Problem ze zwróceniem tablicy w C jest taki, że nie ma tam pełnowartościowej tablicy (obiektu, który ma świadomość swojej liczności, który zna swoje granice, śmiech na sali postawić pytanie: czy pilnuje swoich granic, umie nimi zarządzać)
Jest tylko strasznie prymitywny obszar pamięci - który w pełni można wyrazić jako wskaźnik do pierwszego elementu.

C++ ma prawdziwą tablicę (a nawet dwie) std::array i std:vector

1

Rozwiązanie jest następujące (uwaga - nie działa gdy korzystasz z rekurencji lub wątków):

/* dopisz gwiazdkę po typie zawracanym */
uint32_t* funkcja(uint32_t k, uint32_t x)
{
    uint32_t s = k | 1;
    uint32_t w = 0;
    static uint32_t wynik[3]; /* dopisz kwalifikator "static" */

    for (int i = 0; i < 32; i++)
    {
        k += x;
        x = x * k;
        x ^= (w += s);
    }
    /* normalnie korszystaj z tablicy, pamiętając o inicjalizacji */
    wynik[0] = k;
    wynik[1] = x;
    wynik[2] = w;

    return wynik; /* teraz możesz zwrócić tę tablicę */
}


int main()
{
    uint32_t k_init = 1; 
    uint32_t x_init = 12345;

    uint32_t k = funkcja(k_init, x_init)[0];

    return 0;
}
2
Manna5 napisał(a):

Rozwiązanie jest następujące (uwaga - nie działa gdy korzystasz z rekurencji lub wątków):

No i właśnie z tego powodu to jest złe rozwiązanie.

Mało tego na jednym wątku nie będzie działać prawidłowo, jak dwa razy wywoła się tę funkcję. Np coś takiego:

auto a = funkcja(1, 2);
auto b = funkcja(10, 1);
std::cout << (a[0] + b[0]) << '\n';
0

Zrobiłem tę strukturę:

#include <cstdint>
#include <cstdio>
#include <bitset>
#include <immintrin.h>
#include<iostream>
#include<array>

struct kxw { uint32_t k,x,w; };

struct kxw initializator(uint32_t k, uint32_t x)
{
    uint32_t s = k | 1;
    uint32_t w = 0;

    for (int i = 0; i < 32; i++)
    {
        k += x;
        x = x * k;
        x ^= (w += s);
    }

    return kxw {k,x,w};
}

int main()
{
    uint32_t k_init = 12345; 
    uint32_t x_init = 67891;

    uint32_t k = initializator(k_init, x_init).k;
    uint32_t x = initializator(k_init, x_init).x;
    uint32_t w = initializator(k_init, x_init).w;

    return 0;
}

0
Tomasz_D napisał(a):

Zrobiłem tę strukturę:

    uint32_t k = initializator(k_init, x_init).k;
    uint32_t x = initializator(k_init, x_init).x;
    uint32_t w = initializator(k_init, x_init).w;

Tylko że po chińskiego powtarzasz obliczenia?

    kxw poludzku=initializator(k_init, x_init);
    uint32_t k=poludzku.k;
    uint32_t x=poludzku.x;
    uint32_t w=poludzku.w;
0

Tak a propos, dopiero zauważyłem że to c++ więc czemu podchodzisz do tego od d..py strony?

#include <cstdint>
#include <iostream>
using namespace std;

class kxw
{
	public:
	uint32_t k,x,w;
	kxw(uint32_t k,uint32_t x):k(k),x(x) {}
	kxw &operator++()
	{
	    uint32_t s=k|1;
		w=0;	
	    for(int i=0;i<32;++i)
	    {
	        k+=x;
	        x*=k;
	        x^=(w+=s);
	    }
	    return *this;
	}
};

int main()
{
	kxw it(12345,67891);
	for(int i=0;i<10;++i,++it) cout<<"k="<<it.k<<"; x="<<it.x<<"; w="<<it.w<<";"<<endl;
    return 0;
}
``
0

Dlaczego od d**y strony? Nie wiem czym jest:

kxw(uint32_t k,uint32_t x):k(k),x(x) {}
kxw &operator++()

i

kxw it(12345,67891);

Więc nie mogłem tego tak napisać. Nie idzie tego nawet wygooglać. Generalnie wiem tylko czym są funkcje, nigdy nie używałem klas, ani struktur, kojarzę jedynie z definicji czym są.

1
Tomasz_D napisał(a):

Nie idzie tego nawet wygooglać. Generalnie wiem tylko czym są funkcje, nigdy nie używałem klas, ani struktur, kojarzę jedynie z definicji czym są.

Cóż, to przykre. Jak pracujesz z Rosji może tak być.

Na szczęście u nas google i cały internet działa normalnie

1 użytkowników online, w tym zalogowanych: 0, gości: 1