|
|
|
|
Strumenti |
06-02-2020, 01:18 | #1 |
Junior Member
Iscritto dal: Jan 2020
Messaggi: 17
|
C problemi funzione puntatore per vettore
RINGRAZIO SUBITO PER L'ATTENZIONE!
L'esercizio chiedeva di usare una funzione: int * negativi(int a[],int n,int *c); per il ritorno di un vettore di negativi presi da un altro primo vettore. trovo dei problemi nel ritorno del vettore di negativi..funziona tutto ma al momento di stampa del vett. mi da solo zeri. nell'esempio dell'esercizio veniva usata una funzione MAXALLOCAZIONE su risultato..può essere questo il problema? ecco il codice completo: Codice:
#include <stdio.h> int * negativi(int a[],int n,int* c); int carica(int a[]); #define MAX 20 int main(){ int a[MAX+1]; int b[MAX+1]={0}; int* c; int i,n,j; c=&j; n=carica(a); int* p1; p1=&b[0]; for(i=0;i<n;i++) printf("- %d ",*(a+i)); printf("\nCERCO I NEGATIVI\n"); p1=negativi(a,n,c); for(i=0;i<j;i++) printf("- %d ",*(b+i)); //stampa vettore di negativi } //----------------- int carica(int a[]){ int i,val; int n=0; for(i=0;i<MAX;i++){ scanf("%d",&val); if(val!=-1){ a[i]=val; n++; } else break; } return n; } int * negativi(int a[],int n,int* c){ int* risultato; int i; int j=0; for(i=0;i<n;i++){ if(a[i]<0){ risultato[j]=a[i]; //riempimento vettore di negativi j++; } } *c=j; return risultato; } Ultima modifica di 9abs : 06-02-2020 alle 01:20. |
06-02-2020, 07:31 | #2 |
Senior Member
Iscritto dal: Apr 2005
Messaggi: 2993
|
Sono un pelo arrugginito col c++ ma.. quel carica.. cosa è che carica?
Non vedo puntatori quindi sono tutte variabili locali e quando poi tu le richiami in cerca va a cercare roba in un array non inizializzato. A me sotto linux infatti va in core dump. Prova a debuggare mettendo un break sulla funzione e vedere cosa passa come valori. |
06-02-2020, 09:32 | #3 |
Senior Member
Iscritto dal: Apr 2001
Città: Milano
Messaggi: 3594
|
risultato:
1 -3 4 5 6 1,-3,4,5,6, CERCO I NEGATIVI -3, nota: #define MAX 5 al posto di 20 Codice:
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop //--------------------------------------------------------------------------- #pragma argsused #include <stdio.h> #include <conio.h> int * negativi(int a[],int n,int* c); int carica(int a[]); #define MAX 5 int main() { int a[MAX+1]; int b[MAX+1]={0}; int *c; int i,n,j; c = &j; n = carica(a); int* p1; p1=&b[0]; for(i=0;i<n;i++) printf("%d,",*(a+i)); printf("\nCERCO I NEGATIVI\n"); p1 = negativi(a,n,c); for(i=0;i<j;i++) printf("%d,",*(p1+i)); //stampa vettore di negativi // perchè b e non p1?????? getch(); // mia aggiunta } //----------------- int carica(int a[]) { int i,val; int n=0; for(i=0;i<MAX;i++) { scanf("%d",&val); if(val!=-1) { a[i]=val; n++; } else break; } return n; } int * negativi(int a[],int n,int *c) { int *risultato; risultato = (int *)malloc(5); // mia aggiunta int i; int j=0; for(i=0;i<n;i++) { if(a[i]<0) { risultato[j] = a[i]; //riempimento vettore di negativi j++; } } *c = j; return risultato; } |
06-02-2020, 12:24 | #4 |
Junior Member
Iscritto dal: Jan 2020
Messaggi: 17
|
PROBLEMA RISOLTO
grazie ho risolto il problema!
era questo pezzo: Codice:
for(i=0;i<j;i++) printf("- %d ",*(p1+i)); //con *(b+i) non mi funziona..come mai? //gli elementi non dovrebbero trovarsi in b[ ] Codice:
#include <vcl.h> //questo #pragma hdrstop //questo //--------------------------------------------------------------------------- #pragma argsused //questo #include <stdio.h> #include <conio.h> //questo è solo per C++? Anche sinteticamente senza farvi perdere troppo tempo! Grazie ancora per l'aiuto e l'attenzione! |
06-02-2020, 12:35 | #5 |
Senior Member
Iscritto dal: Apr 2005
Messaggi: 2993
|
inoltre volevo sapere di più su:
Codice:
#include <vcl.h> //questo #pragma hdrstop //questo //--------------------------------------------------------------------------- #pragma argsused //questo #include <stdio.h> #include <conio.h> //questo è solo per C++? pragma hdrstop <- https://docs.microsoft.com/en-us/cpp...p?view=vs-2019 pragma argsused dice che la prossima funzione non dove preoccuparsi se il parametro non viene mai invocato conio.h sono le funzioni per leggere quello che gli passi nel prompt essenzialmente |
06-02-2020, 23:08 | #6 |
Senior Member
Iscritto dal: May 2001
Messaggi: 12580
|
Al volo, mi riferisco al sorgente originale:
Codice:
int * negativi(int a[], int n, int* c) { int* risultato; int i; int j=0; for (i=0; i<n; i++) { if (a[i] < 0) { risultato[j]=a[i]; //riempimento vettore di negativi j++; } } *c=j; return risultato; } La prima cosa che si vede è che usi un puntatore non inizializzato, un errore abbastanza grave, se fossi mio studente ti avrei dato 0 . Premessa: ti suggerisco di studiarti per bene la differenza tra array e puntatori (e si, c'è differenza e non poca al contrario di quello che molti pensano). Un puntatore altro non è che un indirizzo ad un area di memoria. Nel tuo caso, il puntatore non è inizializzato o meglio possiamo considerare il suo contenuto praticamente RANDOM. Nella migliore delle ipotesi il tuo programma ti dà dati sballati, nella peggiore crasha. La domanda che devi farti è, dove metto questi valori? Ci sono due possibilità, stack oppure heap. La memoria stack è già allocata ed è quella in cui sono appoggiate le variabili automatiche, che vengono create all'entrata di una funzione e "distrutte" al termine. Risultato, i e j sono variabili automatiche ad esempio, al termine della funzione la loro memoria non è più disponibile (le cose sono un po' diverse di così ma non voglio complicarti la vita). Un array non può essere restituito da una funzione C. Questo significa che puoi restituire solo il suo indirizzo di base. L'indirizzo che restituisci al termine della funzione non può puntare ad un area dello stack della stessa funzione perché come detto non sarebbe più raggiungibile. Quindi hai due strategie: 1) passi un puntatore ad un area pre-allocata, ad esempio così: Codice:
void negativi(int a[], int n, int* c, int* risultato); Codice:
void funzione_invocante(void) { int a[3] = { -1, 0, 1 }; int ris[3] = { 0, }; int num_insert; negativi(a, 3, &num_insert, ris); } 2) usi la funzione di allocazione dinamica malloc(), come ti ha suggerito misterx. Questa funzione prende in input il numero di bytes da allocare e restituisce un puntatore diverso da NULL se l'allocazione è andata a buon fine. Nota che in questo caso l'allocazione avviene in un'area di memoria chiamata "heap" che non viene liberata in automatico. Al termine del suo utilizzo va usata la funzione free() che prende in ingresso il puntatore restituito da malloc(): Codice:
int* vettore = malloc(5 * sizeof(int)); /* alloco lo spazio per 5 interi */ if (vettore == NULL) { fprintf(stderr, "Errore durante l'allocazione!!!\n"); ... /* exit() o return codice di errore */ } negativi(..., vettore); /* fai qualcosa con vettore */ free(vettore); Siccome malloc() prende in ingresso la dimensione in bytes, devi considerare l'occupazione di memoria del tuo vettore. Se sono interi significa che ciascun elemento occuperà sizeof(int) bytes quindi allocare lo spazio per 5 interi significa allocare 5*sizeof(int) bytes. Mi sono dilungato ma spero sia stato chiaro Ultima modifica di WarDuck : 06-02-2020 alle 23:13. |
07-02-2020, 19:14 | #7 | |
Member
Iscritto dal: Feb 2006
Messaggi: 134
|
Quote:
Va bene anche il resto che hai scritto, ma questa te la dovevo quotare. E' tutto il giorno che sistemo il codice scritto da uno che non indenta manco se sennò muore |
|
07-02-2020, 20:45 | #8 |
Senior Member
Iscritto dal: May 2001
Messaggi: 12580
|
Se usi Linux ti suggerisco di dare un'occhiata al programma indent
|
10-02-2020, 18:56 | #9 |
Junior Member
Iscritto dal: Jan 2020
Messaggi: 17
|
|
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 02:08.