123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- <!--
- 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>
|