introducao_matrizes.html 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. <!--
  2. Introdução à Programação - 2017 - Prof. Leoônidas de Oliveira Brandão
  3. Introdução às matrizes
  4. LInE (Laboratory of Informatics in Education) - http://www.usp.br/line
  5. IME - USP
  6. Material didático
  7. Pode usar livrevemente este material para fins não comerciais, devendo sempre fazer referência à autoria.
  8. Sugestões/apontamento são bem vindos: leo@ime.usp.br (favor indicar no assunto "material de introducao 'a programacao")
  9. Prof. Leônidas de Oliveira Brandão
  10. http://www.ime.usp.br/~leo
  11. http://line.ime.usp.br
  12. http://www.matemtica.br
  13. -->
  14. <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
  15. <meta name='keywords' content='mac0122, material, professores, leonidas de oliveira brandao'>
  16. <link rel='stylesheet' type='text/css' href='css_img_js_conf/all.css'>
  17. <link rel='stylesheet' type='text/css' href='css_img_js_conf/line_introducao_programacao.css'>
  18. <script src="css_img_js_conf/defineLInE.js"></script> <!-- para referencias 'a documentos internos -->
  19. <div class="pagina">
  20. <p class="secao">Introdução às matrizes</p>
  21. <center><p>[
  22. <a href="#sequencia" title="matriz = sequencia contigua de variaveis em memoria">Memória</a> &nbsp; | &nbsp;
  23. <a href="#parametros" title="matriz como parametro de funcao">Parâmetros</a> &nbsp; | &nbsp;
  24. <a href="#vetores" title="linha = um vetor">Vetores</a> &nbsp; | &nbsp;
  25. <a href="#c-python" title="diferencas em C e em Python">C/Python</a> &nbsp; | &nbsp;
  26. <a href="#C" title="matrizes em C">C</a> &nbsp; | &nbsp;
  27. <a href="#Python" title="matrizes em Python">Python</a> &nbsp; &nbsp;
  28. ]</p>
  29. </center>
  30. <p>
  31. Nesta seção examinaremos resumidamente como utilizar matrizes tanto em <em>C</em> quanto em <em>Python</em>.
  32. </p>
  33. <p>
  34. Da mesma forma que o conceito de <i>vetor</i> é útil quando necessita-se de uma grande quantidade de valores
  35. associados, todos eles, a um mesmo tipo de dado (como as várias notas de determinado aluno),
  36. o conceito de <b style="color:#0000aa;">matriz</b> é útil quando naturalmente os dados considerados apresentam
  37. duas dimensões.
  38. Um exemplo é quando precisamos processar dados de um grupo de indivíduos (e.g. alunos), cada um deles com várias
  39. medidas (e.g. notas - vide figura 1).
  40. </p>
  41. <p>
  42. Também vale a pena destacar que, tanto em <em>C</em> quanto em <em>Python</em>, a implementação de matriz é
  43. feita por meio de vetor de vetores.
  44. Desse modelo, em ambas pode-se tratar cada linha como um vetor.
  45. Por exemplo, se a matriz recebe o nome de <tt>M</tt>, então <tt>M[0]</tt> é sua primeira linha,
  46. <tt>M[1]</tt> a segunda linha e assim por diante.
  47. Se for necessário pegar um elemento específico da matriz, deve-se usar dois colcetes, como em
  48. <tt>M[i][j]</tt>, que devolve o valor da linha <i>i</i> na coluna <i>j</i>
  49. (e.g. <tt>M[0][0]</tt> devolve o valor da primeira posição da matriz e <tt>M[1][0]</tt> devolve o valor do
  50. primeiro elemento sua segunda linha).
  51. </p>
  52. <a name="sequencia">
  53. <p class="secao">Matrizes: sequência contígua de variáveis</p>
  54. </a>
  55. <p>
  56. Do ponto de vista computacional a implementação de matrizes segue o princípio dos <i>vetores</i>, uma <i>matriz</i> ocupa
  57. uma porção contígua da memória do computador, servindo para representar o conceito matemático associado.
  58. Lembrando que ao representar um <i>vetor</i> o acesso ao elemento da posição <i>i</i> pode ser feito por meio da sintaxe
  59. <i>vet[i]</i>, no caso de <i>matriz</i> é necessário indicar em qual linha <i>i</i> e em qual coluna <i>j</i> o elemento está,
  60. por exemplo, se a variável tem por nome <i>Mat</i>, usaria <i>Mat[i][j]</i>.
  61. </p>
  62. <p>
  63. Este tipo de estrutura de dados é natural quando os dados apresentam 2 atributos. Por exemplo, em uma sala de aula,
  64. o professor precisa manter informações dos resultados obtidos pelos alunos em várias atividades, assim pode-se utilizar uma
  65. matriz para representar estes dados: as atividades de cada aluno estão em uma única linha da matriz <i>Mat</i>
  66. (e.g., <i>Mat[i][0]</i> é o resultado da atividade <i>0</i> para o aluno <i>i</i>).
  67. </p>
  68. <center>
  69. <img src="img/int_mat_representacao.png" title="ilustracao de matriz em memoria"/>
  70. <br/>
  71. <i>Fig. 1. Ilustração de como uma matriz é representada na "memória" do computador.</i>
  72. </center>
  73. <p>
  74. Mas como é possível implementar computacionalmente esse tipo de estrutura?
  75. Na figura acima está representado uma matriz conceitual, com a ideia de alunos e notas, e à direita como estes dados estão
  76. na memória do computador, supondo-se M+1 alunos e N+1 atividades.
  77. Se na representação computacional, o nome da matriz for <i>Mat</i>, então os dados correspondentes ao
  78. <i>aluno 0</i> são: <i>Mat[0][1]</i>, <i>Mat[0][1]</i> e assim por diante até o <i>Mat[0][N]</i>.
  79. </p>
  80. <a name="parametros">
  81. <p class="subsecao">Matrizes: como parâmetro de função</p>
  82. </a>
  83. <p>
  84. Do mesmo modo que vetores, ao passar uma matriz como parâmetro de uma função, este funcionará como <b>parâmetro por referência</b>
  85. (ou por <b>endereço</b>). Ou seja, é passada uma referência ao <i>parâmetro efetivo</i> (em que chamou a função)
  86. de modo que qualquer alteração dentro da função, no <i>parâmetro formal</i>, significará que o valor na matriz
  87. que foi passada como parämetro (no local que chamou a função e portanto o <i>parâmetro efetivo</i>) será alterado.
  88. </p>
  89. <p>
  90. Tanto em <em>C</em> quanto em <em>Python</em> as matrizes (e vetores) são passados por referência. O exemplo abaixo ilustra
  91. que alterar os dados de uma matriz dentro de uma função implica em alterar a matriz que lhe foi passada (parâmetro efetivo).
  92. </p>
  93. <p><center>
  94. <i>Tab. 1. Matrizes passadas via parâmetro para funções (equivale à uma referência à uma matriz "externa").</i>
  95. <br/>
  96. <table class="tbCodeLinCol">
  97. <tr><th colspan="3">Função com computa soma de 2 matrizes em <i>C</i> e em <i>Python</i> </th> </tr>
  98. <tr>
  99. <th>Exemplo em <i>C</i></th>
  100. <th>Exemplo em <i>Python</i></th>
  101. </tr>
  102. <tr valign="top"><td><table class="tbCode">
  103. <tr><td><pre><incl1>#include</incl1> &lt;stdio.h&gt;
  104. <def>#define</def> NL 20 <cyan>// constante para maximo de linhas</cyan>
  105. <def>#define</def> NC 20 <cyan>// constante para maximo de colunas</cyan>
  106. <cyan>// Funcao para gerar nova matriz MA + MB</cyan>
  107. <tt class="tipo">void</tt> somaMat (<verm>int</verm> MA[][NC], <verm>int</verm> MB[][NC], <verm>int</verm> MC[][NC], <verm>int</verm> nL, <verm>int</verm> nC) {
  108. <verm>int</verm> i, j; <cyan>// auxiliar, para indexar os matrizes</cyan>
  109. <azul>for</azul> (i=0; i&lt; nL; i++) <cyan>// "Ler" nL x nC valores </cyan>
  110. <azul>for</azul> (j=0; j&lt; nC; j++) <cyan>// inteiros armazenando-os</cyan>
  111. MC[i][j] = MA[i][j] + MB[i][j];
  112. }
  113. <cyan>// Funcao para entrar matriz nL x nC, linha por linha</cyan>
  114. <tt class="tipo">void</tt> lerMatriz (<verm>int</verm> mat[][NC], <verm>int</verm> nL, <verm>int</verm> nC) {
  115. <verm>int</verm> i,j; <cyan>// declara indices</cyan>
  116. <azul>for</azul> (i=0; i&lt;nL; i++) <cyan>// i entre 0 e nL-1</cyan>
  117. <azul>for</azul> (j=0; j&lt;nC; j++) <cyan>// j entre 0 e nC-1</cyan>
  118. <tt class="fnc">scanf</tt>("%d", &mat[i][j]);
  119. }
  120. <cyan>// Funcao para imprimir matriz nL x nC, linha por linha</cyan>
  121. <tt class="tipo">void</tt> imprimeMatriz (<verm>int</verm> mat[][NC], <verm>int</verm> nL, <verm>int</verm> nC) {
  122. <verm>int</verm> i,j; <cyan>// declara indices</cyan>
  123. <azul>for</azul> (i=0; i&lt; nL; i++) { <cyan>// i entre 0 e nL-1</cyan>
  124. <verm>printf</verm>("%2d: ", i); <cyan>// "Imprime" numero desta linha</cyan>
  125. <azul>for</azul> (j=0; j&lt; nC; j++) <cyan>// j entre 0 e nC-1</cyan>
  126. <verm>printf</verm>("%3d ", mat[i][j]); <cyan>// em 3 espacos</cyan>
  127. <verm>printf</verm>("\n"); <cyan>// Mude de linha</cyan>
  128. }
  129. }
  130. <verm>int</verm> main (void) {
  131. <verm>int</verm> i, j; <cyan>// auxiliar, para indexar os matrizes</cyan>
  132. <verm>int</verm> m, n; <cyan>// tamanho util das matrizes</cyan>
  133. <verm>int</verm> matA[NL][NC], matB[NL][NC], matC[NL][NC]; <cyan>// Matriz para inteiros (ate' NL*NC elementos)</cyan>
  134. <tt class="fnc">scanf</tt>("%d %d", &m, &n);
  135. <verm>printf</verm>("Entra matriz A:\n"); lerMatriz(matA, m, n);
  136. <verm>printf</verm>("Entra matriz B:\n"); lerMatriz(matB, m, n);
  137. <verm>printf</verm>("Gera matriz C:\n"); somaMat(matA, matB, matC, m, n); <cyan>// parametros efetivos</cyan>
  138. <verm>printf</verm>("Matriz A:\n"); imprimeMatriz(matA, m, n); <cyan>// 'matA' e' parametro efetivo</cyan>
  139. <verm>printf</verm>("Matriz B:\n"); imprimeMatriz(matB, m, n); <cyan>// aqui e' 'matB'</cyan>
  140. <verm>printf</verm>("Matriz C:\n"); imprimeMatriz(matC, m, n); <cyan>// aqui e' 'matC'</cyan>
  141. return 0;
  142. }</pre></td>
  143. </table></td>
  144. <td><pre><incl1>from</incl1> __future__ import print_function; <cyan># imprime sem mudar linha Python 2</cyan>
  145. <cyan># Funcao para gerar nova matriz MA + MB</cyan>
  146. <verm>def</verm> somaMat (MA, MB, nL, nC) :
  147. MC = []; <cyan># inicia matriz que sera devolvida</cyan>
  148. linha = []; <cyan># inicia vetor para compor linha de MC</cyan>
  149. <azul>for</azul> i in range(nL) : <cyan># i varia entre 0 e nL-1</cyan>
  150. <azul>for</azul> j in range(nC) : <cyan># j varia entre 0 e nC-1</cyan>
  151. linha.append(MA[i][j] + MB[i][j]); <cyan># novo elemento de "linha"</cyan>
  152. MC.append(linha); <cyan># para conseguir estrutura adequada</cyan>
  153. return MC;
  154. <cyan># Funcao para entrar matriz nL x nC, linha por linha</tt>
  155. <verm>def</verm> lerMatriz (mat, nL, nC) :
  156. <azul>for</azul> i in range(nL) :
  157. linha = [];
  158. <azul>for</azul> j in range(nC) :
  159. linha.append(<tt class="fnc">input</tt>());
  160. mat.append(linha);
  161. <cyan># Funcao para imprimir matriz nL x nC, linha por linha</cyan>
  162. <verm>def</verm> imprimeMatriz (mat, nL, nC) :
  163. <azul>for</azul> i in range(0, nL) : <cyan># i entre 0 e nL-1</cyan>
  164. <verm>print</verm>("%2d: " % i, end=""); <cyan># "Imprime" numero desta linha</cyan>
  165. <azul>for</azul> j in range(0, nC) :
  166. <verm>print</verm>("%3d " % mat[i][j], end=""); <cyan># em 3 espacos</cyan>
  167. <verm>print</verm>(); <cyan># Mude de linha</cyan>
  168. <verm>def</verm> main () :
  169. matA = [];
  170. matB = [];
  171. linha = <tt class="fnc">raw_input</tt>(); <cyan># ler linha em Python 2 (no 3 usar apenas "input()")</cyan>
  172. m, n = map(int, linha.split()); <cyan># quebrar entrada em 2 inteiros</cyan>
  173. <verm>print</verm>("Matriz A:"); lerMatriz(matA, m, n);
  174. <verm>print</verm>("Matriz B:"); lerMatriz(matB, m, n);
  175. matC = somaMat(matA, matB, m, n); <cyan># parametros efetivos</cyan>
  176. <verm>print</verm>("Matriz A:"); imprimeMatriz(matA, m, n); <cyan># 'matA' e' parametro efetivo</cyan>
  177. <verm>print</verm>("Matriz B:"); imprimeMatriz(matB, m, n); <cyan># aqui e' 'matB'</cyan>
  178. <verm>print</verm>("Matriz C:"); imprimeMatriz(matC, m, n); <cyan># aqui e' 'matC'</cyan>
  179. main();</pre></td>
  180. </tr>
  181. </table></td></tr>
  182. </table></center>
  183. </p>
  184. <a name="vetores">
  185. <p class="subsecao">Matrizes: uma linha equivale a um vetor</p>
  186. </a>
  187. <p>
  188. Uma vez que os elementos em uma linha da matriz estão em posições contíguas da memória, eles podem ser
  189. olhados como um vetor, novamente o <i>contexto</i> determina o significado dos dados.
  190. Assim, se tivermos uma função <i>soma_vetor</i> que recebe como parâmetro um vetor (e sua dimensão) e que gera a soma de seus elementos,
  191. pode-se fazer a seguinte chamada: <i>soma_vetor(mat[i],n)</i>, para qualquer <i>i</i> entre <i>0</i> e <i>M</i> do exemplo acima.
  192. </p>
  193. <p>
  194. Desse modo, o exemplo abaixo ilustra uma função preparada para somar elementos de um vetor (<tt>soma += vet[i];</tt>) sendo usada para
  195. somar as linhas de uma matriz.
  196. <!--
  197. Vamos supor que no trecho de código que invoca a função <i>soma_vetor</i>, usa-se como <i>parämetro efetivo</i> a linha <i>k</i>
  198. (nesse caso entre <i>0 <u><</u> k <u><</u> M</i>) da matriz <i>mat</i>.-->
  199. Então, na execução do laço dentro função, o comando usando o <i>parâmetro formal</i> <i>soma</i>, <tt>soma += vet[i]</tt> equivalerá
  200. ao código <tt>soma += mat[k][i];</tt> no trecho que invocou a função <i>soma_vetor</i>.
  201. </p>
  202. <p><center>
  203. <i>Tab. 2. Uma linha de um matriz é na verdade um vetor.</i>
  204. <br/>
  205. <table class="tbCodeLinCol">
  206. <tr><th colspan="3">Função de função para somar elementos de vetor sendo usado com linhas de matrizes em <i>C</i> e em <i>Python</i> </th> </tr>
  207. <tr>
  208. <th>Exemplo em <i>C</i></th>
  209. <th>Exemplo em <i>Python</i></th>
  210. </tr>
  211. <tr valign="top"><td><table class="tbCode">
  212. <tr><td><pre><incl1>#include</incl1> &lt;stdio.h&gt;
  213. ...
  214. <verm>int</verm> soma_vetor (int vet[], int n) {
  215. <verm>int</verm> i, soma = 0;
  216. <azul>for</azul> (i=0; i &lt; n; i++)
  217. soma += vet[i];
  218. return soma;
  219. }
  220. <verm>int</verm> main (void) {
  221. <verm>int</verm> mat[NL][NC]; ...
  222. ...
  223. <verm>print</verm>("soma linha %d : %d\n", i, soma_vetor(mat[i], n));
  224. ...
  225. return 0;
  226. }</pre></td>
  227. </table></td>
  228. <td><pre><incl1>from</incl1> __future__ import print_function; <cyan># imprime sem mudar linha Python 2</cyan>
  229. <verm>def</verm> soma_vetor (vet, n) :
  230. soma = 0;
  231. <azul>for</azul> i in range(n) :
  232. soma += vet[i];
  233. return soma;
  234. <verm>def</verm> main () :
  235. ...
  236. <verm>print</verm>("soma linha %d : %d\n" % (i, soma_vetor(mat[i], n)));
  237. ...
  238. main();</pre></td>
  239. </tr>
  240. </table></td></tr>
  241. </table></center>
  242. </p>
  243. <p class="subsecao">Diferença entre linguagem compilada (<i>C</i>) e linguagem interpretada (<i>Python</i>)</p>
  244. </a>
  245. <p>
  246. Uma grande diferença entre as linguagens <i>C</i> e <i>Python</i> é que a primeira é
  247. <b>compilada</b> enquanto a segunda é <b>interpretada</b>.
  248. </p>
  249. <p>Uma linguagem <b>compilada</b> (como <i>C</i>) implica na existência de um programa (<b>compilador</b>) que traduz o texto do
  250. programa na linguagem referida, gerando um código equivalente em <b>linguagem de máquina</b>. Desse modo, existem dois momentos
  251. muito distintos, o <i>tempo da compilação</i> e o <i>tempo da execução</i>.
  252. Além disso, é preciso que cada "máquina"
  253. (que significa o computador/CPU e o sistema operacional - como o <i>Linux</i>) tenha o compilador para aquela linguagem.
  254. Isso funciona como se traduzir um texto de uma lingua (como Inglês) para outra (como o Português)
  255. </p>
  256. <p>
  257. Em uma linguagem <b>interpretada</b> (como <i>Python</i>), existe um
  258. programa executável (para a máquina específica em que roda), que é o <b>interpretador</b> para a linguagem específica
  259. (e.g. <i>Python</i>).
  260. Assim, a tradução e a execução é feita praticamente ao mesmo tempo,
  261. como em uma tradução simultänea de uma conferência em Inglës para o Português.
  262. </p>
  263. <p>
  264. Outra diferença grande entre <i>C</i> e <i>Python</i> é que a primeira é muito mais "estável", sua definição não sofre
  265. alterações há anos, enquanto a segunda está em constante mudança.
  266. Por outro lado, os interpretadores <i>Python</i>, em geral, apresentam uma vasta gama de pacotes integrados,
  267. trazendo muitos recursos préviamente programadas, facilitando a "vida do programador"
  268. (e dificultando a dos professores que precisam ficar vetando recursos para poder fazer os aprendizes entenderem que
  269. tudo foi programada e poderem entender como o básico...).
  270. <br/>
  271. Um bom exemplo são os pacotes para tratamento do protocolo <i>HTTP</i>.
  272. Existem também para <i>C</i> pacotes livres para fazer implementações para serviços <i>Web</i> (usando <i>HTTP</i>), mas
  273. geralmente eles não estão integrados aos compiladores.
  274. </p>
  275. <a name="C">
  276. <p class="subsecao">Matrizes em <i>C</i></p>
  277. </a>
  278. <p>
  279. Como em <i>C</i> deve-se sempre declarar o tipo da variável, no caso de matriz deve-se declarar seu tipo e seu tamanho.
  280. No exemplo abaixo ilustramos as declarações e uso de matrizes dos tipos básicos <i>int</i>, <i>char</i> e <i>float</i>.
  281. </p>
  282. <p><center>
  283. <i>Tab. 3. Exemplos de tratamento de matrizes em <i>C</i> (com inteiros, caracteres e "flutuantes").</i>
  284. <br/>
  285. <table class="tbCodeLinCol">
  286. <tr><th colspan="3">Matrizes em <i>C</i> </th> </tr>
  287. <tr>
  288. <th>Matriz de inteiros</th>
  289. <th>Matriz de caracteres</th>
  290. <th>Matriz de flutuantes</th></tr>
  291. <tr valign="top"><td><table class="tbCode">
  292. <tr><td><pre><incl1>#include</incl1> &lt;stdio.h&gt;
  293. <def>#define</def> NL 20 <cyan>// constante para maximo de linhas</cyan>
  294. <def>#define</def> NC 20 <cyan>// constante para maximo de colunas</cyan>
  295. <verm>int</verm> main (void) {
  296. <verm>int</verm> i, j; <cyan>// auxiliar, para indexar os matrizes</cyan>
  297. <verm>int</verm> nL, nC; <cyan>// tamanho util das matrizes</cyan>
  298. <verm>int</verm> mat[NL][NC]; <cyan>// Matriz para inteiros (ate' NL*NC elementos)</cyan>
  299. <tt class="fnc">scanf</tt>("%d %d", &nL, &nC);
  300. <azul>for</azul> (i=0; i&lt; nL; i++) <cyan>// "Ler" nL x nC valores </cyan>
  301. <azul>for</azul> (j=0; j&lt; nC; j++) <cyan>// inteiros armazenando-os</cyan>
  302. <tt class="fnc">scanf</tt>("%d", &mat[i][j]); <cyan>// na matriz</cyan>
  303. <azul>for</azul> (i=0; i&lt; nL; i++) { <cyan>// "Imprimir" os nL x nC</cyan>
  304. <verm>printf</verm>("%2d: ", i); <cyan>// "Imprime" numero desta linha</cyan>
  305. <azul>for</azul> (j=0; j&lt; nL; j++) <cyan>// valores inteiros, ajustando</cyan>
  306. <verm>printf</verm>("%3d ", mat[i][j]); <cyan>// em 3 espacos</cyan>
  307. <verm>printf</verm>("\n"); <cyan>// Mude de linha</cyan>
  308. }
  309. return 0;
  310. }</pre></td>
  311. </table></td>
  312. <td><pre><incl1>#include</incl1> &lt;stdio.h&gt;
  313. <def>#define</def> NL 20 <cyan>// constante para maximo de linhas</cyan>
  314. <def>#define</def> NC 20 <cyan>// constante para maximo de colunas</cyan>
  315. <verm>int</verm> main (void) {
  316. <verm>int</verm> i, j; <cyan>// auxiliar, para indexar os matrizes</cyan>
  317. <verm>int</verm> nL, nC; <cyan>// tamanho util dos matrizes</cyan>
  318. char matC[NL][NC]; <cyan>// Matriz para caracteres</cyan>
  319. <tt class="fnc">scanf</tt>("%d %d", &nL, &nC);
  320. <azul>for</azul> (i=0; i&lt; nL; i++) <cyan>// "Ler" nL x nC valores</cyan>
  321. <azul>for</azul> (j=0; j&lt; nC; j++) <cyan>// tipo "char" armazenando-os</cyan>
  322. <tt class="fnc">scanf</tt>("%c", &matC[i][j]); <cyan>// na matriz</cyan>
  323. <azul>for</azul> (i=0; i&lt; nL; i++) { <cyan>// "Imprimir" os nL x nC</cyan>
  324. <verm>printf</verm>("%2d: ", i); <cyan>// "Imprime" numero desta linha</cyan>
  325. <azul>for</azul> (j=0; j&lt; nC; j++) <cyan>// valores tipo "char",</cyan>
  326. <verm>printf</verm>("%2c", matC[i][j]); <cyan>// ajustando em 2 espacos</cyan>
  327. <verm>printf</verm>("\n"); <cyan>// Mude de linha</cyan>
  328. }
  329. return 0;
  330. }</pre></td>
  331. <td><pre><incl1>#include</incl1> &lt;stdio.h&gt;
  332. <def>#define</def> M 20 <cyan>// usado para constante</cyan>
  333. <verm>int</verm> main (void) {
  334. <verm>int</verm> i, j; <cyan>// auxiliar, para indexar os matrizes</cyan>
  335. <verm>int</verm> nL, nC; <cyan>// tamanho util dos matrizes</cyan>
  336. float matF[NL][NC]; <cyan>// Matriz para caracteres</cyan>
  337. <tt class="fnc">scanf</tt>("%d %d", &nL, &nC);
  338. <azul>for</azul> (i=0; i&lt; nL; i++) <cyan>// "Ler" nL x nC valores </cyan>
  339. <azul>for</azul> (j=0; j&lt; nC; j++) <cyan>// tipo "char" armazenando-os</cyan>
  340. <tt class="fnc">scanf</tt>("%f", &matF[i][j]); <cyan>// na matriz</cyan>
  341. <azul>for</azul> (i=0; i&lt; nL; i++) { <cyan>// "Imprimir" os nL x nC</cyan>
  342. <verm>printf</verm>("%2d: ", i); <cyan>// "Imprime" numero desta linha</cyan>
  343. <azul>for</azul> (j=0; j&lt; nC; j++) <cyan>// valores tipo "float",</cyan>
  344. <verm>printf</verm>("%5.1f", matF[i][j]); <cyan>// usando 5 esp. e 1 dec.</cyan>
  345. <verm>printf</verm>("\n"); <cyan>// Mude de linha</cyan>
  346. }
  347. return 0;
  348. }</pre></td></tr>
  349. </table></td></tr>
  350. </table></center>
  351. </p>
  352. <p>
  353. No <i>C</i> padrão NÃO é possível declarar as dimensões da matriz usando a variável que será usada para
  354. informar o número efetivo de posições "úteis" na matriz, ou seja, <b>não</b> tente fazer algo como:
  355. <tt><font color="#a000">int m, n; float mat[m][n];</font></tt>.
  356. A razão disso é que <i>C</i>, por ser uma linguagem compilada, durante a <b>fase de compilação</b> deve-se reservar o
  357. espaço máximo a ser usado pelo matriz.
  358. Já as variáveis <tt>m</tt> e <tt>n</tt> só serão conhecidas durante a <b>execução</b> do programa.
  359. </p>
  360. <p>
  361. Apesar de algumas implementações de compiladores <i>C</i> permitirem esse tipo de declarção "dinâmica",
  362. NÃO usem sob pena de seu programa não funcionar em outros compiladores.
  363. </p>
  364. <p>
  365. Vejamos o exemplo da função <i>soma_vetor</i> sendo chamada com cada linha de uma matriz, com código completo em <i>C</i>.
  366. <div class="codigo"><pre><cyan>// Exemplo de matriz em Python passando linha em funcao que trabalha com vetor</cyan>
  367. <incl1>#include</incl1> &lt;stdio.h&gt;
  368. <def>#define</def> MAXL 20 <cyan>// usar no maximo 20 linhas</cyan>
  369. <def>#define</def> MAXC 20 <cyan>// usar no maximo 20 colunas</cyan>
  370. <verm>int</verm> soma_vet (<verm>int</verm> vet[], <verm>int</verm> n) {
  371. <verm>int</verm> soma = 0, i;
  372. <azul>for</azul> (i=0; i&lt;n; i++)
  373. soma += vet[i];
  374. return soma;
  375. }
  376. <verm>int</verm> main (void) {
  377. <verm>int</verm> mat[MAXL][MAXC]; <cyan>// declara que existira uma matriz (vetor de vetor)</cyan>
  378. <verm>int</verm> i, j, m = 3, n = 4; <cyan>// dimensoes fixas por simplicidade</cyan>
  379. <azul>for</azul> (i=0; i&lt;m; i++) {
  380. <azul>for</azul> (j=0; j&lt;n; j++) {
  381. mat[i][j] = i*n + j; <cyan>// como ja' existe espaco reservado atribua "i*m + j" para a posicao linha i e coluna j</cyan>
  382. <verm>printf</verm>(" %3d", mat[i][j]); <cyan>// imprime sem mudar de linha</cyan>
  383. }
  384. <verm>printf</verm>("\n"); <cyan>// muda de linha</cyan>
  385. }
  386. <verm>printf</verm>("Imprime somas das linhas\n");
  387. <azul>for</azul> (i=0; i&lt;m; i++)
  388. <verm>printf</verm>("Linha %d tem soma: %3d\n", i, soma_vet(mat[i], n)); <cyan>// %3d ajusta 3 casas 'a direita</cyan>
  389. return 1;
  390. }
  391. </pre></div>
  392. </p>
  393. <a name="Python">
  394. <p class="subsecao">Matrizes em <i>Python</i></p>
  395. </a>
  396. <p>
  397. Em <i>Python</i> pode-se gerar listas de variadas maneiras, a forma sugerida abaixo é gerar uma lista de listas,
  398. sendo que a segunda lista será uma linha da matriz. No código abaixo ilustramos isso.
  399. </p>
  400. <p class="subsecao">A linha de uma matriz é na verdade um vetor</p>
  401. <p>
  402. O exemplo abaixo ilustra a declaração e uso de matrizes, ccom os tipos básicos <i>int</i>, <i>char</i> e <i>float</i>.
  403. </p>
  404. <p><center>
  405. <i>Tab. 4. Exemplos de tratamento de matrizes em <i>Python</i> (com inteiros, caracteres e "flutuantes").</i>
  406. <br/>
  407. <table class="tbCodeLinCol">
  408. <tr><th colspan="3">Matrizes em <i>Python</i> </th> </tr>
  409. <tr>
  410. <th>Matriz de inteiros</th>
  411. <th>Matriz de caracteres</th>
  412. <th>Matriz de flutuantes</th></tr>
  413. <tr valign="top"><td><table class="tbCode">
  414. <tr><td><pre><verm>def</verm> main () :
  415. nL = int(<tt class="fnc">input</tt>()); nC = int(<tt class="fnc">input</tt>()); <cyan># "Ler" dimensoes nL, nc</cyan>
  416. mat = []; <cyan># Matriz: iniciar uma lista vazia</cyan>
  417. <azul>for</azul> i in range(0, nL) :
  418. linha = []; <cyan># iniciar lista vazia para a linha atual</cyan>
  419. <azul>for</azul> j in range(0, nC) : <cyan># ler nI inteiros</cyan>
  420. linha.append(int(<tt class="fnc">input</tt>())); # anexar mais um elemento</cyan>
  421. mat.append(linha); <cyan># anexar a linha `a matriz</cyan>
  422. <cyan># Em Python para imprimir de modo mais "bonito" a matriz,</cyan>
  423. <cyan># pode-se fazer impressao dos elementos da linha sem "quebre",</cyan>
  424. <cyan># ou compondo uma "string". Neste exemplo usamos o segundo "truque".</cyan>
  425. <azul>for</azul> i in range(0, nL) :
  426. strLinha = ""; <cyan># Truque: compor um "string" com a linha i toda</cyan>
  427. <azul>for</azul> j in range(0, nC) :
  428. strLinha += "%3i" % mat[i][j]; <cyan># formatar ajustando 3 pos.</cyan>
  429. <verm>print</verm>("%2i: " % i + strLinha); <cyan># "Imprimir" a linha i</cyan>
  430. main();</pre></td>
  431. </table></td>
  432. <td><pre><verm>def</verm> main () :
  433. nL = int(<tt class="fnc">input</tt>()); nC = int(<tt class="fnc">input</tt>()); <cyan># "Ler" dimensoes nL, nc</cyan>
  434. mat = []; <cyan># Matriz: iniciar uma lista vazia</cyan>
  435. <azul>for</azul> i in range(0, nL) :
  436. linha = []; <cyan># iniciar lista vazia para a linha atual</cyan>
  437. <azul>for</azul> j in range(0, nC) : <cyan># ler nI inteiros</cyan>
  438. linha.append(<tt class="fnc">raw_input</tt>()); <cyan># anexar mais um elemento</cyan>
  439. mat.append(linha); # anexar a matriz a linha</cyan>
  440. <cyan># Nesse exemplo imprimimos usando a biblioteca "print_function"</cyan>
  441. <cyan># para nao "quebrar" linha entre 2 impressoes.</cyan>
  442. <azul>for</azul> i in range(0, nL) :
  443. <verm>print</verm>("%2i: " % i, end=""); <cyan># parametro "end" impede a quebra</cyan>
  444. <azul>for</azul> j in range(0, nC) :
  445. <verm>print</verm>("%4c" % mat[i][j], end="");
  446. <verm>print</verm>(); <cyan># agora "quebre" a linha (final linha i)!</cyan>
  447. main();</pre></td>
  448. <td><pre><verm>def</verm> main () :
  449. nL = int(<tt class="fnc">input</tt>()); nC = int(<tt class="fnc">input</tt>()); <cyan># "Ler" dimensoes nL, nc</cyan>
  450. mat = []; <cyan># Matriz: iniciar uma lista vazia</cyan>
  451. <azul>for</azul> i in range(0, nL) :
  452. linha = []; <cyan># iniciar lista vazia para a linha atual</cyan>
  453. <azul>for</azul> j in range(0, nC) : <cyan># ler nI inteiros</cyan>
  454. linha.append(float(<tt class="fnc">input</tt>())); <cyan># anexar mais um elemento</cyan>
  455. mat.append(linha); <cyan># anexar a matriz a linha</cyan>
  456. <cyan># Neste exemplo usamos novamente o "truque" de usar</cyan>
  457. <cyan># "string" para imprimir cada linha da matriz</cyan>
  458. <azul>for</azul> i in range(0, nL) :
  459. strLinha = ""; <cyan># Truque para imprimir "por linha"</cyan>
  460. <azul>for</azul> j in range(0, nC) :
  461. strLinha += "%5.1f" % mat[i][j]; <cyan># usar 5 espacos, 1 pto dec.</cyan>
  462. <verm>print</verm>("%2i: " % i + strLinha); <cyan># "Imprimir" esta linhalinha = [];</cyan>
  463. main();</pre></td>
  464. </tr>
  465. </table></td></tr>
  466. </table></center>
  467. </p>
  468. <p>
  469. No segundo exemplo acima, utilizamos recurso da biblioteca <tt>print_function</tt>, assim
  470. no <i>Python 2</i> é obrigatório incluir esta biblioteca, como indicado nas primeiras linhas
  471. do exemplo abaixo. No caso do <i>Python 3</i> a inclusão é desnecessária.
  472. </p>
  473. <p>
  474. O exemplo abaixo ilustra outro conceito importante: cada linha da matriz comporta-se como lista e portanto
  475. pode-se aplicar sobre cada linha da matriz, qualquer função que tenha como parâmetro formal uma lista.
  476. O exemplo será aquele da função <i>soma_vetor</i>, que soma os elementos de um vetor.
  477. <div class="codigo"><pre><cyan># Exemplo de matriz em Python passando linha em funcao que trabalha com vetor</cyan>
  478. <cyan># Python2 para 'print' sem pular linha : print("*" , end = "");</cyan>
  479. <incl1>from</incl1> __future__ import print_function
  480. <verm>def</verm> soma_vet (vet, n) :
  481. soma = 0;
  482. <azul>for</azul> i in range(0,n) :
  483. soma += vet[i];
  484. return soma;
  485. mat = []; <cyan># declara que existira uma "lista" (que sera' lista de lista - ou vetor de vetor)</cyan>
  486. m = 3; n = 4; <cyan># dimensoes fixas por simplicidade</cyan>
  487. <azul>for</azul> i in range(0,m) :
  488. linha = []; <cyan># declara um "lista" (ou vetor) que sera' um linha da matriz 'mat[][]'</cyan>
  489. <azul>for</azul> j in range(0,n) :
  490. linha.append(i*n + j); <cyan># equivale a fazer "mat[i][j] = i*m + j" (mas assim resulta erro em Python)</cyan>
  491. <verm>print</verm>(" %3d" % linha[j], end=""); <cyan># imprime sem mudar de linha</cyan>
  492. <verm>print</verm>(); <cyan># muda de linha</cyan>
  493. mat.append(linha); <cyan># define a linha i da matriz (algo como mat[i] = linha)</cyan>
  494. <verm>print</verm>("Imprime somas das linhas");
  495. <azul>for</azul> i in range(0,m) :
  496. <verm>print</verm>("Linha %d tem soma: %3d" % (i, soma_vet(mat[i], n))); <cyan># %3d ajusta 3 casas 'a direita</cyan></pre>
  497. </div>
  498. </p>
  499. <p>
  500. Muita atenção ao método usado para construir a matriz, usando uma
  501. lista auxiliar <tt>linha</tt> e a necessidade de anexar cada linha separadamente (<tt>mat.append(linha);</tt>.
  502. Se isso não está suficientemente claro, sugiro que peguem
  503. <a href="codigos/introducao_matrizes_teste_linhas.py" title="exemplo ilustrativo de construcao de matriz">este exemplo</a>
  504. e "brinquem" com ele, até entendê-lo bem.
  505. </p>
  506. <p>
  507. Bem, em resumo é isso.</p>
  508. <p class="autoria">
  509. <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/>
  510. <a href="http://www.ime.usp.br/~leo" target="_blank" title="seguir para a página do LInE">http://line.ime.usp.br</a>
  511. </p>
  512. <p class="rodape">
  513. <b>Alterações</b>:<br/>
  514. 2020/08/15: novo formato, pequenas revisões<br/>
  515. 2020/05/18: inserido um código <i>Python</i> explicando como criar matrizes.<br/>
  516. 2019/06/06: vários pequenos acertos ao longo do texto.
  517. <!-- 201?/??/??: primeira versão. -->
  518. </p>
  519. </div>