Functie ce returneaza pointer catre integer

c

(George Cristea) #1

Salutare am o nelamurire in legatura cu functiile ce returneaza pointer catre un anumit tip de date …
De exemplu nu inteleg unde ar trebui sa fie greseala in acest cod :slight_smile:

#include<stdio.h>
int *f1(int x, inty)
{
return (x+y);
}
int main()
{
int a=2,b=3,*s;
s=f1(a,b);
printf("%d",*s);
}

(Cosmin Popescu) #2
#include "stdafx.h"


#include<stdio.h>
#include <conio.h>
int f1(int x, int y)
{
	return x + y;
}
int main()
{
	int a = 2, b = 3/*, *s*/;
	//s = f1(a, b);
	int(*funcPtr)(int, int) = &f1;
	printf("%d", funcPtr(1, 1));
	_getche();
}

citeste in link-urile de mai jos


Al doilea link iti explica minunea int(*funcPtr)(int, int) = &f1;

Foloseste un ide sau debugger ca sa vezi erorile


(Adrian) #3

De ce ai vrea sa incerci sa afli ce valoare int e la adresa 5? :slight_smile:


(George Cristea) #4

hmm cred ca am inteles, deci functia returneaza o adresa cum as putea sa fac ca functia sa returneze adresa sumei celor 2 parametri ?


(Cosmin Popescu) #5

cred ca functia iti pune la o adresa rezultatul si cu & ii iau de la adresa aia

Precizare: Nu am mai pus mana pe C din anul 1 de facultate. Multe amintiri sunt vagi

_getche() l-am adugat ca sa nu dispara fereastra.


(George Cristea) #6

programul de mai sus e pentru un test si trebuie sa imi dau seama unde e greseala , dar chiar nu am inteles pointerii catre functii prea bine


(Adrian) #7

Te-as sfatui sa nu incerci asa ceva. Atat cei doi parametri cat si valoarea returnata se pun de obicei pe stiva (cu exceptii cand se opereaza cu registri). Valorile temporare pot fi pe stiva sau in ceva registri, se pot suprascrie. Daca tot vrei sa returnezi o adresa, ai putea sa aloci memorie in functie (dar atunci esti responsabil de eliberare dupa ce termini cu valoarea returnata). O alta metoda ar fi sa ai o valoare globala si sa returnezi pointer la valoarea aia, sau sa ai o valoare statica in functie cam asa:

static int val;
val = a + b;
return &val;

Nu vad de ce ai face asemenea lucruri in asemenea situatie. E inutil.


(George Cristea) #8

Nu e ca si cum vreau neaparat sa fac asta vreau doar sa inteleg mai bine termenul si problema e una didactica http://prntscr.com/jiqaxg , poti sa ma lamuresti de ce apare aceasta eroare , am inteles ca functia returneaza adresa a unei sume dintre doi intregi dar ce este gresit in ea


(Adrian) #9

Ai putea sa faci conversia explicit la ‘(int*)’ ca sa scapi de eroarea la compilare, dar dupa aia o sa ai o surpriza cu ‘*s’. Dupa cum spuneam, nu e o idee buna. Incearca varianta din raspunsul meu anterior, daca tii mortis sa returnezi un pointer.


(George Cristea) #10

da chiar am inteles si am incercat ce ai zis , ideea e ca eu cautam o justificare pt acea eroare de compilare http://prntscr.com/jiqg47 de asta vroiam sa inteleg cum ar fi aratat codul corect cel mai apropiat de codul acesta , dar cred ca am gasit justificarea erorii ! Multumesc mult amandurora!


(Cosmin Popescu) #11

citeste si aici

te ajuta sa intelegi mai bine


(Adrian) #12

Pai justificarea e simpla, vrei sa returnezi un tip intreg in locul unei adrese. E adevarat ca pana la urma poti sa fortezi conversia, dar nu are prea mult sens in aceasta circumstanta.


(Serghei Amelian) #13

Am sezaţia că omul crede că funcţia returneaza adresa la care se află suma.


(George Cristea) #14

Nu,am inteles ce returneaza defapt !


(Serghei Amelian) #15

Funcţia ta nu face decât să returneze rezultatul adunării, atât şi nimic mai mult. Întămplator, pointerii sunt şi ei un fel de integeri (pe 64 de biti, im cazuri programelor pe 64 de biti), din acest motiv nu primesti eroare de compilare acolo.


(Cosmin Popescu) #16

@George_Cristea am incercat azi o alta abordare

int f1(int *x, int *y)
{
	return *x + *y;
}

int main()
{
	/*int a = 2, b = 3, *s;
	s = f1(a, b);
	printf("%d", *s);*/

	int x = 10;
	int y = 20;

	//initializez pointerii cu adresele variabilelor x si y de mai sus
	int* a = &x;
	int* b = &y;



	int s = f1(a, b);
	printf("%d", s);
	_getche();
}

Sper sa fie mai clar. Cred ca este mai aproape de ceea ce voiai sa faci tu initial


https://www.cs.auckland.ac.nz/references/unix/digital/AQTLTBTE/DOCU_045.HTM


(Serghei Amelian) #17

De fapt mai util ar fi ceva de genul ăsta (ceva de genul ăsta se foloseşte în factory pattern).

http://cpp.sh/8beht

#include <stdio.h>
#include <stdlib.h>


int *f1(int a, int b)
{
    // se aloca memorie in heap
    int *result = (int*)malloc(sizeof(int));
    
    // se stocheaza rezultatul adunarii in heap
    *result = a + b;
    
    // se returneaza adresa memoriei unde este stocat
    // rezultatul adunarii
    return result;
}


int main()
{
    int a = 2, b = 3, *s;
    
    // atentie, aici se aloca memorie
    // dupa ce terminam cu ea, trebuie dealocata
    // alfel ne trezim cu celebrul memory-leak
    s = f1(a, b);
    
    printf("%d",*s);
    
    // atentie, memoria trebuie dealocata
    free(s); 
    
    return 0;
}

Desigur, in C++ se va folosi perechea de operatori new si delete sau new şi “smart pointer”.


(George Cristea) #18

Acum sigur am inteles , multumesc amandurora!


(Adrian) #19

Adica ce-i explicam mai sus in cuvinte. Apropo de smart pointers, nu mai e nevoie sa folosesti new, poti sa folosesti std::make_shared (sau std::make_unique, daca folosesti unique_ptr). Pentru cine are chef de asa ceva, se poate scrie un intreg program fara sa apara in el (m/c/re)alloc/free, new/delete.