Doubt about pointers

4

This code creates array, initializes and prints, as well as adding, subtracting and multiplying arrays:

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 do not understand why it puts indexes on elements being that it was not declared so. And for what it uses pointer to pointer to int ; and what would be the difference if it was just a pointer to int ?

    
asked by anonymous 11.03.2015 / 23:46

2 answers

3

With arrays (two-dimensional arrays) there are subtilizes:

int a[10][10]

a contiguous memory area of 100 integers is reserved. And when you use a[2][2]
ends up being internally transformed 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 function parameters you want to work for arrays of any dimension, we have problems: you do not have an easy way of declaring a variable-sized array (there are ways to get around).

When you declare

int **a 

You're bound to 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 declaration is independent of size (and therefore good for function parameters involving matrices of variable length).

When the matrices are large the temporal efficiency and memory can be very different .

    
13.03.2015 / 14:32
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 deep down when you write:

a[5]

In fact the code for this is

*(a+5)

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

When you have arrays it is common for you to have a pointer that indicates a dimension of the array to another pointer that is another dimension of the array.

A pointer to 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 indirections. To access the actual data you want you have to first find out where is the address where the address of where the value is. It's like a treasure hunt where every place has a new clue to the treasure.

There are also strings in C. They are pointers to char .

So if you have a array , at the bottom you have a pointer (which symbolizes the array ) for a pointer the string ). So at the bottom an array of strings in the background is a two-dimensional array .
char *texto = "texto"; //string
char **ponteiroParaTexto = &texto; //referência para a string

C also has no equal references to other languages at the highest level. Pointers are used to access a reference.

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

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

12.03.2015 / 00:20