How can I make this code more readable and efficient? How can I rewrite this code to make it more readable and, if possible, more efficient? The conditions are entirely necessary in this problem, but how could I rewrite those if(a != 1) and such?

celula ** verificaNo(celula ** matriz, int linhas, int colunas){
celula ** aux = matriz;
int i, j, k;
int node = 1;
int a = 0;
int b = 0;
int c = 0;


for(i = 0; i &lt; linhas; i++){
    for(j = 0; j &lt; colunas; j++){
        if((i == 0) &amp;&amp; (j == 0)){
            aux[i][j].no = node;
        }
        else if((i == 0) &amp;&amp; (j != 0)){
            if(aux[i][j-1].peso == 0 &amp;&amp; aux[i][j].peso == 0){
                aux[i][j].no = aux[i][j-1].no;
            }
            else if(aux[i][j-1].peso != 0 &amp;&amp; aux[i][j].peso == 0){
                for(k = j; aux[i+1][k].peso == 0 &amp;&amp; k &gt; 0; k--){
                    if(aux[i][k-1].peso == 0){
                        aux[i][j].no = aux[i][k-1].no;
                        a = 1;
                    }
                }
                if(a != 1){
                    node++;
                    aux[i][j].no = node;
                }
            }
        }
        else if((j == 0) &amp;&amp; (i != 0)){
            if(aux[i-1][j].peso == 0 &amp;&amp; aux[i][j].peso == 0){
                aux[i][j].no = aux[i-1][j].no;
            }
            else if(aux[i-1][j].peso != 0 &amp;&amp; aux[i][j].peso == 0){
                for(k = j; aux[i][k].peso == 0 &amp;&amp; k &lt; colunas; k++){
                    if(aux[i-1][k+1].peso == 0){
                        aux[i][j].no = aux[i-1][k+1].no;
                        b = 1;
                    }
                }
                if(b != 1){
                    node++;
                    aux[i][j].no = node;
                }
            }
        }
        else if(aux[i][j].peso == 0 &amp;&amp; aux[i-1][j].peso == 0 &amp;&amp; i != 0){
            aux[i][j].no = aux[i-1][j].no;
        }
        else if(aux[i][j].peso == 0 &amp;&amp; aux[i][j-1].peso == 0 &amp;&amp; j != 0){
            aux[i][j].no = aux[i][j-1].no;
        }
        else if(aux[i][j].peso == 0){
            for(k = j; aux[i][k].peso == 0 &amp;&amp; k &lt; colunas; k++){
                if(i != 0){
                    if(aux[i-1][k].peso == 0){
                        aux[i][j].no = aux[i-1][k].no;
                        c = 1;
                    }
                }
            }
            if(c != 1){
                node++;
                aux[i][j].no = node;
            }
        }
    }
}   
return aux;
}
This would become instantly more understandable if you gave a description (a comment at the start of the function) of what it was supposed to do.  You could also give the structure celula, which I'm assuming is at least:

struct celula
{
    int no;        // number of something?
    int peso;      // weight, perhaps?
};


Also you use i for line (linhas) and j for column (colunas). But l and c would be more logical and readable (but l looks like 1, so in English I'd use r for "row").  I'm generally ok with short variable names, but in such a long function i and j don't work for me.  In English I would probably use row and col.

As your function has nested loops with the outer loop doing nothing but enclosing the inner loop, I would if possible extract the whole inner loop to a separate function. But I can see that this might not be easy if those badly named variables a, b, c, loop accumulate across rows.  It is difficult to tell whether they do from a short look - I might take a longer look later...

Later...

Returning to variables a, b, c:  they are never reset once set. 
Is that correct?  These variables names are meaningless and need changing.  And what does node mean - again the name needs improving.

A bigger observation is that everything below the first else contains the term aux[i][j].peso == 0.  I think these can all be factored out (so that the condition is tested at the top of the loop. 

for(i = 0; i &lt; linhas; i++){
    for(j = 0; j &lt; colunas; j++){
        if((i == 0) &amp;&amp; (j == 0)){
            aux[i][j].no = node;
        }
        else if(aux[i][j].peso == 0) {  // moved to here
            if((i == 0) &amp;&amp; (j != 0)){


And also the i != 0 and j != 0 in the following lines are unnecessary, as they have been handled further up:

else if(aux[i-1][j].peso == 0 &amp;&amp; i != 0){                     // here
    aux[i][j].no = aux[i-1][j].no;
}
else if(aux[i][j-1].peso == 0 &amp;&amp; j != 0){                     //here
    aux[i][j].no = aux[i][j-1].no;
}
else{
    for(k = j; aux[i][k].peso == 0 &amp;&amp; k &lt; colunas; k++){
        if(i != 0){                                           // here