Doubt about pointers

Asked

Viewed 260 times

4

This code creates matrix, initializes and prints, as well as adding, subtracting and multiplying matrices:

typedef struct{  
    int nl;  
    int nc;  
    int **elementos;  
}MATRIZ;  
void criar_matriz (int, int, MATRIZ *);  
void inicializar_matriz (MATRIZ *);  
void imprimir_matriz (MATRIZ *);  
void somar_matrizes (MATRIZ *, MATRIZ *,MATRIZ *);  
void subtrair_matrizes (MATRIZ *, MATRIZ *,MATRIZ *);  
void multiplicar_matrizes (MATRIZ *, MATRIZ *, MATRIZ *);  

void criar_matriz (int nl, int nc, MATRIZ *m) {  
    int i, j;       
    m->elementos = (int **) malloc (sizeof(int *)*nl);  
    if (!m->elementos) {  
        printf("Nao foi possivel reservar memoria para a matriz!\n");  
        exit(1);  
    }  
    for (i=0; i<nl; i++) {  
        m->elementos[i] = (int *) malloc (sizeof(int)*nc);  
        if (!(m->elementos[i])) {  
            printf("Nao foi possivel reservar memoria para a matriz!\n");  
            exit(2);  
        }  
    }  
    m->nl = nl;  
    m->nc = nc;  
    for (i=0; i<nl; i++)    
    for (j=0; j<nc; j++)  
    m->elementos[i][j] = 0;  
}  

void inicializar_matriz (MATRIZ *m) {  
    int i, j;  
    for (i=0; i<m->nl; i++)  
    for (j=0; j<m->nc; j++) {  
        printf ("\nEntre com matriz[%d][%d]=",i+1,j+1);  
        scanf ("%d",&(m->elementos[i][j]));  
    }  
}  
void imprimir_matriz (MATRIZ *m) {  
    int i, j;
    for (i=0;i<m->nl;i++) {  
        printf("\n|");
        for (j=0;j<m->nc;j++)  
            printf ("%5d", m->elementos[i][j]);  
        printf(" |");  
    }  
}  
void somar_matrizes (MATRIZ *m1, MATRIZ *m2, MATRIZ *m3) {  
    if (m1->nl==m2->nl && m1->nc==m2->nc) {  
        int i, j;  
        criar_matriz (m1->nl, m1->nc, m3);  
        for (i=0; i<m3->nl; i++)  
            for (j=0; j<m3->nc; j++)  
                m3->elementos[i][j] = m1->elementos[i][j] + m2->elementos[i][j];  
    } else {  
        printf ("A soma nao eh possivel!\n");  
    }  
}  
void subtrair_matrizes (MATRIZ *m1, MATRIZ *m2, MATRIZ *m3) {  
    if (m1->nl==m2->nl && m1->nc==m2->nc) {  
        int i, j;  
        criar_matriz (m1->nl, m1->nc, m3);  
        for (i=0; i<m3->nl; i++)  
            for (j=0; j<m3->nc; j++)  
                m3->elementos[i][j] = m1->elementos[i][j] - m2->elementos[i][j];  
    } else {  
        printf ("A soma nao eh possivel!\n");  
    }  
}  
void multiplicar_matrizes (MATRIZ *m1, MATRIZ *m2, MATRIZ *m3) {  
    if (m1->nc==m2->nl) {  
        int i, j, z;  
        criar_matriz (m1->nl, m2->nc, m3);  
        for (i=0; i<m3->nl; i++)  
            for (j=0; j<m3->nc; j++) {  
                m3->elementos[i][j] = 0;  
                for (z=0; z<m1->nc; z++)  
                    m3->elementos[i][j] += m1->elementos[i][z] * m2->elementos[z][j];  
            }  
    } else {  
        printf ("A multiplicacao nao eh possivel!\n");  
    }  
}  

But I don’t understand why he puts indexes on elements when he wasn’t declared that way. And why he uses pointer to pointer to int; and what would be the difference if it was just a pointer to int?

  • 1

    If you know English, take a look at c-Faq especially section 6.

2 answers

7

It’s simple, in C there are no arrays in fact, it’s just a syntactic sugar, it’s just to make life easier for the programmer. C only has pointers. So in the background when you write:

a[5]

actually the code of this is

*(a+5)

So the ways of writing array and pointers are often interchangeable in most situations.

When you have matrices it is common to have a pointer that indicates one dimension of the matrix to another pointer that is another dimension of the matrix.

A pointer to pointer of int means that you have a pointer that points to another pointer and only this second pointer has a pointer that points to an integer. You have two indirect. To access the real data you want you have to find out first where the address where the value is. It’s like a treasure hunt game where every place gives a new clue until you get to the treasure.

Nor are there strings in C. They are pointers to char.

So if you have one array of strings, at the bottom has a pointer (which symbolizes the array) to a pointer (which symbolizes the string). So deep down a array of strings at the bottom is a array two-dimensional.

char *texto = "texto"; //string
char **ponteiroParaTexto = &texto; //referência para a string

C also does not have equal references to other higher-level languages. Pointers are used to access a reference.

So every time you need to access a reference to a array or a string, or even for another reference, it will have pointer to pointer. A parameter known to be some form of pointer that will be received by reference will use this form of indirect.

It is possible to have several levels of indirect but in general two is the practical limit for the vast majority of problems. If you need more, there’s a reasonable chance the code is too confusing and should be refactored.


  • Ahhhhh, I get it. Thanks/

  • 1

    @If understood and the answer is satisfactory mark it as the answer to your question.

3


With matrices (two-dimensional arrays) there are some subtilizas:

int a[10][10]

a contiguous memory area of 100 integers is reserved. And when you use a[2][2]
ends up being transformed internally into something similar to

*(a+2+2*10)

or a special one-dimensional array. This implies knowing the "10" or the inner dimension of the matrix.

So when you define the parameters of the function you want it to work for matrices of any dimension, we have problems: you don’t have an easy way to declare a variable size matrix (there are ways to go around).

In declaring

int **a 

you’re bound by a more complex memory allocation, (which in the case you presented is not contiguous) and the occurrences of a[2][2] are interpreted as:

 *(*(a+2)+2)

This statement is independent of the size (and therefore good for declaration of function parameters involving variable size matrices).

When the matrices are large a temporal efficiency and of total memory occupied, can be very different.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.