CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Wskaźnik do tablicy jako argument funkcji

Wskaźnik do tablicy jako argument funkcji

dział ogólny

Wskaźnik do tablicy jako argument funkcji

Nowy postprzez nvdante » poniedziałek, 16 marca 2015, 10:55

Witam ponownie!
Chciałbym napisać krótki kod, który po odpaleniu main wywoła funkcję z argumentem podanym przez usera, a następnie zrobi tablicę n-elementową i do kolejnej funkcji poda wskaźnik do tablicy oraz jej rozmiar.
Napisałem sobie takie coś:
KOD cpp:     UKRYJ  
#include <iostream>
#include <windows.h>
#include <ctime>

using namespace std;
void srednia(int, int);

void funkcja(int n)
{
        int *t1=new int[n];
        srand(unsigned(time(0)));
       
        for (int i=0; i<n; i++)
                {
                        t1[i]=rand()%10;
                }
        for (int i=0; i<n; i++)
                {
                        cout<<"["<<t1[i]<<"]";
                }
        cout<<endl<<"Wskaznik do tablicy to: "<<&t1<<endl;
       
        int **wsk = &t1;
        srednia(**wsk, n);
}

void srednia(int wsk, int n)
{
        cout<< &wsk;
}

int main()
{
        cout<<"Podaj n: "<<endl;
        int n;
        cin>>n;
       
        funkcja(n);
       
        system("pause");
        return 0;
}
 

Problem jednak w tym, że:
- wsk wyświetla wartość inną niż &t1, więc nie jest to adres pamięci
- nie mogę odnaleźć drugiego elementu i kolejnych

Kompiluje na Dev-cpp i Visual Studio.
Pozdrawiam
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows VistaFirefox

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez Mironas » poniedziałek, 16 marca 2015, 11:48

Zmienna t1 jest wskaźnikiem a więc:

1. Nie musisz wyłuskiwać adresu z &t1 aby go wyświetlić.

2. Możesz ten wskaźnik (t1) przekazać do następnej funkcji jako parametr.
Nie musisz tworzyć kolejnego wskaźnika do wskaźnika (int **wsk = &t1) co zresztą źle robisz, tylko po to aby przekazać go do innej funkcji.

3. parametrem funkcji srednia powinien być wskaźnik a nie zmienną int.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez nvdante » poniedziałek, 16 marca 2015, 12:47

1. Ok tylko jak w takim przypadku pobrać adres np.: 1 elementu tablicy? Zapis t1[1] spowoduje pobranie wartości, a nie adresu. Czy w tej sytuacji mam wykorzystać &t1[1]? Skoro tak to &t1[0] da mi to samo co t1, prawda?
2. Czy w takim razie przekazanie powinno wyglądać tak:
KOD cpp:     UKRYJ  
typ_funkcji nazwa(typ *wskaźnik, typ zmienna)
{
}

int main()
{
     nazwa(*wskaźnik, zmienna);
}
 

Mam wrażenie, że main jest źle, ale nie wiem jak poprawić.
Czy w moim kodzie zapis: void srednia(int, int) jest dobry? Pisałeś, żeby przekazywać wskaźnik, więc nie wiem czy int, chociaż typ danych to int.
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows VistaFirefox

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez Mironas » poniedziałek, 16 marca 2015, 13:34

Zapis t1[1] spowoduje pobranie wartości, a nie adresu. Czy w tej sytuacji mam wykorzystać &t1[1]? Skoro tak to &t1[0] da mi to samo co t1, prawda?

Tak, tak, tak.

Przekazanie powinno wyglądać tak:
KOD cpp:     UKRYJ  
typ_funkcji nazwa(typ *wskaźnik, typ zmienna)
{
}

int main()
{
     //nazwa(*wskaźnik, zmienna); // Źle
     nazwa(wskaźnik, zmienna); // Dobrze
}

Za ten post autor Mironas otrzymał podziękowanie od:
nvdante
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez nvdante » poniedziałek, 16 marca 2015, 13:38

Super, wielkie dzięki, dalej postaram się sam :)
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows VistaFirefox

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez nvdante » wtorek, 17 marca 2015, 10:41

