Upload
internet
View
106
Download
0
Embed Size (px)
Citation preview
Ementa:
Equivalente ao sumário do livro:
The C Programming Language, Second edition.
Autores: Brian W. Kernighan, Dennis M. Ritchie
Bibliografia The C Programming Language, Second edition.
Brian W. Kernighan, Dennis M. Ritchie.
Internet hyperlinks
Capítulo 1
Sucinta introdução à linguagem C Analisar programas em C com os elementos
essenciais da linguagem: Variáveis e constantes Aritmética Fluxo de controle Funções Rudimentos de E/S
Primeiro programa
Imprima as palavras:“hello, world”
Primeiro programa – obstáculos
Aonde criar o texto do programa? Como compilá-lo? Como carregá-lo? Como executá-lo? Aonde e como ver o resultado de sua execução?
Código de helloworld.c
#include <stdio.h>
main()
{
printf("hello, world\n");
}
---------------------------
prog01-chap01-pg09.c
Etapas:
Usar um editor (ex. gedit) para criar o texto do programa, salvando-o no arquivo helloworld.c
Compilar o programa (usamos o compilador gcc)
$ gcc helloword.c -o nome_do_executavel <enter>
Executar o programa
$ nome_do_executavel <enter> Verificar a saída no terminal
Integrate Development Environment
Para facilitar o desenvolvimento de programas:
• Netbeans http://netbeans.org/
• Eclipse http://www.eclipse.org/
• Anjuta http://www.anjuta.org/
• Geany http://www.geany.org/
• Code::Blocks http://www.codeblocks.org/
• …
Programas em C
Um programa consiste de funções e variáveis As funções contêm comandos que especificam
as operações a serem realizadas As variáveis armazenam os valores usados nas
operações delas resultantes main () é uma função especial. É o entry-point
de execução do programa. Os programas em C iniciam aí a sua execução. Todo programa deve ter uma função main ().
Detalhes do primeiro programa
#include <stdio.h>
informa ao compilador para incluir informações da biblioteca padrão de E/S.
Os parênteses após o nome da função (ex. main (...)) delimitam a lista de argumentos.
Os comandos de uma função são delimitados por chaves → { statement }
Invoca-se uma função, indicando-se o nome da função, seguido da lista de argumentos delimitada por parênteses. Ex. printf(“helloworld\n”);
prog02-chap01-pg12 (1)
Comentário: quaisquer caracteres situados entre /* e */ são ignorados pelo compilador
Podem aparecer em qualquer lugar do programa aonde seja válido um espaço em branco, uma marca de tabulação ou uma nova linha.
prog02-chap01-pg12 (2)
Em C deve-se declarar todas as variáveis antes de usá-las;
Normalmente no início das funções e antes de qualquer comando executável;
A declaração indica o nome e o tipo da variável; Os valores assumidos por um determinado tipo
(ex. int) depende das características de hardware da máquina;
prog02-chap01-pg12 (3)
Alguns tipos de dados básicos em C: int -16bits -32768<=valor<=32767 float - 32 bits - com pelo menos 6 dígitos
significativos 10-38 <=valor<=10+38
char - um único byte - caracter short - inteiro curto long - inteiro longo double – ponto flutuante com dupla precisão A faixa de valores assumidos depende do hw;
prog02-chap01-pg12 (4)
Outros tipos de dados em C: Vetores Estruturas Pointers Funções
Em C os comandos individuais são terminados por ;
prog02-chap01-pg12 (5)
Semântica do loop while
while (fahr <= upper) {
statement
} A condição entre parênteses é testada. Se verdadeira, o
corpo do while é executado. A condição é novamente testada, e se verdadeira, o corpo do while é executado novamente, e assim por diante... Quando a condição se tornar falsa o corpo do while não será executado e a execução continuará no comando que se segue ao loop.
prog02-chap01-pg12 (6)
A organização lógica do programa é enfatizada pela identação (não faz parte da linguagem);
Facilita o entendimento dos programas; Recomendações: um comando por linha / deixar
espaços em torno dos operadores; Na divisão entre inteiros o resultado é truncado.
Assim 2/3 = 0;
prog02-chap01-pg12 (7)
printf é uma função geral de conversão de formatos. Seu primeiro argumento é uma cadeia de caracteres a ser impressa, onde cada sinal %
indica aonde um dos outros argumentos (segundo, terceiro, …) deverá ser substituído, e também sob que formato deverá ser impresso.
%d – inteiro decimal %s – cadeia de caracteres %f – ponto flutuante
prog04-chap01-pg14 (1)
O comando for (outra forma de loop) for (expr1; expr2; expr3)
statement
É equivalente a:
expr1;
while (expr2) {statement
expr3;
}
prog04-chap01-pg14 (2)
expr1 é executada uma vez, antes do loop ser iniciado;
expr2 é o teste ou condição para o controle do loop;
expr3 corresponde ao passo de incremento e eventalmente altera o valor de expr2, podendo ocasionar o fim do loop;
prog04-chap01-pg14 (3)
Escolhendo entre os loops while e for:
for é mais apropriado para loops nos quais a inicialização e incrementos são comandos simples e logicamente relacionados, pois é mais compacto que o while e mantém os comandos de controle do loop juntos e no mesmo local.
prog05-chap01-pg17 (1)
O uso de números mágicos em um programa não é boa prática de programação (ex. 0, 300, 20, etc.)
Dificultam o entendimento do código Difíceis de serem alterados de forma
sistemática Solução: substituí-los por nomes simbólicos ou
constantes simbólicas
prog05-chap01-pg17 (2)
# define nome texto substituto
…
# define LOWER 0 /* lower limit of table */
#define UPPER 300 /* upper limit */
#define STEP 20 /* step size */ LOWER, UPPER e STEP são constantes simbólicas e
não variáveis Por convenção são escritos em MAIÚSCULAS para
serem facilmente identificados
Entrada e Saída de caracteres (i) No modelo de E/S suportado pela biblioteca
padrão o texto de E/S é manipulado como um fluxo de caracteres, não importando a sua origem ou destino.
Um fluxo de texto é uma seqüência de caracteres particionada em linhas.
Cada linha consiste em zero ou mais caracteres seguidos por um caracter de nova linha (\n)
A biblioteca é responsável por fazer com que cada linha da E/S esteja de acordo com o modelo.
Entrada e Saída de caracteres (2)
A biblioteca padrão dispõe de uma série de funções para E/S
As mais simples são: getchar e putchar getchar – lê o próximo caracter de entrada do
fluxo de texto e o retorna como seu valor Após c = getchar (); a variável c contém o
caracter lido O fluxo de textos de entrada normalmente tem
origem no teclado, mas pode vir de arquivos.
Entrada e Saída de caracteres (3)
putchar (c) imprime um caracter (coloca-o no fluxo de saída) a cada vez que é invocada
O fluxo de saída é normalmente direcionado para o terminal
O valor impresso é o conteúdo de c, sob a forma de um inteiro
Invocações a putchar e a printf podem ser intercaladas e a saída corresponderá à ordem de invocação das funções
prog06-chap01-pg18.c (1)
Programa que copia a entrada (teclado) para a saída (terminal), um caracter por vez
read a character
while (charater is not end-of-file indicator)
output the character just read
read a character
prog06-chap01-pg18.c (2)
O operador != significa não é igual a O caracter que aparece na tela é armazenado
internamente apenas como um padrão de bits O tipo char foi desenvolvido para armazenar o padrão
de bits correspondente a um caracter Em C pode-se usar um tipo int para esta finalidade O programa usa int para distingüir quando não há mais
caracteres na entrada. Neste caso, getchar retorna EOF, um valor distinto de qualquer caracter real
EOF é um inteiro definido em <stdio.h>
prog07-chap01-pg19.c Segunda versão do programa que copia a entrada
(teclado) para a saída (terminal), um caracter por vez Entrada centralizada Mais fácil de se ler (para os programadores em C) Os parênteses envolvendo a atribuição (c =
getchar()) são necessários, pois a precedência de != é superior à de =.
Efeito não desejado de se atribuir a c o valor 0 ou 1, dependendo se a invocação a getchar encontrou ou não o fim de arquivo.
prog08-chap01-pg19.c Programa que conta quantos caracteres há no texto de
entrada Operador ++, que significa incremento de um ++nc é equivalente a nc = nc + 1 ++nc é diferente de nc++, embora ambos incrementem
c de um O tipo long representa inteiros que ocupam pelo menos
32 bits (em algumas máquinas o valor de um int é no máximo de 32767)
%ld informa a printf que o argumento correspondente é um long
prog09-chap01-pg20.c
Outra versão do programa que conta quantos caracteres há no texto de entrada
Possibilita contar muito mais caracteres, por armazenar o número de caracteres lidos em um double (ponto flutuante de dupla precisão)
A contagem dos caracteres é realizada na definição das condições de contorno do for e não em seu corpo
As regras do C exigem que o comando for tenha um corpo. No caso, o comando nulo: ;
prog10-chap01-pg20.c (1)
Programa para contar quantas linhas há no texto de entrada.
Lembra que em C um fluxo de texto é uma seqüência de caracteres particionada em linhas.
Cada linha consiste em zero ou mais caracteres seguidos por um caracter de nova linha (\n)
Assim, contar linhas, é equivalente a contar o numero de caracteres de new line (\n) no texto de entrada.
prog10-chap01-pg20.c (2)
O comando if
if (condition)
statement Significado do if
A condição entre parênteses é testada. Se verdadeira, executa statement (ou grupo de statements entre chaves)
== é a notação de C para “é igual a” = é a notação de C para o comando de atribuição
prog10-chap01-pg20.c (3)
Um caracter escrito entre aspas simples – 'c' - representa um valor inteiro igual ao valor numérico do caracter no conjunto de caracteres da máquina (constante de caracter).
'A' é uma constante de caracter. No conjunto de caracteres ASCII seu valor é 65, a representação interna do caracter A.
O valor de '\n' é 10 em ASCII. '\n' representa um único caracter (lembrar da
seqüência de escape).
prog11-chap01-pg21.c (1) Programa para contar linhas, palavras e caracteres Uma palavra é qualquer seqüência de caracteres que
não contém um caracter de espaço, tabulação ou nova linha.
Versão simplificada do programa wc do unix. nl = nw = nc = 0; /* atribui às três variáveis o
valor zero */ Uma atribuição tem um valor e é associativa, da direita
para a esquerda. Equivalente a nl = (nw = (nc = 0));
prog11-chap01-pg21.c (2) O operador || significa o ou lógico Analogamente && significa o e lógico As expressões conectadas por && ou || são avaliadas da
esquerda para a direita. A avaliação terminará assim que a veracidade ou falsidade for conhecida.
Forma geral do comando else
if (expression)
statement1
else
statement2
statementi
pode ser {statementi*}
Vetores em C
Indica uma coleção de variáveis do mesmo tipo, referenciada por um nome comum.
O acesso a um elemento específico dentro desta coleção de variáveis se dá através de um índice.
Ex.: int ndigito[10]; ndigito[i] Em C, os subscritos (índices) dos vetores
sempre iniciam de 0 (zero). Um subscrito pode ser qualquer expressão
inteira, variável inteira ou constante inteira.
prog12-chap01-pg24.c
Programa para contar o número de ocorrências de cada dígito, de caracteres de espaço em branco (space, tab, new line) e de todos os outros caracteres.
Usa um vetor – int ndigito[10] - para armazenar o número de ocorrências de cada dígito.
O programa usa propriedades da representação em caracteres dos dígitos.
Se o caracter armazenado em c é um dígito o seu valor numérico é c – '0'
Decisões múltiplas em C (1)
if (condition1)
statement1
else if (condition2)
statement2
...
...
else
statementn+1
Decisões múltiplas em C (2) As condições são avaliadas em ordem, a partir do topo,
até que uma das condições (conditioni )seja satisfeita;
nesse ponto statementi é executado e a construção
inteira é terminada. (statementi pode representar vários
statements envolvidos por chaves). Se nenhuma das condições for satisfeita, o statement
n após o else é
executado, se houver. Se o else e statementn forem
omitidos nenhuma ação é tomada. Alternativa para decisões múltiplas: o comando switch.
prog13-chap01-pg26.c (1)
C não possui operador de exponenciação. O programa define uma função power(m, n) que
eleva um inteiro positivo m à potència inteira positiva n.
Biblioteca padrão: pow(x, y) Protótipo → int power(int m, int n);
parâmetros
prog13-chap01-pg26.c (2)
argumentos
printf("%d %d %d\n", i, power(2,i), power(-3,i));
parâmetros
int power(int base, int n)
{ … }
Funções (1)
Forma de se encapsular alguma computação. Equivalente a uma sub-rotina ou função em
Fortran e a procedure ou função em Pascal. Idéia: não se preocupar como uma tarefa é
realizada e sim o que é realizado. Permite efetuar a decomposição de uma grande
tarefa em várias tarefas menores. Essencial no desenvolvimento de sistemas mais
complexos.
Funções (2) Forma geral de definição de uma função:
tipo-retornado nome-da-função (lista de
declarações de parâmetros)
{
declarações
statements
} As definições de funções podem aparecer em qualquer
ordem em um único arquivo fonte ou em arquivos diversos.
Funções (3) Protótipo de função: declaração que deve
combinar com a definição da função. Envolve apenas
tipo-retornado nome-da-função (lista de declarações de parâmetros);
Parâmetro (argumento formal): variável nomeada na lista entre parênteses em uma definição de função.
Argumento (argumento real): variável ou valor usado na invocação (chamada) de uma função.
Funções (4)
Os nomes dos parâmetros e argumentos não precisam ser idênticos.
Os nomes dos parâmetros são opcionais no protótipo da função.
A função retorna o seu valor (que é de um tipo especificado) por meio de um comando
return expressão; Uma função não precisa retornar um valor.
Neste caso, o tipo-retornado é void.
Funções (5) return; faz com que o controle, mas não um valor,
seja retornado ao trecho de código que invocou a função. Equivalente a chegar a }, o delimitador de fim da função.
main é uma função e pode possuir um comando return ao seu final (retorna um valor ao ambiente em que o programa em C foi executado.
Código de retorno 0 → término normal. Código de retorno != 0 → indica situações incomuns
ou erros.
Funções (6)
Diferenças da definição e declaração de funções entre o ANSI C e as versões anteriores de C
(ver prog13a-chap01-pg28.c). Os parâmetros são nomeados entre parênteses -
( ) - e os seus tipos são declarados antes do abre-chave - { .
No protótipo da função não era permitido a declaração dos tipos de parâmetros (resultado: o compilador não tinha como checar se a invocação da função estava correta).
Funções - call by value (1)
Chamadas por valor (call by value)
é fornecida à função uma cópia dos argumentos em variáveis temporárias (os parâmetros), de tal forma que os valores das variáveis no trecho do programa que invocou a função não são alterados.
Logo, em C, uma função chamada não pode alterar o valor de uma variável na função que a invoca. Só pode alterar os valores da sua própria cópia.
Funções - call by value (2)
Call by value é uma vantagem → propicia o encapsulamento do código da função, evitando reflexos nas variáveis do código que invoca a função.
Os parâmetros comportam-se como variáveis locais à função que foi invocada.
São inicializados com os valores assumidos pelos argumentos no trecho do código que invocou a função (ver prog14-chap01-pg28.c).
Funções - call by reference
Em C, quando necessário, é possível a uma função, alterar o valor de uma variável na função que a invoca.
Na invocação da função deve-se fornecer, como argumento, o endereço da variável a ser alterada (pointer para a variável).
A função invocada deve declarar, como parâmetro um pointer e deve referenciar indiretamente o valor da variável.
Funções – vetores como argumentos
Quando o nome do vetor é usado como argumento, o valor passado à função é o local ou endereço de início do vetor.
Não há uma cópia para os elementos do vetor. A função pode ter acesso e alterar qualquer
elemento do vetor com o uso de subscritos.
Constante do tipo cadeia de caracteres
Para armazenar a constante ''dia\n'' o compilador C cria um vetor com um '\0', ao seu final.
d i a \n \0
prog15-chap01-pg30.c (1)
Programa para ilustrar o uso de vetores de caracteres e funções que o manipulam
Lê um conjunto de linhas e imprime a maior delas.
while (there's another line)
if (it's longer than the previous longest)
(save it)
(save its length)
print longest line
prog15-chap01-pg30.c (2)
Desenvolver uma função getline para obter a próxima linha de entrada
getline deve ser útil em outros contextos getline retorna o tamanho da linha obtida,
ou zero, se for encontrado o fim de arquivo Lembrar que zero não é um tamanho
válido para uma linha, pois, mesmo uma linha-vazia possui o caracter de new line - \n
prog15-chap01-pg30.c (3)
A maior linha encontrada até o momento deve ser salva em algum lugar.
Desenvolver a função copy, para copiar a nova linha (no caso de ser maior que a anterior) para um local seguro.
Na função main deve-se ter um código para controlar getline e copy.
Os protótipos das funções getline e copy são declarados no início do arquivo, anterior à função main.
prog15-chap01-pg30.c (4)
main e getline trocam informações por intermédio de um par de argumentos/parâmetros e pelo valor retornado por getline.
Getline declara os parâmetros em
int getline(char s[], int lim)
o primeiro parâmetro s é um vetor. Seu tamanho não é necessário em getline, pois já foi definido em main.
O valor retornado por getline é um int (o tamanho da linha obtida),
prog15-chap01-pg32.c (5)
O tipo retornado por copy é void, indicando explicitamente que nenhum valor é retornado.
getline insere o caracter ' \0' ao final do vetor, para sinalizar o fim da cadeia de caracteres (mesma convenção utilizada pelo compilador C nas constantes do tipo cadeia de caracteres).
A especificação de formato %s em printf sinaliza que o argumento correspondente deve ser uma cadeia de caracteres.
Testando o tamanho retornado por getline e o último caracter retornado no vetor, main poderia determinar se a linha obtida é maior que um valor máximo pré-determinado e prosseguir da forma desejada (ignorou-se esse caso).
Variáveis externas e escopo (1)
prog16-chap01-pg32.c As variáveis declaradas em uma função são
privativas ou locais à função. Outras funções não têm acesso a elas (isto vale
também para as variáveis declaradas em main). Cada variável local a uma função existe somente
enquanto a função está ativa e deixa de existir quando a função termina.
Por isso são também conhecidas como variáveis automáticas.
Variáveis externas e escopo (2)
As variáveis automáticas devem ser explicitamente inicializadas a cada chamada.
É possível definir-se variáveis externas a todas as funções – as variáveis globais.
Elas são visíveis a todas as funções e podem ser por elas alteradas.
As variáveis externas são permanentes e retêm os seus valores entre as diversas chamadas a uma função.
Variáveis externas e escopo (3)
Tornam o programa mais acoplado, o que dificulta alterações futuras e a própria compreensão do programa (lembrar que o todo é maior que as partes).
Uma variável externa deve ser definida exatamente uma vez, fora de qualquer função. Isto aloca área de armazenamento para ela.
Cada função que desejar ter acesso à variável externa deve declará-la explicitamente com extern ou implicitamente pelo contexto.
Variáveis externas e escopo (4)
Antes que uma função possa usar uma variável externa, o nome da variável deve tornar-se conhecido pela função.
Uma alternativa é inserir uma declaração extern na função
extern char line[], longest[]; Em certos casos pode-se omitir a declaração
extern. Ex.: se a definição da variável extern ocorrer no
arquivo-fonte antes do seu uso na função.
Variáveis externas e escopo (5) Uma prática comum é inserir a definição de todas as
variáveis externas no início do arquivo fonte e omitir as declarações extern dentro das funções.
Se o programa está distribuído por vários arquivos fontes e uma variável extern é definida em arquivo1 e usada em arquivo2 e arquivo3, então as declarações extern em arquivo2 e arquivo3 são necessárias.
Uma alternativa é concentrar todas as declarações extern em um arquivo separado (header) e incluí-lo por um #include no início de cada arquivo fonte.
#include ''myheader.h''
Variáveis externas e escopo (6)
Definição – refere-se ao local aonde se cria a variável ou se destina área de armazenamento para a mesma.
Declaração – refere-se ao local em que a natureza da variável é estabelecida (seu tipo), mas não há alocação de área para a mesma.
A keyword void deve ser usada em lista explicitamente vazias. Tem a ver com a checagem de argumentos nos compiladores e a compatibilidade com versões mais antigas do C.