Esercizio sui vettori in C

Obidream
Salve a tutti, vorrei chiedervi di dare un'occhiata al seguente esercizio per aiutarmi a concluderlo.

Si scriva un programma C che
a. nel main chieda all’utente di inserire N valori interi e li metta in un
vettore vett, quindi chieda un ulteriore valore intero di x
b. passi il vettore e x ad una funzione che moltiplichi ciascuno
degli elementi del vettore per x, il cui prototipo è

void mult(int v[], int n, int x);

Ecco un mio abbozzo di soluzione:

#include <stdio.h>
#include <stdlib.h>
#define N 5

void mult(int v[], int n, int x); /* prototipo della funzione */

int main()
{
int vett[N],indice,x;

printf("Si inseriscano N numeri:\n");

for(indice=0; indice<N; indice++)
scanf("%d",&vett[indice]);

printf("Si inserisca un ulteriore valore intero x\n");
scanf("%d",&x);

for(indice=0; indice<N; indice++)
    printf("\nL'elemento %d equivale a %d\n",indice+1,vett[indice]); /* indice+1 serve a visualizzare gli elementi partendo da 1 e non da zero */

return EXIT_SUCCESS;

}

void mult(int v[], int n, int x)
{
int i;

for(i=0; i<n; i++)
    v[i] *= x;

return;
}


In pratica il mio problema penso sia questo.. come faccio a dire nel main che ho fatto la moltiplicazione richiesta con la funzione mult e stampare a video il risultato? :)

Risposte
nessuno.nobody
Considera che int v[] è un puntatore al primo elemento dell'array, quindi tu passando "l'array" (che in C sono una bugia) alla funzione, hai passato anche il suo valore.

Non devi fare altro che invocare la funzione all'interno dei main con i parametri corretti e stampare poi i valori del puntatore (l'array) passato alla funzione mul

Obidream
Grazie per la risposta, inanzitutto :) Sistemato in questa maniera "gira" :wink:

#include <stdio.h>
#include <stdlib.h>
#define N 5

void mult(int v[], int n, int x); /* prototipo della funzione */

int main()
{
int vett[N],indice,x;

printf("Si inseriscano N numeri:\n");

for(indice=0; indice<N; indice++)
scanf("%d",&vett[indice]);

printf("Si inserisca un ulteriore valore intero x\n");
scanf("%d",&x);

mult(vett,indice,x);

for(indice=0; indice<N; indice++)
    printf("\nL'elemento %d equivale a %d\n",indice+1,vett[indice]); /* indice+1 serve a visualizzare gli elementi partendo da 1 e non da zero */

return EXIT_SUCCESS;

}

void mult(int v[], int n, int x)
{
int i;

for(i=0; i<n; i++)
    v[i] *= x;

return;
}


Piccola curiosità personale: questo è il primo corso di informatica della mia vita, quindi in che senso gli array in C sono bugia? :D

nessuno.nobody
Perché:
int v[] e int *v sono la stessa identica cosa.
Che entrambi vogliono dire "il puntatore al primo elemento di v", dopo tu, con la notazione a quadre, mediante un indice, accedi alle varie locazioni di memoria allocate sequenzialmente.
Ma fare v[1] non è altro che l'equivalente dello spostare il puntatore di che punta al primo elemento di v, di sizeof(int)*1 in avanti.
Gli array in C, non sono altro che puntatori a una zona di memoria in cui tu puoi liberamente accedere.
Un array come char v[10], avrà a disposizione sizeof(char)*10 byte di memoria contigua allocata, in cui tu puoi spaziare liberamente.
Appena provi ad accedere ad un elemento al di fuori dell'indice (salvo "sicurezze" del compilatore (stack protection)), ricevi un segnale d'errore che ti dice che non puoi andare oltre e fa terminare il programma (ma in C puoi gestire anche questi ed evitare al chiusura del programma).

robe921
sinceramente non capisco perché inserisci la libreria stdlib.h solo per quel "return EXIT_SUCCESS".. non era più comodo un "return 0"?

se usi una procedura "void" non hai motivo di scrivere "return" alla fine, perché per definizione una procedura non restituisce nulla (void)

vict85
Inserire il return è utile per l'utente perché identifica subito dove finisce la funzione.

robe921
a mio parere, invece, può essere fuorviante in una void

claudio862
"nessuno.nobody":
int v[] e int *v sono la stessa identica cosa.

In realtà no, c'è qualche differenza tra array e puntatori, ad esempio:

#include <stdio.h>

int main()
{
    char a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
    char *b = a;
    
    //a++; // Questo è un errore
    b++;   // Questo no
    
    printf("sizeof(a) = %lu\n", (unsigned long)sizeof(a));
    // = 13 (il numero di elementi di a)
    
    printf("sizeof(b) = %lu\n", (unsigned long)sizeof(b));
    // = 4 (la dimensione di int* sul mio computer)
}

Però in effetti un array decade a puntatore quasi ovunque, quindi il discorso è valido, a parte questo:

Appena provi ad accedere ad un elemento al di fuori dell'indice [...] ricevi un segnale d'errore che ti dice che non puoi andare oltre e fa terminare il programma

Purtroppo non succede sempre, a volte continua a funzionare senza dare errori e magari dando anche risultati plausibili.


"robe92":
sinceramente non capisco perché inserisci la libreria stdlib.h solo per quel "return EXIT_SUCCESS".. non era più comodo un "return 0"?

Aumenta un po' la semantica, non stai restituendo semplicemente un numero (0), ma stai comunicando che l'esecuzione ha avuto successo. In caso contrario invece credo che l'unico modo standard sia usare EXIT_FAILURE, dato che anche valori diversi da zero possono significare successo su alcune piattaforme (ad esempio su VMS si usa 1).

nessuno.nobody
Penso che il return EXIT_SUCCESS sia cosa buona e giusta, è sempre meglio usare costanti che ci tolgono dubbi (ovviamente per un programma del genere chi se ne frega, però in applicazioni più corpose un EXIT_SUCCESS, EXIT_FAIULRE, et simila sono praticamente un obbligo (visto un minimo di cross-platform possible col C).
Mentre per un return all'interno di una funzione void, la vedo una cosa inutile, che non aumenta nemmeno la leggibilità

Obidream
"nessuno.nobody":
Penso che il return EXIT_SUCCESS sia cosa buona e giusta, è sempre meglio usare costanti che ci tolgono dubbi (ovviamente per un programma del genere chi se ne frega, però in applicazioni più corpose un EXIT_SUCCESS, EXIT_FAIULRE, et simila sono praticamente un obbligo (visto un minimo di cross-platform possible col C).
Mentre per un return all'interno di una funzione void, la vedo una cosa inutile, che non aumenta nemmeno la leggibilità

Per quanto riguarda l'EXIT_SUCCESS è una cosa che ci ha suggerito il docente proprio per il motivo da te spiegato, mentre il return nel void è inutile in effetti, tanto la funzione è comunque chiusa dal blocco.. L'ho comunque inserito perché questo è un esercizio che il prof assegna e che poi va a finire su un portale della didattica, una volta che viene corretto da lui, e siccome non abbiamo pratica con le funzioni è meglio inserirlo per ora :)

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.