Zastanawia mnie jeszcze jedna rzecz.
Skoro takim kodem:
KOD cpp:     UKRYJ  
#include <iostream>
#include <Windows.h>
#include <ctime>

using namespace std;

void Funkcja(float x)
{
        cout<<"Zostalam wywolana "<<x<<" razy!"<<endl;
}

int main()
{
        int x=5;
        void (*Wskaznik)(float x);
        Wskaznik=&Funkcja;
        (*Wskaznik)(x);
       
        system("pause");
        return 0;
}
 

Jestem w stanie wywołać funkcję poprzez wskaźnik na nią z jednym argumentem to dlaczego w tym kodzie to nie działa:
KOD cpp:     UKRYJ  
#include <iostream>
#include <Windows.h>
#include <ctime>

using namespace std;

void zwieksz(float x, float d)
{
        cout << "Liczba " << x << " zwiekszona o " << d << " daje liczbe: " << x + d << endl;
}

void zmniejsz(float x, float d)
{
        cout << "Liczba " << x << " zmniejszona o " << d << " daje liczbe: " << x - d<<endl;
}

void dzialanie(float x, float d)
{
        int wybor;
        cout << "Wybierz dzialanie na liczbach: " << endl;
        cout << "1. Zwiekszenie wartosci" << endl;
        cout << "2. Zmniejszenie wartosci" << endl;
        cin >> wybor;
       
        void(*zwieksz)(float x, float d);
        zwieksz=&zwieksz;
        void(*zmniejsz)(float x, float d);
        zmniejsz=&zmniejsz;
        switch (wybor)
        {
                case 1:
                        (*zwieksz)(x, d);
                        break;
                case 2:
                        (*zmniejsz)(x, d);
                        break;
        }
}

int main()
{
        float x, d;
        cout << "Podaj liczbe: " << endl;
        cin >> x;
        cout << "Podaj wartosc zmiany: " << endl;
        cin >> d;

        dzialanie(x, d);

        system("pause");
        return 0;
}
 

Odpowiedź kompilatora to:

In function 'void dzialanie(float, float)':
[Error] cannot convert 'void (**)(float, float)' to 'void (*)(float, float)' in assignment
[Error] cannot convert 'void (**)(float, float)' to 'void (*)(float, float)' in assignment
recipe for target 'main.o' failed

Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows VistaFirefox

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez polymorphism » wtorek, 17 marca 2015, 10:59

KOD cpp:     UKRYJ  
zwieksz = &zwieksz;
zmniejsz = &zmniejsz;

Nie wiem, jak żeś wpadł na pomysł nazwania wskaźników dokładnie tak samo jak funkcje, których adresy przypisujesz. Kompilator ma prawo zgłupieć.

Tak jest czytelniej:
KOD cpp:     UKRYJ  
typedef void(*fp)(float, float);

fp zwieksz_ = &zwieksz;
fp zmniejsz_ = &zmniejsz;


KOD cpp:     UKRYJ  
switch (wybor)
{
case 1:
        (*zwieksz)(x, d);
        break;
case 2:
        (*zmniejsz)(x, d);
        break;
}

Po co te wskaźniki, jeśli w tym switchu spokojnie możesz wywołać funkcje "po nazwie"? Chyba o to Ci chodziło:
KOD cpp:     UKRYJ  
fp op = nullptr;

switch (wybor)
{
case 1: op = &zwieksz; break;
case 2: op = &zmniejsz; break;
};

if(op) op(x, d);
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez Mironas » wtorek, 17 marca 2015, 11:05

Dlatego, że używasz tej samej nazwy dla funkcji i dla wskaźnika do niej.
Dla przykładu polecenie:
KOD cpp:     UKRYJ  
zwieksz=&zwieksz;

dla kompilatora może oznaczać nie przypisanie adresu funkcji do wskaźnika (co było Twoim celem) a przypisanie adresu wskaźnika do wskaźnika - albo jakoś tak.

PS
Zakładam, że masz powód aby komplikować proste operacji i posługiwać się wskaźnikami do funkcji a nie wywoływać po nazwie.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez nvdante » wtorek, 17 marca 2015, 11:07

