XXIV Curso de Especialização em Teleinformática e Redes de Computadores www.teleinfo.ct.utfpr.edu.br TEL45 - Linguagem C e MATLAB C parte 1 abr.2014 Prof. Gustavo B. Borba/Prof. Humberto R. Gamba Para quem pretende programar ou atua na área técnica ◦ :-) Para quem não pretende programar ◦ Entender melhor o mundo: computadores estão em todos os lugares e precisam de programas. ◦ Raciocinar para resolver problemas: análise e síntese. Para passar instruções precisas ao computador (programa), é necessário ter uma idéia muito clara de como resolver o problema. 2 Alto nível “Some estes dois números” Linguagens diferentes 01001100101... Baixo nível 3 4 5 6 • Native compiler • Cross-compiler Stephen Prata, C Primer Plus, 5th Ed. 7 1. Sintaxe pelo menos até o ponto em que o compilador não reclama mais... 2. Significado que o compilador atribui àquilo que você escreve. 3. Estilo adequado para a liguagem. É a “arte” de escrever programas claros e eficientes. 8 Analogia ◦ Um prédio com a infra-estrutura pronta: portas, janelas, instalação elétrica, escritório com linhas de telefone. ◦ Este prédio pode ser equipado para torna-se uma fábrica de parafusos ou de sorvete. IDE Meu projeto Exemplos - Borland Builder - Microsoft Visual Studio - Qt - Dev C++ - Code::Blocks 9 Stephen Prata, C Primer Plus, 5th Ed. 10 #include <stdio.h> int main(void) { int num; num = 1; /* um programinha */ /* define uma variável num */ /* atribui um valor para num */ printf(“Eu sou um "); /* chama a função printf() */ printf("computador.\n"); printf(“Gosto do %d porque é o primeiro.\n",num); return 0; } #include <stdio.h> # indica que a linha é tratada pelo pré-processador. include é uma diretiva para o pré-processador. stdio.h é um header file ANSI-C. É necessário para usar a função printf( ) e as outras funções que estão nesta biblioteca. Pq já não é incluído automaticamente? Stephen Prata, C Primer Plus, 5th Ed. 11 #include <stdio.h> int main(void) { int num; num = 1; /* um programinha */ /* define uma variável num */ /* atribui um valor para num */ printf(“Eu sou um "); /* chama a função printf() */ printf("computador.\n"); printf(“Gosto do %d porque é o primeiro.\n",num); return 0; } int main(void) É a função principal. Funções são os blocos básicos de um programa C. Um programa C sempre inicia executando a função chamada main( ). int é o tipo de dado que main( ) retorna. void indica que a função main( ) não recebe nenhuma informação. Stephen Prata, C Primer Plus, 5th Ed. 12 #include <stdio.h> int main(void) { int num; num = 1; /* um programinha */ /* define uma variável num */ /* atribui um valor para num */ printf(“Eu sou um "); /* chama a função printf() */ printf("computador.\n"); printf(“Gosto do %d porque é o primeiro.\n",num); return 0; } int main(void) { ... } As chaves delimitam a função. { início da função } fim da função /*comentário*/ //comentário Stephen Prata, C Primer Plus, 5th Ed. 13 #include <stdio.h> int main(void) { int num; num = 1; /* um programinha */ /* define uma variável num */ /* atribui um valor para num */ printf(“Eu sou um "); /* chama a função printf() */ printf("computador.\n"); printf(“Gosto do %d porque é o primeiro.\n",num); return 0; } int num; É uma declaração. Declara que: 1) nesta função há uma variável chamada num. 2) num é uma variável do tipo int. int é um exemplo de tipo de dado. Stephen Prata, C Primer Plus, 5th Ed. 14 #include <stdio.h> int main(void) { int num; num = 1; /* um programinha */ /* define uma variável num */ /* atribui um valor para num */ printf(“Eu sou um "); /* chama a função printf() */ printf("computador.\n"); printf(“Gosto do %d porque é o primeiro.\n",num); return 0; } num = 1; É uma atribuição. A declaração int num; reserva espaço na memória para a variável num. A atribuição num = 1; armazena o valor 1 neste espaço de memória. = é um operador de atribuição. Stephen Prata, C Primer Plus, 5th Ed. 15 printf(“Eu sou um "); printf(); Os parênteses indicam que printf é o nome de uma função. O que está dentro dos parênteses é a informação recebida pela função. Isto é chamado de argumento da função. printf( ) escreve na tela o que está entre as aspas. Para chamar ou invocar uma função: Colocar o nome da função e os argumentos desejados dentro dos parênteses. Stephen Prata, C Primer Plus, 5th Ed. 16 printf("computador.\n"); \n é o caractere newline. \n é um exemplo de uma escape sequence. Serve para representar caracteres difíceis ou impossíveis de digitar no programa. Exemplos: \t tabulação \\ barra invertida \’ apóstrofo \” aspas Stephen Prata, C Primer Plus, 5th Ed. 17 printf("Gosto do %d porque é o primeiro.\n", num); %d é um placeholder para indicar onde o conteúdo de num deve ser impresso. % indica que uma variável será impressa d indica que esta variável deve ser impressa no formato decimal inteiro. Exemplos: %c caractere %s string %f decimal com ponto flutuante Stephen Prata, C Primer Plus, 5th Ed. 18 #include <stdio.h> int main(void) { int num; num = 1; /* um programinha */ /* define uma variável num */ /* atribui um valor para num */ printf(“Eu sou um "); /* chama a função printf() */ printf("computador.\n"); printf(“Gosto do %d porque é o primeiro.\n",num); return 0; } O que este programa faz é somente escrever na tela: Eu sou um computador. Gosto do 1 porque é o primeiro. Stephen Prata, C Primer Plus, 5th Ed. 19 #include <stdio.h> int main(void) { int num; num = 1; /* um programinha */ /* define uma variável num */ /* atribui um valor para num */ printf(“Eu sou um "); /* chama a função printf() */ printf("computador.\n"); printf(“Gosto do %d porque é o primeiro.\n",num); return 0; } return 0 É o valor que a função retorna. O int em int main(void) significa que main( ) retorna um inteiro. Stephen Prata, C Primer Plus, 5th Ed. 20 #include <stdio.h> int main(void) { int num; num = 1; /* um programinha */ /* define uma variável num */ /* atribui um valor para num */ printf(“Eu sou um "); /* chama a função printf() */ printf("computador.\n"); printf(“Gosto do %d porque é o primeiro.\n",num); return 0; } Implementar e executar. Ver arquivo TEL45_Slides_IDEcb.pdf Stephen Prata, C Primer Plus, 5th Ed. 21 São os nomes usados para fazer referência a variáveis e funções. • o primeiro caractere deve ser letra ou sublinhado; • deve ser sempre menor que 32 caracteres; • letras maiúsculas e minúsculas são diferenciadas (case-sensitive); • pode-se misturar letras maiúsculas e minúsculas; • não é permitido o uso de espaços ou outros caracteres especiais. Exemplos: válido qqr temp2 eixo_y coefRend inválido $z]* 2temp eixo-y coef rend O compilador utiliza o sublinhado na frente de variáveis especiais, portanto evita-se iniciar o nome de variáveis com sublinhado. 22 Tipo char unsigned int unsigned short unsigned long unsigned float double Tamanho em Bytes char int short long 1 1 4 4 2 2 4 4 4 8 Faixa de valores -128 a 127 0 a 255 -2.147.483.648 a 2.147.483.647 0 a 4.294.967.295 -32.768 a 32.767 0 a 65.535 -2.147.483.648 a 2.147.483.647 0 a 4.294.967.295 1.2E-38 a 3.4E+38 2.2E-308 a 1.8E+308 23 tipo nome_da_variável = constante; Exemplos: Single quote ‘ ’ usado para atribuir um caractere a uma variável char Double quotes “ ” usado para atribuir um string a um char do tipo array char ch = ‘a’ ; int x = 67 ; float valor = 45.896 ; int i , j = 89 , k = m = 8 ; char s1 , s2 = ‘a’ , g ; Seqüência de caracteres char txt[ ] = “Isto é um string” ; float a=b=c=45.78 , pi = 3.1416 ; 24 printf() Caractere de Como o argumento correspondente é impresso conversão %c %d, %i %u %o %x, %X %e, %E %f %g, %G %s %p %n %% como um caractere como um decimal inteiro como um decimal inteiro sem sinal como um inteiro octal sem sinal como um inteiro hexadecimal sem sinal como um decimal com ponto flutuante; ex, 7.123000e+00 como um decimal com ponto flutuante; ex, 7.123000 no formato %e ou %f, dependendo do qual for menor como um string o argumento associado é um ponteiro a um void; o seu valor é impresso como hexadecimal o argumento associado será um ponteiro onde é colocado o número de caracteres escritos até o momento com o formato %%, o símbolo % é impresso Exemplo: printf(“formatacao %s %d %f \n ”, “controlada”, 2000, 3.77); 25 Um número inteiro positivo pode especificar o tamanho do campo de impressão: int a = 1234; printf(“%6d”, a); Nesse caso %6d especifica que a largura para impressão de a é igual a 6, justificado à direita. 1 Para justificar à esquerda é usado um sinal negativo: 2 3 4 %-12d Se o argumento a ser convertido for menor que o campo especificado, espaços em branco serão colocados na esquerda ou na direita, dependendo se o justificado for à direita ou à esquerda. 1 2 3 4 Caso o argumento seja maior que o especificado, o campo de impressão será estendido até o necessário, de acordo com o número de caracteres do argumento. 26 A precisão é indicada por um ponto seguido do número de casas. float b = 100.012345; printf ( “%8.4f ”, b ) ; 1 0 0 . 0 1 2 3 printf ( “%-12.4f ”, b ) ; 1 0 0 . 0 1 2 3 27 sizeof() int main() { char c = unsigned unsigned double d printf( printf( printf( printf( printf( Fornece o tamanho do operando em bytes 'A'; short s = 65535; int i = 0xffffffff; = 3.141592; "c=%c\nO tipo de dado char tem %d bytes\n\n", c, sizeof(c) ); "c=%d impresso com %%d\n\n", c ); "s=%x\nO tipo de dado short tem %d bytes\n\n", s, sizeof(s) ); "i=%u\nO tipo de dado int tem %d bytes\n\n", i, sizeof(i) ); "pi\n%6.2f\nO tipo de dado double tem %d bytes\n\n", d, sizeof(d) ); return 0; } 28 #include <stdio.h> int scanf(“string_de_controle”, outros_argumentos) string_de_controle contém os comandos de formatação. outros_argumentos é a lista de endereços das variáveis de armazenamento. Os endereços são obtidos com o operador & Exemplo: int main() { int i; printf("Entre com um int: "); scanf("%d", &i); printf("Vc digitou %d", i); return 0; } 29 Código %c %d %i %e %f %h %o %s %x %p %n Significado Lê um único caractere Lê um inteiro decimal lê um inteiro decimal lê um número de ponto flutuante lê um número de ponto flutuante lê um inteiro curto (short int) lê um octal lê um string lê um hexadecimal lê um ponteiro recebe um inteiro igual ao número de caracteres lidos até o momento 30 #include <stdio.h> #include <stdlib.h> int main() { float salario; printf("Entre o salario desejado:"); printf(" $_______\b\b\b\b\b\b\b"); //\b é backspace scanf("%f", &salario); printf("\n\t$%.2f por mes é %.2f por ano.", salario, salario*12.0); printf("\rLegal!\n"); return 0; } Stephen Prata, C Primer Plus, 5th Ed. 31 Operadores são utilizados para manipular dados. • • Os operadores realizam: • • cálculos; comparação entre variáveis; atribuição de valores; etc... a) Operadores aritméticos b) Operadores relacionais c) Operadores lógicos Os operadores podem ser d) Operadores de atribuição agrupados nas classes: e) Operador de tamanho f) Operador bit-a-bit g) Operador ternário 32 O operador atribuição “=” atribui a expressão na sua direita para a variável à sua esquerda: x = 2000; A ação é executada da direita para a esquerda atribui o valor 2000 à variável de nome x. Toda expressão em C tem um valor: 5 + 2 tem valor 7, x = 3 tem valor 3. Isso permite escrever atribuições múltiplas: x=y=3 33 adição subtração divisão multiplicação módulo (resto da divisão inteira) + / * % Os operadores + , - , / , * são definidos para os tipos: - inteiros; - caracteres; - reais (float, double). O operador módulo (%) só é definido para inteiros. 34 O operador unário é utilizado para indicar a troca do sinal algébrico: x = -8; x = -x; resulta em x = 8. 35 operador == != < > <= >= descrição igualdade desigualdade menor que maior que menor ou igual maior ou igual exemplo while(x == 10) {...} while(x != 10) {...} while(x < 10) {...} while(x > 10) {...} while(x <= 10) {...} while(x >= 10) {...} Os operadores relacionais retornam um inteiro igual a: 1 se a relação for verdadeira 0 se a relação for falsa 36 Equacionamento do problema 2120 fahr 320 1000 celsius 00 Faixa de conversão 212 32 fahr 32 100 0 celsius 0 5 celsius ( fahr 32) 9 de 00 a 3000 com passos de 200 37 #include <stdio.h> #include <stdlib.h> #include <conio.h> int main() { float ini=0, fim=300, inc=20; float f=ini, c; while(f <= fim) { c = (5.0/9.0)*(f-32.0); printf("%4.0f %6.1f\n", f, c); f = f+inc; } return 0; } 38 #include <stdio.h> #include <stdlib.h> #define SEC_PER_MIN 60 // seconds in a minute int main() { int sec, min, left; printf("Convert seconds to minutes and seconds!\n"); printf("Enter the number of seconds (<=0 to quit):\n"); scanf("%d", &sec); // read number of seconds while (sec > 0) { min = sec / SEC_PER_MIN; // truncated number of minutes left = sec % SEC_PER_MIN; // number of seconds left over printf("%d seconds is %d minutes, %d seconds.\n", sec, min, left); printf("Enter next value (<=0 to quit):\n"); scanf("%d", &sec); } printf("Done!\n"); return 0; } Stephen Prata, C Primer Plus, 5th Ed. 39 AND ou E (operador de interseção) && OR ou OU (operador de união) || NOT ou NÃO (operador de negação) ! • Os operadores lógicos retornam 1 (um) para verdadeiro e 0 (zero) para falso. • Valores diferentes de zero são interpretados como verdadeiros. • A validação de uma expressão envolvendo operadores lógicos é feita da esquerda para a direita. 40 #include <stdio.h> #include <stdlib.h> int main() { int x = 10, y = 20; int n, e, ou; n = !(x>1); printf("n = %d\n", n); n = !(x>y); printf("n = %d\n", n); e = (x > 1) printf("e = e = (x > 1) printf("e = ou = (x > 1) printf("ou = ou = (x < 1) printf("ou = imprime n= imprime n= && (y > x) && (5 > 10); %d\n", e); && (y > x) && (5 < 10); %d\n", e); imprime e= imprime e= || (y > x) || (5 > 10); %d\n", ou); || (y < x) || (5 > 10); %d\n", ou); imprime ou= imprime ou= return 0; } 41 = += -= *= /= a+=b; a-=b; a*=b; a/=b; a a a a = = = = a a a a + * / b; b; b; b; Pré-fixados (prefix mode) Incremento: ++ Decremento: -- ++a; --a; a = a + 1; a = a - 1; Pós-fixados (postfix mode) a++; a--; a = a + 1; a = a - 1; A operação de inc ou dec é realizada antes de usar o valor do operando A operação de inc ou dec é realizada depois de usar o valor do operando 42 #include <stdio.h> #include <stdlib.h> int main() { int x, y, a, b; x = 10; y = ++x; printf(“x=%d y=%d\n”, x, y); imprime x= y= a = 10; b = a++; printf(“a=%d b=%d\n”, a, b); imprime a= b= return 0; } Herbert Schildt, C Completo e Total, 3a Ed. 43 Forma 1 if(expressão) instrução A instrução é executada se a expressão for verdadeira. Forma 2 if(expressão) instrução1 else instrução2 Se expressão for verdadeira, a instrução1 é executada. Caso contrário, a instrução2 é executada. Forma 2 if(expressão1) instrução1 else if (expressão2) instrução2 else instrução3 Se expressão for verdadeira, a instrução1 é executada. Se a expressão1 for falsa mas a expressão2 for verdadeira, a instrução2 e é executada. Caso contrário, se ambas expressões forem falsas, a instrução3 é executada. 44 Fazer um programa que classifica uma nota de 0 a 10 em ruim, regular, boa ou excelente. Critério: [0...4) ruim [4...6) regular [6...8) boa [8...10] excelente 45 [0...4) ruim [4...6) regular [6...8) boa int main() Solução { float n = 7.5; [8...10] excelente 1 int main() { Solução 2 float n; printf("Digite a nota: "); if (n<4) printf("ruim"); else if (n>=4 && n<6) printf("regular"); else if (n>=6 && n<8) printf("boa"); else printf("excelente"); while(scanf("%f", &n) == 1) { if(n>=8) printf("excelente\n"); else if(n>=6) printf("boa\n"); else if(n>=4) printf("regular\n"); else printf("ruim\n"); printf("Digite a proxima nota (q para sair): "); } return 0; return 0; } } 46 O operador ternário trabalha com três expressões: expressao1 ? expressao2 : expressao3 ; Se a expressao1 é verdadeira, a expressão dois é avaliada e o resultado é o valor da expressao2 como um todo. Se a expressao1 for zero, isto é falso, a expressao3 é avaliada, e será o resultado da expressão como um todo. Por exemplo, o código: x = ( y < z ) ? y : z ; assinala a x o menor valor entre y e z. 47 #include <stdio.h> #include <stdlib.h> #define COVERAGE 200 /* square feet per paint can */ int main() { int sq_feet; int cans; printf("Enter number of square feet to be painted (=0 to quit):\n"); scanf("%d", &sq_feet); while (sq_feet > 0) { cans = sq_feet / COVERAGE; cans += ((sq_feet % COVERAGE == 0)) ? 0 : 1; printf("You need %d %s of paint.\n", cans, "cans"); printf("Enter next value (=0 to quit):\n"); scanf("%d", &sq_feet); } return 0; } Sempre imprime “cans”. Porém, quando é apenas uma, deveria imprimir “can”. Para solucionar, insira um operador ternário na linha indicada. Stephen Prata, C Primer Plus, 5th Ed. 48 #include <stdio.h> #include <stdlib.h> #define COVERAGE 200 /* square feet per paint can */ int main() { int sq_feet; int cans; printf("Enter number of square feet to be painted (=0 to quit):\n"); scanf("%d", &sq_feet); while (sq_feet > 0) { cans = sq_feet / COVERAGE; cans += ((sq_feet % COVERAGE == 0)) ? 0 : 1; printf("You need %d %s of paint.\n", cans, cans == 1 ? "can" : "cans"); printf("Enter next value (=0 to quit):\n"); scanf("%d", &sq_feet); } return 0; } Stephen Prata, C Primer Plus, 5th Ed. 49 AND OR XOR NOT & | ^ ~ a b a&b a|b a^b 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 1 1 1 1 0 São válidos para char, int, short e long. 50 #include <stdio.h> #include <stdlib.h> int main() { unsigned char a, b, c, d; a = 0x0F & 0x55; printf("a = %x\n", a); b = 0x0F | 0x55; printf("b = %x\n", b); c = 0x0F ^ 0x55; printf("c = %x\n", c); d = ~0x55; printf("d = %x\n", d); return 0; } 51 #include #include #include #include <stdio.h> <stdlib.h> <conio.h> <math.h> int main() { int i, t, m; while(scanf("%d", &i),i<1000) { printf("%5x h = ", i); t = pow(2,27); m = 1; while(t>0) { (i&t) ? printf("1") : printf("0"); t = t/2; if(m/4 == 1) { printf(" "); m=0; } m++; } printf("b\n"); } return 0; } 52 Deslocamento para a direita Deslocamento para a esquerda Ambos operadores de deslocamento >> << trabalham com expressões do tipo inteiras. A expressão: exp1 << exp2 faz com que os bits da exp1 sejam deslocados para a esquerda. O número de deslocamentos é dado pela exp2. Na medida em que os bits são deslocados, o bit menos significativo (mais da direita) é preenchido com 0. 53 54 #include #include #include #include <stdio.h> <stdlib.h> <conio.h> <math.h> int main() { int i, t, m; while(scanf("%d", &i),i<1000) { printf("%5x h = ", i); t = pow(2,27); m = 1; while(t>0) { (i&t) ? printf("1") : printf("0"); t >>= 1; //t = t/2; if(m/4 == 1) { printf(" "); m=0; } m++; } printf("b\n"); } return 0; } 55 Uma função é um bloco de programa que realiza uma determinada tarefa. Evita a repetição de código ◦ Se é necessário realizar uma tarefa várias vezes, basta escrever uma função e utilizá-la todas as vezes. Pode-se também utilizá-la em outros programas. Ajuda a organizar o programa ◦ Torna o programa mais modular e, com isso, mais fácil de ler, modificar e depurar. tipoRetornado nomeFunc(parâmetros formais) { corpo de função } Stephen Prata, C Primer Plus, 5th Ed. 56 Prog13 Função void #include <stdio.h> #include <conio.h> #define NOME "XPTO 2000 LTDA" #define END "CURITIBA" #define L 40 void starbar(void) { int cnt; for (cnt = 1; cnt<=L; cnt++) printf("%c", '*'); printf("\n"); void starbar(void); //protótipo int main() { int cnt = 1; starbar(); //chamada printf("%s %d\n", NOME, cnt++); printf("%s %d\n", END, cnt); starbar(); //chamada getch(); return 0; } //definição } void: vazio, sem efeito #define: instrução para o pré-processador Variável cnt: escopos diferentes. “Um não tem nada a ver com o outro”. IDE Run to cursor: F4 Next line: F7 Step into: Shift+F7 Stephen Prata, C Primer Plus, 5th Ed. 57 Prog14 Função que recebe parâmetros #include <stdio.h> #include <conio.h> #define NOME "XPTO 2000 LTDA" #define END "CURITIBA" void charbar(char, int); //protótipo int main() { charbar(‘#’,30); //chamada printf("%s\n", NOME); printf("%s\n", END); charbar(‘-’,30); //chamada void charbar(char ch, int n)//definição { int cnt; for (cnt = 1; cnt<=n; cnt++) printf("%c", ch); printf("\n"); } getch(); return 0; } Stephen Prata, C Primer Plus, 5th Ed. 58 Prog15 Função com return #include <stdio.h> #include <conio.h> int min(int, int); //protótipo int main() { int x=5, y=3; //chamada printf("minimo = %d", min(x,y)); getch(); return 0; } int min(int a, int b) //definição { return a < b ? a : b; } Stephen Prata, C Primer Plus, 5th Ed. 59 Prog16 Função com mais de um return #include <stdio.h> #include <conio.h> Há um erro neste prog! int par(int); //protótipo int main() { int x=11; if (par(x)) //chamada printf("par"); else printf("impar"); getch(); return 0; } int par(int x) //definição { if(!(a%2)) return 1; else return 0; } 60