<!--
 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> &nbsp; | &nbsp;
  <a href="#memoria" title=""></a> &nbsp; &nbsp;
 ]</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> &lt;stdio.h&gt;
// 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&lt;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&lt;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> &lt;stdio.h&gt;
<incl1>#include</incl1> &lt;string.h&gt; <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&lt;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> &lt;stdio.h&gt;
<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&lt;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>
  &nbsp; <verm>int</verm> vet1[5], i; <cyan>// no lugar de linha 1 da main</cyan><br/>
  &nbsp; apont = vet1; <cyan>// ou apont = &vet1; ou apont = &vet1[0];</cyan><br/>
  &nbsp; for (i=0; i&lt;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> &lt;stdio.h&gt;

<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&lt;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&lt;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&lt;nl; i++)    <cyan>// foram alocados na memoria MAXL*MAXC</cyan>
    for (j=0; j&lt;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&lt;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> &lt;stdio.h&gt;
<incl1>#include</incl1> &lt;stdlib.h&gt; <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&lt;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&lt;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&lt;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&lt;nl; i++)
    for (j=0; j&lt;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&lt;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&lt;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>