Passaggio di argomenti

di michxle il
10 risposte

Ho scritto una funzione per trovare la riga di una matrice in cui compare un carattere speciale ma quando richiamo la funzione nel main mi da l'errore: passing argument 1 of 'trova_riga_avatar' from incompatible pointer type, ma non capisco perché.

 int trova_riga_avatar(char **v, int rig, int col)
{
  bool b = false;
  for(int i=0; i<rig; i++)
  {
    for(int j=0; j<col; j++)
    {
      if(v[i][j] == 'o')
      {
        b = true;
        return i;
      }
    }
  }
}
int main()
{
char lab[5][5];
x = trova_riga_avatar(lab, 5, 5);
return 0;
}

10 Risposte

  • Intanto la variabile b non serve dato che non te ne fai nulla.

    Deve essere 

    int trova_riga_avatar(char v[][5], int rig, int col)

    Inoltre manca un valore da restituire se la if fallisce sempre. La funzione deve terminare con

        return -1;
    }

    e la x nel main deve essere di tipo int

    int x = trova_riga_avatar(lab, 5, 5);
  • Grazie mille per i consigli. Posso chiedere come mai nella firma della funzione devo scrivere char v[][5], cioè il 5 per cosa sta?

  • Le righe non sono necessarie, le colonne sì. Ecco perché 5

  • 20/02/2023 - michxle ha scritto:


    Grazie mille per i consigli. Posso chiedere come mai nella firma della funzione devo scrivere char v[][5], cioè il 5 per cosa sta?

    Quando si utilizza l'identificatore di un array, escluso alcuni casi particolari, questo decade a puntatore al suo primo elemento. Nel caso specifico lab, quando passato come argomento alla funzione, sarà convertito in un puntatore ad un array di 5 (la dimensione più interna) char; l'argomento della funzione dovrà quindi essere del tipo:

    char (*v)[5]

    Volendo può andar bene anche

    char v[][5]

    ma a mio parere risulta meno esplicativo.

    Ovviamente quanto da te scritto non potrebbe mai andar bene in quanto

    char **v

    char (*v)[5]

    sono due tipi diversi, e se gli passi lab il programma si aspetta un puntatore ad un array di 5 char e di certo non un puntatore doppio a char.

  • Ok ma se io volessi non specificare il il numero di colonne della matrice nella funzione perché nel main viene chiesto all'utente di inserirlo ed è quindi un numero variabile?

  • Allora dovresti allocare dinamicamente la matrice e non come hai scritto nel mail.

    A quel punto dovresti usare un doppio puntatore.

    Se scrivi in C usi la malloc , in C++ la new

  • Se è C e non C++ puoi fare così

    #include "stdio.h"
    
    int trova_riga_avatar(int rig, int col, char v[rig][col]){
      for(int i=0; i<rig; i++)
        for(int j=0; j<col; j++)
          if(v[i][j] == 'o')
            return i;
      return -1;
    }
     
    int main(){
        char lab[4][3] = {
            {'a', 'b', 'c'},
            {'d', 'e', 'f'},
            {'f', 'g', 'h'},
            {'o', 'j', 'k'}       
        };
        int x = trova_riga_avatar(4, 3, lab);
        printf("%d", x);
        return 0;
    }
  • Ma scusate, senza impazzire troppo sul tipo dati da passare o su come gestire righe e colonne

    o anche se usare C o C++

    non gli conveniva passare l'indirizzo della matrice e poi andare di aritmetica dei puntatori?

    santo C storico che va anche in C++, per definizione?

    oppure ho capito male qualcosa io? 

  • Potrebbe essere una soluzione più complessa se non ha familiarità con i puntatori.

    E non è comunque elegante trattare tutto come un vettore piatto 

  • Che non sia elegante concordo

    Ma visto che si tratta, lo ha scritto stamane, di una matrice di dimensione imposta a runtime, io vedo poche alternative, magari mi sbaglio io…

    Oltre un anno fa avevo fatto una cosa (in C, no C++) che attraverso un typeof di un casting ad un VLA permetteva di usare comunque gli indici, come se un doppio puntatore fosse una matrice nativa

    Ma sono il primo ad affermare che è una “molto brutta cosa” 

Devi accedere o registrarti per scrivere nel forum
10 risposte