<!-- Introdução à Programação - 2017 - Prof. Leoônidas de Oliveira Brandão Introdução aos vetores em C LInE (Laboratory of Informatics in Education) - http://www.usp.br/line IME - USP Material didático Pode usar livrevemente este material para fins não comerciais, devendo sempre fazer referência à autoria. Sugestões/apontamento são bem vindos: leo@ime.usp.br (favor indicar no assunto "material de introducao 'a programacao") Prof. Leônidas de Oliveira Brandão http://www.ime.usp.br/~leo http://line.ime.usp.br http://www.matemtica.br --> <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'> <meta name='keywords' content='mac0122, material, professores, leonidas de oliveira brandao'> <link rel='stylesheet' type='text/css' href='css_img_js_conf/all.css'> <link rel='stylesheet' type='text/css' href='css_img_js_conf/line_introducao_programacao.css'> <script src="css_img_js_conf/defineLInE.js"></script> <!-- para referencias 'a documentos internos --> <div class="pagina"> <!-- <center><p>[ <a href="#" title=""></a> | <a href="#memoria" title=""></a> ]</p> </center> --> <p class="secao">Introdução aos vetores em <i>C</i></p> <p> Como explicado no <a href="#" onclick="trocaPagina('introducao_vetores.html')" title="introducao aos vetores">texto introdutório ao conceito de vetores</a>, um vetor é uma sequência de dados ocupando posições consecutivas de memória e por isso existe uma ordem natural entre seus elementos, o primeiro elemento, o segundo e assim por diante. A grande vantagem de usar vetor é poder trabalhar com muitas variáveis utilizando um único nome para esse "agregado" de variáveis. Para isso existe uma sintaxe especial para pegar cada elemento do vetor, em posições específicas, como o primeiro elemento ou o décimo elemento. </p> <p> A linguagem <i>C</i> trata o conceito de vetor de um modo bastante próximo ao modo como é possível implementar esse conteito. Ilustraremos isso mostrando que podemos usar <i><a href="#" onclick="trocaPagina('introducao_apontadores_c.html')" title="ver apontadores em C">apontadores</a></i> para pegar elementos dos vetores. </p> <bloco1>Neste texto: <a class="" title="definir e imprimir um vetor" href="#define">definir/imprimir vetor</a>; <a class="" title="definir e imprimir string" href="#string">definir "string"</a>; <a class="" title="funcoes da biblioteca string.h" href="#strcmp">funções para "string"</a>; <a class="" title="vetor e apontadores" href="#apontador">vetor e apontador</a>; <a class="" title="definir e imprimir uma matriz" href="#matriz">definir/imprimir matriz</a>; <a class="" title="trabalhr com vetor/matriz dinamica (via apontador)" href="#dinamica">vetor/matriz dinâmicas</a>. </bloco1> <!-- secao --> <a name="define"> <p class="secao">1. Definindo e imprimindo um vetor</p> </a> <p> Pode-se construir um vetor em <i>C</i> fornecendo todos seus elementos, como em: <tt><verm>int</verm> vet[] = {21, 22, 23, 24};</tt>. </p> <p> Pode-se também construir de modo "dinâmico", dependendo dos valores que variáveis assumem em meio ao código. Para isso deve-se declarar o máximo de posições que o vetor ocupará (como <tt><def>#define</def> MAX 10 ... <verm>int</verm> vet[MAX];</tt>) e depois define-se cada elemento, por exemplo, usando um comando de atribuição, como: <tt>vet[i] = 10+i;</tt>, que define o valor do elemento na posição <i>i</i> como o valor <tt>10+i</tt>. </p> <p> No exemplo a seguir construímos um vetor com <i>MAX</i> elementos, iniciando no <i>10+i</i> e seguindo até o <i>10+n-1</i>. Nesse exemplo indicamos, em um comentário, como usar apontador (<i>*(v+i)=10+i</i>) para definir os elementos de um vetor (usando <i>aritmética de ponteiros</i>). </p> <div class="exemplo"><i>Exemplo 1</i>. Construir um vetor e imprimir seus elementos. </div><!-- class="exemplo" --> <div class="codigo"> <pre><incl1>#include</incl1> <stdio.h> // Declarar uma constante (para ser usada como dimensao maxima do vetor) <def>#define</def> MAX 10 // Funcao para imprimir elementos de vetor em uma mesma linha // Nao precisa saber do total alocado para o vetor efetivo, pois para pegar o elemento i basta // saber a primeira posicao, digamos 'apont' e pegar '*(apont + i)' <verm>void</verm> imprime_vetor1 (<verm>int</verm> vet[], <verm>int</verm> tam) { <verm>int</verm> i; for (i=0; i<tam; i++) <verd>printf</verd>("%d ", vet[i]); <verd>printf</verd>("\n"); <cyan>// ao final quebre a linha</cyan> } // Esta funcao define os valores para o vetor (passagem por referencia/endereco) // Lembrando: todo vetor e' passado por referencia 'a funcao (logo // alterar seus valores localmente implica em alterar os valores do // parametro efetivo! // Por ser vetor como parametro, nao precisa declarar a dimensao (nao precisa reservar espaco, e' apenas uma referencia) // Mas se fosse matriz precisaria saber dimensao coluna <verm>void</verm> definirVetor (<verm>int</verm> v[], <verm>int</verm> tam) { <verm>int</verm> i; for (i=0; i<tam; i++) <cyan>// definir vetor/lista com: (10,11,12,13,...10+n-1)</cyan> v[i] = 10+i; <cyan>// Aqui altera' o 'parametro efetivo'! Tambem pode-se usar como apontador: *(v+i) = 10+i;</cyan> } <verm>int</verm> main (<verm>void</verm>) { <verm>int</verm> n=10, vet[MAX]; <cyan>// alocar MAX posicoes para o vetor 'vet' (pode-se usar menos)</cyan> definirVetor(vet, n); <cyan>// parametro efetivo 'vet' por ser vetor, se alterado na funcao, altera o efetivo!</cyan> <cyan>// Imprime o vetor/lista de uma so' vez (na mesma linha)</cyan> <verd>printf</verd>("\nO vetor: "); imprime_vetor1(vet, n); <cyan>// em C NAO e' possivel imprimir todos os dados de um vetor => fazer uma funcao...</cyan> return 0; }</pre> </div><!-- class="codigo" --> <p> <b>Importante</b>. Em <i>C</i>, usar um <i>vetor como parâmetro (formal) em função</i> implica que esta usando <b>passagem por referência (ou endereço)</b>! <br/> Portanto, dentro da função, se alterar o valor de qualquer elemento do vetor (<i>parâmetro formal</i>), isso implicará que, durante a execução, o seu <i>parâmetro efetivo</i> (aquele que é <i>passado efetivamente</i> para função) terá o elemento correspondente alterado. Por este motivo, no exemplo acima, ao fazer uma atribuição dentro da função (<tt>v[i] = 10+i;</tt>), estamos na verdade alterando os valores do <i>parâmetro efetivo</i> <tt>vet</tt>, por esse motivo usamos o nome <b style="color:#0000aa">passagem por referência (ou endereço)</b>, é como se o <i>parâmetro formal</i> <tt>v[]</tt> fosse uma <b>referência</b> (um "apelido") para o <i>parâmetro efetivo</i> <tt>vet[]</tt>. <br/> Se tiver dúvidas, <a href="#" onclick="trocaPagina('introducao_parametros_funcoes.html')" title="examine o texto sobre parametros de funcoes">reveja o texto sobre parâmetros de funções</a>. </p> <!-- secao --> <a name="string"> <p class="secao">2. Defininido uma <i>cadeia de caracteres</i> ("string")</p> </a> <p> Em <i>C</i> é possível definir um vetor com caracteres, formando uma palavra, ou seja, uma <i>cadeia de caracteres</i>, que abreviadamente é denominada "<i>string</i>". Para isso pode-se fazer uma atribuição como constante ou ler os dados como palavra. Isso é ilustrado no exemplo abaixo. </p> <div class="exemplo"><i>Exemplo 2</i>. Trabalhando com "strings". Uma "string" fixa e digitar uma frase, imprimindo o número de caracteres nela. </div><!-- class="exemplo" --> <div class="codigo"> <pre><incl1>#include</incl1> <stdio.h> <incl1>#include</incl1> <string.h> <cyan>// para usar a funcao 'strlen(...)'</cyan> <verm>void</verm> main (<verm>void</verm>) { <verm>int</verm> i; <verm>char</verm> string[] = "0123456789abcdefghih"; <cyan>// (1) - define a "string"</cyan> <cyan>// Imprimir cada caractere da string com seu codigo ASCII</cyan> <verd>printf</verd>("Imprime caracteres e seus codigos ASCII na forma de tabela\nColuna 1 => caractere; coluna 2 => seu codigo ASCII\n"); <!--" --> for (i=0; i<strlen(string); i++) <verd>printf</verd>("%20c : %3d\n", string[i], string[i]); <cyan>// em C inteiro pode ser "lido" como caractere e vice-versao (via codigo ASCII)</cyan> <cyan>// Pode-se imprimir como uma frase toda usando o formatador %s</cyan> <verd>printf</verd>("Frase: %s\n", string); <cyan>// A string tem 20 caracteres, testando os caracteres 19 'h' e 20 '\n'</cyan> <verd>printf</verd>("A string tem 20 caracteres, testando os caracteres 19 '%c' e 20 '\\n' em ASCII=%d\n", string[19], string[20]); }</pre> </div><!-- class="codigo" --> <p> Deve-se notar que em <i>C</i>, ao fazer a leitura de uma "string" (por exemplo, via teclado com <tt><verd>scanf</verd>("%s", &string);</tt>), automaticamente é inserido o caractere '\0' ao final da "string". Assim, no exemplo acima ao declarar a "string" com o comando <tt><verm>char</verm> string = "0123456789abcdefghih";</tt>, essa terá 20 caracteres "úteis" (a última posição "útil" será a posição 19, com o caractere 'h') e na posição 20 existirá o caractere '\0' (cujo código ASCII é o zero - 0). </p> <!-- secao --> <a name="apontador"> <p class="secao">3. Vetores e apontadores</p> </a> <p> Uma vantagem didática da utilização da linguagem <i>C</i> em um curso introdutório de programação é que essa é uma linguagem que não esconde muitos detalhes de como os conceitos são implementados. Isso possibilita mostrarmos os fundamentos da computação, os princípios elementares que permitem a construção de sistemas mais sofisticados. Nesse sentido o conceito de vetor é ilustrativo, pois sua implementação depende da existência de apontadores. </p> <p> Ao declarar um vetor, significa que associamos um nome de variável (o "nome do vetor") a uma sequência de posições de memória, todas de mesmo tipo (logo de mesmo tamanho). Na verdade essa variável guarda o endereço inicial do vetor, o endereço de seu primeiro elemento. <center> <img src="img/int_vet_apontador_menor.png" title="representacao de vetor em memoria com indicacao de endereco ocupado"/> </center> </p> <p><sabermais title="Para quem deseja saber como funciona"> Por exemplo, ao declarar o vetor com <tt><verm>int</verm> v[5];</tt>, são reservadas 5 posições de memória, cada uma com o número de <i>bytes</i> suficientes para armazenar um dado do tipo <i>int</i> (cada <i>int</i> geralmente ocupa 2 <i>bytes</i> ou 16 <i>bits</i>). Vamos supor que <i>sizeof(int)</i> devolve o número de <i>bytes</i> ocupados por qualquer número inteiro (essa função existe precisamente com este sentido na biblioteca <tt>stdlib.h</tt>). Assim, se o primeiro elemento do vetor está na posição de memória <i>X</i>, então o endereço do segundo será <i>X+sizeof(int)</i> e assim por diante até o último desses 5 elementos, que estaria na posição <i>X+5*sizeof(int)</i>. </sabermais></p> <p> O nome de um vetor em <i>C</i> é na verdade uma variável <i><a href="#" onclick="trocaPagina('introducao_apontadores_c.html')" title="ver apontadores em C">apontadora</a></i> e esse fato retoma a observação de <i>C</i> não esconder detalhes. Além disso a linguagem permite calculemos a posição de um elemento de vetor somando ao seu endereço inicial o número de elementos que desejamos pular (e.g. <tt>v+3</tt>). Fazendo isso, automaticamente o compilador traduz essa expressão deslocando o número de <i>bytes</i> do tipo envolvido e por isso, fazer <tt>v+3</tt>, é o mesmo que pegar o elemento da posição 3 ou <tt>v[3]</tt>. </p> <p> Como a declaração de uma variável apontadora é feita usando um asterisco (como em <tt><verm>int</verm> *apont;</tt>), vamos apresentar um código simples que declara um vetor e depois usamos um apontador para mostrar que, com ele, também podemos "passear" por todos os elementos do vetor. </p> <div class="exemplo"><i>Exemplo 3</i>. Construindo um vetor e imprimindo seus elementos via um apontador. </div><!-- class="exemplo" --> <div class="codigo"> <pre><incl1>#include</incl1> <stdio.h> <verm>void</verm> imprimeVetor (<verm>int</verm> *apont, <verm>int</verm> n) { <verm>int</verm> i; <verd>printf</verd>("Vetor:"); <cyan>// supondo X ser o primeiro endereco em 'apont'</cyan> for (i=0; i<n; i++) <verd>printf</verd>(" %d", *(apont+i)); <cyan>// pegar elemento na posicao 'X + i*sizeof(int) - isso e' o mesmo que apont[i]</cyan> <verd>printf</verd>("\n"); } <verm>int</verm> main (<verm>void</verm>) { <verm>int</verm> vet1[] = { 5, 4, 3, 2, 1 }; <cyan>// define vetor com 5 posicoes de 0 ate' 4</cyan> <verm>int</verm> *apont; <verm>int</verm> N = 5; imprimeVetor(vet1, N); <cyan>// passa para "apont" o endereco inicial do vetor</cyan> return 0; }</pre> </div><!-- class="codigo" --> <p> Assim, também é possível alterar os valores em qualquer posição do vetor a partir do endereço. Por exemplo, se fizermos<br/> <tt> <verm>int</verm> vet1[5], i; <cyan>// no lugar de linha 1 da main</cyan><br/> apont = vet1; <cyan>// ou apont = &vet1; ou apont = &vet1[0];</cyan><br/> for (i=0; i<5; i++) *(apont+i) = 5-i;</tt><br/> geraríamos novamente o vetor <tt>vet1 = { 5, 4, 3, 2, 1}</tt>. Experimente! </p> <!-- secao --> <p class="secao">4. Funções úteis da biblioteca <i>string.h</i></p> </a> <p> A implementação da função <tt>strlen</tt> (que está na biblioteca <tt>string.h</tt>) usa esse fato, a existência de um caractere especial que só pode ser utilizado em "string" como finalizador para encontrar o tamanho da "string". Assim, se fizer um comando como <tt>string[10] = '\0'; <verd>printf</verd>("%s\n", string);</tt>, será impresso na tela <tt>0123456789</tt>. </p> <p> Existem outras funções na biblioteca <tt>string.h</tt>, uma delas é a <tt>strcpy(str1,str2)</tt> que copia o conteúdo da "string" <i>str2</i> sobre a <i>str1</i>, desde que a declaração delas seja compatível (ou seja, <i>str2</i> não pode ter mais caracteres do que a declaração inicial de <i>str1</i>). Outra função bastante útil é a <tt>strcmp</tt> que compara lexicograficamente (ordem dos dicionários) duas "strings", do seguinte modo, o comando <tt>strcmp(str1, str2)</tt> devolve <ul> <li>negativo, se <i>str1</i> menor lexicograficamente que <i>str2</i></li> <li>zero, se <i>str1</i> igual a <i>str2</i></li> <li>positivo, se <i>str1</i> maior lexicograficamente que <i>str2</i></li> </ul> </p> <!-- secao --> <a name="matriz"> <p class="secao">5. Defininido vetor de vetor (ou matriz)</p> </a> <p> Uma vez que um vetor/lista é armazenado consecutivamente na memória, então podemos armazenar vários vetores também consecutivamente para obter algo que represente (e seja tratado como) uma <b style="color:#00aa00">matriz</b>. Como na imagem abaixo, em que cada alocamos <i>nl</i> vetores consecutivos na memória, cada vetor com <i>nc</i> posições de memória, desde <tt>vet[0]</tt> até <tt>vet[nc-1]</tt>. Assim, podemos ver este agregado de dados como uma matriz <tt>mat[][]</tt>, cuja primeira linha é o primeiro vetor e assim por diante. Isso está ilustrado na imagem abaixo. <center> <img src="img/int_vet_vet_representacao.png" title="representacao matriz e como fica em memoria como vetor de vetor"/> </center> </p> <p> Desse modo obtemos uma estrutura com dois índices que pode ser manipulada como uma matriz (como em <i>mat[i][j]</i>). No exemplo abaixo ilustramos isso de dois modos, imprimindo as linhas da matriz e mostrando que pode-se passar como parâmetro uma linha de matriz para uma função que tenha como <i>parâmetro formal</i> um vetor. </p> <div class="exemplo"><i>Exemplo 4</i>. Construindo matriz como vetor de vetor e ilustrando que cada linha dela é um vetor, podendo portanto ser usado para chamar uma função que tem como parâmetro um vetor. </div><!-- class="exemplo" --> <div class="codigo"> <pre><incl1>#include</incl1> <stdio.h> <def>#define</def> MAXL 10 <cyan>// declarar constantes (para ser usada como dimensoes maximas da matriz)</cyan> <def>#define</def> MAXC 10 <cyan>// Funcao que soma elementos no vetor (precisa do numero de elementos no vetor para saber quando parar)</cyan> <verm>int</verm> soma_linha (<verm>int</verm> linha[], <verm>int</verm> n) { <cyan>// usando como parametro um vetor (NAO precisa da dimensa, explicacao abaixo)</cyan> <verm>int</verm> i, soma = 0; for (i=0; i<n; i++) soma += linha[i]; return soma; } <cyan>// Copiar aqui a funcao do exemplo 1: imprime_vetor1</cyan> <cyan>// Funcao para imprimir linhas de matriz (linha por linha): usa 'imprime_vetor1(...)' para imprimir uma linha</cyan> <cyan>// Precisa do numero de colunas pois na pratica os elementos estao em linhas de MAXC elementos</cyan> <verm>void</verm> imprime_matriz (<verm>int</verm> mat[][MAXC], <verm>int</verm> numLinhas, <verm>int</verm> numColunas) { <verm>int</verm> i; for (i=0; i<numLinhas; i++) imprime_vetor1(mat[i], numColunas); <cyan>// para pegar inicio de 'mat[i]' usa-se o valor de MAX</cyan> } <verm>void</verm> main (<verm>void</verm>) { <verm>int</verm> mat1[MAXL][MAXC]; <cyan>// alocar MAXL*MAXC posicoes para a matriz 'mat1' ('mat1' e' um vetor de vetor)</cyan> <verm>int</verm> n = 10, i, j, nl, nc, prim, seg; <cyan>// Vetor de vetor ou matriz</cyan> nl = 3; nc = 4; for (i=0; i<nl; i++) <cyan>// foram alocados na memoria MAXL*MAXC</cyan> for (j=0; j<nc; j++) <cyan>// mas usaremos apenas nl*nc</cyan> mat1[i][j] = i*nc + j; <cyan>// Pegando o primeiro e segundo elemento da terceira linha de mat1: mat1[2][1]</cyan> prim = mat1[2][0]; seg = mat1[2][1]; <cyan>// pegar primeiro e segundo elemento da linha mat1[2]</cyan> <verd>printf</verd>("O primeiro e segundo elemento da terceira linha da matriz: %d e %d\n", prim, seg); <cyan>// Imprime a matriz</cyan> <verd>printf</verd>("\nA matriz: \n"); <cyan>// informe o que vira impresso a seguir (na mesma linha devido ao parametro end=""</cyan> imprime_matriz(mat1, nl, nc); <cyan>// Verifique que cada linha da matriz e' de fato um vetor</cyan> <cyan>// Usar a funcao 'somalinha(...)' que soma elementos em vetor</cyan> for (i=0; i<nl; i++) <verd>printf</verd>("Soma da linha %2d = %3d\n", i, soma_linha(mat1[i], nc)); <cyan>// note que cada linha 'mat1[i]' tem 'nc' elementos uteis</cyan> } </pre> </div><!-- class="codigo" --> <!-- secao --> <a name="dinamica"> <p class="secao">6. Defininido vetor de vetor (ou matriz) de modo dinâmico.</p> </a> <p> Uma vez que um vetor é armazenado consecutivamente na memória, então podemos armazenar vetores de modo consecutivo para obter algo que represente (e seja tratado como) <i>matriz</i>. Neste caso obtemos uma estrutura com dois índices (como em <i>mat[i][j]</i>). No exemplo abaixo ilustramos isso de dois modos, imprimindo as linhas da matriz e mostrando que pode-se passar como parâmetro uma linha de matriz para uma função que tenha como <i>parâmetro formal</i> um vetor. </p> <div class="exemplo"><i>Exemplo 5</i>. Construindo matriz como vetor de vetor e ilustrando que cada linha dela é um vetor, podendo portanto ser usado para chamar uma função que tem como parâmetro um vetor. </div><!-- class="exemplo" --> <div class="codigo"> <pre><incl1>#include</incl1> <stdio.h> <incl1>#include</incl1> <stdlib.h> <cyan>// para 'malloc' e 'free'</cyan> <def>#define</def> MAXL 10 <cyan>// declarar constantes (para ser usada como dimensoes maximas da matriz)</cyan> <def>#define</def> MAXC 10 // Copiar aqui a funcao do exemplo 1: imprime_vetor1 // Funcao para imprimir elementos de vetor em uma mesma linha - usando aritmetica de ponteiro <verm>void</verm> imprime_vetor2 (<verm>int</verm> *pont, <verm>int</verm> tam) { <verm>int</verm> i; for (i=0; i<tam; i++) <cyan>// "*(pont+i)" significa, pegar a posicao do primeiro elemento</cyan> <verd>printf</verd>("%d ", *(pont+i)); <cyan>// (em 'linha') e deslocar i posicoes (do tipo 'int')</cyan> <verd>printf</verd>("\n"); <cyan>// ao final quebre a linha</cyan> } // Funcao que soma elementos no vetor: outra versao tratando o vetor como apontador <verm>int</verm> soma_linha (<verm>int</verm> *linha, <verm>int</verm> n) { <cyan>// usando como parametro apontador para inteiro</cyan> <verm>int</verm> i, soma = 0; <cyan>// Uma vez que um vetor e' na verdade uma sequencia de posicoes de memoria, C</cyan> <cyan>// simplesmente anota o endereco da primeira posicao no nome do vetor 'linha',</cyan> <cyan>// por isso e' a mesma coisa que declarar como parametro formal o apontador '<verm>int</verm> *linha'</cyan> for (i=0; i<n; i++) soma += *(linha + i); return soma; } // Funcao para imprimir linhas de matriz (linha por linha): usa funcao 'imprime_vetor1(...)' // Precisa do numero de colunas pois na pratica os elementos estao em linhas de MAXC elementos <verm>void</verm> imprime_matriz (<verm>int</verm> mat[][MAXC], <verm>int</verm> numLinhas, <verm>int</verm> numColunas) { <verm>int</verm> i; for (i=0; i<numLinhas; i++) imprime_vetor2(mat[i], numColunas); <cyan>// para pegar inicio de 'mat[i]' usa-se o valor de MAX</cyan> } <verm>void</verm> main (<verm>void</verm>) { <verm>int</verm> *vet2; <cyan>// declara um apontador para inteiro que depois apontara' para o vetor dinamico</cyan> <verm>int</verm> mat1[MAXL][MAXC]; <cyan>// alocar MAX*MAX posicoes para a matriz 'mat1' ('mat1' e' um vetor de vetor)</cyan> <verm>int</verm> (*apontador)[MAXC]; <cyan>// declara um apontador para linhas com MAXC elementos, se usar apenas '<verm>int</verm> *apontador',</cyan> <cyan>// '*(apontador[i]+j) = i*nc+j;' poderia resultar advertencia indicada em (1)</cyan> <verm>int</verm> n = 10, i, j, nl, nc, prim, seg; <cyan>// Vetor de vetor ou matriz</cyan> <cyan>// Definir a amtriz de 2 modos (com indices de matriz ou como apontador)</cyan> nl = 3; nc = 4; apontador = mat1; <cyan>// pegue o endereco inicial da matriz - (1) se usar "int *apontador", na declaracao</cyan> <cyan>// acima, poderia resultar advertencia: "warning: assignment from incompatible pointer type"</cyan> for (i=0; i<nl; i++) for (j=0; j<nc; j++) <cyan>// ilustra 2 forma de manipular matriz/vetor</cyan> if (j%2) <cyan>// se j impar => definir com indices</cyan> mat1[i][j] = i*nc + j; else <cyan>// se j par => definir com apontador</cyan> *(apontador[i] + j) = i*nc + j; <cyan>// deslocar i linhas (i*MAXC) e depois deslocar j elementos</cyan> <cyan>// Pegando o primeiro e segundo elemento da terceira linha de mat1: mat1[2][1]</cyan> prim = mat1[2][0]; seg = mat1[2][1]; <cyan>// pegar primeiro e segundo elemento da linha mat1[2]</cyan> <verd>printf</verd>("O primeiro e segundo elemento da terceira linha da matriz: %d e %d\n", prim, seg); <cyan>// Imprime a matriz</cyan> <verd>printf</verd>("\nA matriz: \n"); <cyan>// informe o que vira impresso a seguir (na mesma linha devido ao parametro end=""</cyan> imprime_matriz(mat1, nl, nc); <cyan>// Verifique que cada linha da matriz e' de fato um vetor</cyan> <cyan>// Usar a funcao 'somalinha(...)' que soma elementos em vetor</cyan> for (i=0; i<nl; i++) <verd>printf</verd>("Soma da linha %2d = %3d\n", i, soma_linha(mat1[i], nc)); <cyan>// note que cada linha 'mat1[i]' tem 'nc' elementos uteis</cyan> <cyan>// Agora definindo vetor com tamanho dinamico</cyan> n = 6; vet2 = malloc(sizeof(int) * n); <cyan>// aloca dinamicamente n posicoes para inteiros ('Memory ALLOCation')</cyan> <cyan>// Define vetor com n elementos exatamente</cyan> for (i=0; i<n; i++) *(vet2+i) = 10 + i; <cyan>// Imprime o vetor/lista de uma so' vez (na mesma linha)</cyan> <verd>printf</verd>("\nO vetor definido via alocacao dinamica: "); imprime_vetor1(vet2, n); <cyan>// em C NAO e' possivel imprimir todos os dados de um vetor => fazer uma funcao...</cyan> free(vet2); <cyan>// depois de usar pode-se devolver as posicoes para sistema operacional</cyan> } </pre> </div><!-- class="codigo" --> <p class="autoria"> <a href="https://www.ime.usp.br/~leo" target="_blank" title="seguir para a pagina do prof. Leônidas">Leônidas de Oliveira Brandão</a><br/> <a href="http://www.ime.usp.br/~leo" target="_blank" title="seguir para a página do LInE">http://line.ime.usp.br</a> </p> <p class="rodape"> <b>Alterações</b>:<br/> 2020/10/20: pequenos acertos léxicos e na introdução da seção 3 (ajuda da Priscila Lima), acerto em comentário no código "Exemplo 2" (ajuda do Felipe C. Lourenço)<br/> <!-- Exemplo 2: eliminado 'ord(.)' --> 2020/08/13: novo formato, pequenas revisões<br/> domingo, 17 May 2020, 18:30<br/> segunda, 03 May 2018, 16:00 </p> </div>