Genialnie, teraz działa.
Chciałem uniknąć bałaganu, a zrobiłem jeszcze większy :)
Bardzo dziękuję!

@Mironas, niestety mam, wymagania uczelni - wykładowca karze, student musi ;)
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows VistaFirefox

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez polymorphism » wtorek, 17 marca 2015, 11:10

p.s. przeedytowałem posta, przeczytaj.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez nvdante » wtorek, 17 marca 2015, 11:33

Treść zadania jest następująca:
Zdefiniowana zostanie funkcja dzialanie() wywołująca ( za pomocą wskaźnika ) funkcję zwieksz() lub zmniejsz(). Wskaźnik do funkcji zwieksz() lub zmniejsz() ( użytkownik dokonuje wyboru działania ) jest przekazywany jako argument do funkcji dzialanie().

W związku z tym pomyślałem, żeby w switchu dać odwołanie poprzez wskaźnik do konkretnych funkcji. W sumie działa, więc raczej bym tak zostawił.
Dużo prościej można by to było zrobić właśnie po nazwie, ale chodziło o sprawdzenie zastosowania wskaźników "w akcji".

Nie bardzo tylko mam pomysł na ostatnią część, czyli na przekazanie wskaźników do funkcji działanie() jako argument. Powinienem w main() przypisać wskaźniki do funkcji i razem ze zmiennymi x i d przekazać oba do funkcji dzialanie(), a z niej do funkcji zwieksz() lub zmniejsz()? Trochę to komplikuje sprawę, bo wskaźniki są dwa, a możliwa do wykonania operacja tylko jedna.
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows VistaFirefox

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez polymorphism » wtorek, 17 marca 2015, 15:31

Dużo prościej można by to było zrobić właśnie po nazwie, ale chodziło o sprawdzenie zastosowania wskaźników "w akcji".

Nie. Po nazwie nie możesz, bo w zadaniu masz napisane, że dzialanie ma wywołać funkcję, którą dostanie w parametrze, więc ten switch robi wyjazd.

Jeśli dobrze rozumiem, chodzi o coś takiego:
KOD cpp:     UKRYJ  
void dzialanie(float x, float d, fp fn)
{
       fn(x, d);
}

/* wywołanie */
dzialanie(x, d, &zwieksz);
...

dzialanie(x, d, &zmniejsz);
 
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez nvdante » wtorek, 17 marca 2015, 17:40

No, ale chyba muszę umieścić dzialanie() w switchu, bo inaczej użytkownik nie dokona wyboru tylko wykona oba działania.
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows 7Firefox

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez Mironas » wtorek, 17 marca 2015, 18:31

Nie - to nie musi byś switch. Może być if lub jeszcze prościej:
KOD cpp:     UKRYJ  
  op = (wybor==1) ? &zwieksz : &zmniejsz
  op(x, d);
 

Tylko w tym konkretnym przypadku jeśli użytkownik wybierze błędnie, np 3 to wykona się funkcja zmniejsz.
Avatar użytkownika
Mironas
Programista I
Programista I
 
Posty: 427
Dołączył(a): poniedziałek, 2 stycznia 2012, 19:02
Podziękował : 17
Otrzymał podziękowań: 61
System operacyjny: Windows 10
Kompilator: C++Builder 10.3 Rio
TMS Components Pack
Gadu Gadu: 0
    Windows XPChrome

Re: Wskaźnik do tablicy jako argument funkcji

Nowy postprzez nvdante » wtorek, 17 marca 2015, 19:28

OK, dzięki :) Potestuję.
Liberae sunt nostrae cogitationes
Avatar użytkownika
nvdante
Intelektryk
Intelektryk
 
Posty: 188
Dołączył(a): piątek, 12 czerwca 2009, 16:58
Lokalizacja: Dom
Podziękował : 8
Otrzymał podziękowań: 0
System operacyjny: Windows 7
Kompilator: VS 2015
Gadu Gadu: 0
    Windows 7Firefox

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 1 gość

cron