Você está na página 1de 46

Computação 2

Linguagem C
Revisão de Conceitos de
Programação
2023
Conteúdo

Introdução

Histórico

Elementos fundamentais
– Estrutura de programa
– Variáveis e tipos

Estruturas de decisão

Estruturas de repetição

Funções

Ponteiros
Linguagem de Programação C

Linguagem de programação genérica, de alto nível
– Foi desenvolvida por programadores para programadores, tendo como meta características de
flexibilidade e portabilidade
– O C é uma linguagem que nasceu juntamente com o advento da teoria de linguagem estruturada e do
computador pessoal
– Tornou-se rapidamente uma linguagem “popular” entre os programadores
– Usado para desenvolver o sistema operacional UNIX
– Base para desenvolver novas linguagens, entre elas C++ e Java

C é uma linguagem de alto nível com uma sintaxe bastante estruturada e flexível tornando
sua programação bastante simplificada
– Consegue também acessar recursos de baixo nível do SO e do hardware disponível

Programas em C são compilados, gerando programas executáveis
Linguagem de Programação C

C compartilha recursos tanto de alto quanto de baixo
nível, pois permite acesso e programação direta do
microprocessador
– Rotinas cuja dependência do tempo é crítica, podem ser
facilmente implementadas usando instruções em Assembly

Estruturalmente simples (poucas funções intrínsecas)
– Permite a inclusão de uma quantidade arbitrária de rotinas
do usuário
– Fornecedores de compiladores fornecem uma grande
variedade de rotinas pré-compiladas em bibliotecas
Linguagem de Programação C

1970: Denis Ritchie cria uma linguagem a partir do BCPL
– AT & T Bell Labs
– Chama a linguagem de B

1972: Ritchie começa a melhorar B, criando o C
– Compilador foi incluído na versão 2 do Unix

1978: Brian Kerningham junta-se a Ritchie
– Livro “The C Programming Language”
– Especificação informal da linguagem

1983: A linguagem é padronizada pelo American National
Standard Institute: surge o ANSI C.

Anos 1990: Borland International Co, escolhe C e Pascal como
linguagens para o seu IDE
– Integrated Development Enviroment (Ambiente Integrado de
Desenvolvimento)
– Turbo Pascal e Turbo C
Linguagem de Programação C

História da linguagem C é bastante ligada à
história do sistema operacional Unix
– Unix foi originalmente implementado em Assembly
em um PDP-7
– Kernel do Unix foi reescrito em C em 1973

Version 4 Unix

Para um PDP-11
– Dennis Ritchie e Ken Thompson

Ambos receberam o Prêmio Turing

Implementação ligada ao hardware limitava ports
para outras plataformas
– Unix foi um dos primeiros sistemas operacionais
implementado em uma linguagem de alto nível
Estrutura de Programa

Cabeçalho
– Diretivas de compilador

Constantes simbólicas

Declaração de variáveis

Inclusão de bibliotecas

Declaração de rotinas

Blocos de instruções
– {…}
– Terminação de linha com ;

Bloco de instruções principal
– main()

Demais funções

Comentários
– // e /* … */
Variáveis

Espaços de memória
nomeados

Devem ser declaradas
– Tipo e nome

int c = 0;

Valor é opcional, mas recomendado
– Nomes são sensíveis a
maiúsculas/minúsculas
Tipos de dados

Utilizados para declaração de variáveis e funções
– Tipos básicos

Aritméticos (inteiros e ponto flutuante - IEEE-754)

Podem ou não ter sinal (unsigned)

Tamanho de armazenamento dependente da arquitetura do sistema operacional / cpu
– Tipos enumerados

Aritméticos com uma faixa discreta de valores
– Void

Sem valor
– Tipos derivados

Ponteiros, arrays, structures, union, function
Tipos inteiros
Tipo Tamanho de Faixa de valores
armazenamento
char 1 byte -128 a 127 ou 0 a 255
unsigned char 1 byte 0 a 255
signed char 1 byte -128 a 127
int 2 ou 4 bytes -32,768 a 32,767 ou
-2,147,483,648 a 2,147,483,647

unsigned int 2 ou 4 bytes 0 a 65,535 ou 0 a 4,294,967,295

short 2 bytes -32,768 a 32,767


unsigned short 2 bytes 0 a 65,535
long 8 bytes -9223372036854775808 a
9223372036854775807
unsigned long 8 bytes 0 a 18446744073709551615
Tipos de ponto flutuante
Tipo Tamanho de Faixa de valores Precisão default
armazenamento

float 4 bytes 1.2E-38 a 3.4E+38 6 casas decimais

double 8 bytes 2.3E-308 a 1.7E+308 15 casas decimais

long double 10 bytes 3.4E-4932 a 1.1E+4932 19 casas decimais



Limites de tipos
Operadores

Aritméticos ●
Bitwise
– & (and)
– + - * / % ++ --
– | (or)

Relacionais – ^ (xor)
– ~ (complemento de 1)
– == != > < >= <=
– >> << (shift para a direita e esquerda)

Lógicos ●
Atribuição
– && (and) – = += -= *= /= %=

Miscelânia
– || (or)
– sizeof()
– ! (not) – & (endereço de variável)
– * (ponteiro para variável)
Operadores – precedência
Categoria Operador Associatividade
Pós fixados () [] -> . ++ - - Esquerda para a direita
Unários + - ! ~ ++ - - (tipo) * & sizeof Direita para a esquerda
Multiplicativo */% Esquerda para a direita
Aditivo +- Esquerda para a direita
Shift << >> Esquerda para a direita
Relacional < <= > >= Esquerda para a direita
Igualdade == != Esquerda para a direita
Bitwise AND & Esquerda para a direita
Bitwise XOR ^ Esquerda para a direita
Bitwise OR | Esquerda para a direita
Logical AND && Esquerda para a direita
Logical OR || Esquerda para a direita
Condicional ?: Direita para a esquerda
Atribuição = += -= *= /= %=>>= <<= &= ^= |= Direita para a esquerda
Entrada e saída de dados

Entrada e saída de dados para ●
Funções
programas – Caracter
– Geralmente linha de comando ou arquivos

getchar() e putchar()

Fluxos de dados (streams)

Standard files (arquivos padrões)
– Buffer de caracteres
– C trata todos os dispositivos como

Strings
arquivos
– Caracteres até um EOF (end of line)

– Standard input e output



gets() e puts()

stdin, linha de comando, teclado – Entrada e saída formatadas

sdtout, tela ●
Com mensagens e “placeholders”

stderr, tela primária ●
scanf() e printf()
Saída de dados

Formatada
– Função printf() Placeholders
– Mostra uma constante string
%d – inteiros
– Podem ser especificados caracteres %f – ponto flutuante
especiais para variáveis (placeholders) %c – caracter
– Variáveis serão mostradas onde apontado %s – strings (char[ ])
pelos placeholders

Ex
– printf(“Resultado: %d”, soma);
Entrada de dados

Formatada
– Função scanf()
– Usa placeholders

Como printf
– Referencia as variáveis pelo seu endereço

Para poder manipular a variável dentro da função

Ex
– scanf(“%d”, &valor);
Demonstrações
Estruturas de decisão

Alterar o fluxo de execução do
programa baseado no teste de uma
condição
– Uma ou mais condições
– Valores não-zero e não-nulo são
verdadeiros

Comandos
– if
– if … else
– switch
Estruturas de decisão
if (condição) {
bloco 1;
} else {
bloco 2;
}
Estruturas de decisão
if (condição) { if (numero >= 5) {

bloco 1; printf("Limite atingido");

} else { } else {

bloco 2; printf("Valor normal");


}
}
Estruturas de decisão
switch(expressão) {
case constante :
comando(s);
break; /* opcional */

case constante :
comando(s);
break; /* opcional */

default : /* opcional */
comando(s);
}
Estruturas de decisão
char nota = 'B';
switch(expressão) {
switch(nota) {
case constante :
case 'A' :
comando(s); printf("Excelente!\n" );
break; /* opcional */ break;
case 'B' :
case 'C' :
case constante :
printf("Muito bom\n" );
comando(s); break;
break; /* opcional */ case 'D' :
printf("Aprovado\n" );
break;
default : /* opcional */
case 'F' :
comando(s); printf("Reprovado\n" );
} break;
default :
printf("Nota inválida\n" );
}
Estruturas de decisão

Operador condicional (?)
– Operador ternário
– Pode ser usado para substituir if...else em sentenças simples

Se usado sem cuidado, pode diminuir a legibilidade do código

Forma geral
– exp1 ? exp2 : exp3;
– condição ? verdadeiro : falso;

Exemplo
– max = (num1 > num2) ? num1 : num2;
Estruturas de repetição

Loops

Usando quando se precisa repetir a
execução de um bloco de código
– Eventualmente com parâmetros diferentes a
cada execução

Determinar as condições da execução
repetida
– Início e fim, número de repetições

Comandos
– while
– for
– do...while
Estruturas de repetição
while (condição) {
bloco;
}
Estruturas de repetição
while (condição) { int a = 0;
bloco;
} while( a <= 10 ) {
printf("Valor de a: %d\n", a);
a++;
}
Estruturas de repetição
for (ini;cond;incr) {
bloco;
}

ini: inicialização
cond: condição
incr: incremento
Estruturas de repetição
for (ini;cond;incr) { int a = 0;
for( a = 0; a <= 10; a = a + 1 ){
bloco;
printf("Valor de a: %d\n", a);
} }

for( int b = 0; b <= 20; b++ ){


ini: inicialização
printf("Valor de b: %d\n", b);
cond: condição }
incr: incremento
Estruturas de repetição
do {
comando(s);
} while( condição );
Estruturas de repetição
do { int a = 0;

comando(s);
do {
} while( condição ); printf("Valor de a: %d\n", a);
a = a + 1;
} while( a <= 10 );
Demonstrações
Funções

Sequência ou grupo de comandos que juntos realizam um determinado objetivo
– Também chamadas de sub-rotinas, procedures, métodos, etc

Todo programa C tem ao menos uma função
– main()

As bibliotecas padrão de C fornecem diversas “built-in functions”
– Usadas no dia-a-dia de programação

O código pode (deve) ser dividido em blocos e funções separadas
– Legibilidade, melhor manutenção
– Funções definidas pelo programador
Funções

Funções em C precisam ser declaradas com um function header e um function body

Principais partes
– Tipo de retorno
– Nome da função
– Parâmetros
– Corpo da função

tipo_retorno nome_funcao ( lista de parâmetros ) {


corpo da função
}
Funções
int max(int num1, int num2) {

Funções devem ser declaradas
no começo do programa
int result;
– Avisa o compilador sobre nome e
como chamar a função
if (num1 > num2)
– Corpo da função é definido depois
result = num1;

Chamada da função
else
– Baseada em seu nome e
result = num2;
parâmetros

Como as funções existentes nas
bibliotecas C return result;
}
Funções

Passagem de parâmetros
– Por valor

Call by value

Passagem padrão de parâmetros em C

Se valores dos parâmetros forem alterados dentro da função, o código que chamou a função
não irá perceber
– Por referência

Call by reference

São passados os endereços das variáveis dos parâmetros

Recebidas na função como ponteiros

Se a função altera o valor dos parâmetros, isso fica visível para o código que chamou
Ponteiros

Toda variável é uma alocação de memória e
possui um endereço dentro da memória
– Pode ser acessado com o operador &

Um ponteiro é uma variável cujo valor é o
endereço de outra variável
– Ela “aponta” para a outra variável
– Declarado com o modificador *
● tipo *nome_var;

Porque precisamos de ponteiros?
– Para funções poderem alterar valor de variáveis
– Para construir estruturas de dados complexas
Ponteiros

Operações importantes
– Definir uma variável do tipo ponteiro
● int var = 20;
● int *pvar;
– Atribuir o endereço de uma variável para o
ponteiro
● pvar = &var;
– Acessar o valor da variável pelo ponteiro
● printf("Endereço da variável: %x \n",
pvar);
● printf("Conteúdo da variável: %d \n",
*pvar);
Ponteiros

Operações importantes
– Definir uma variável do tipo ponteiro
● int var = 20;
● int *pvar;
var
– Atribuir o endereço de uma variável para o
ponteiro
● pvar = &var;
– Acessar o valor da variável pelo ponteiro
● printf("Endereço da variável: %x \n",
pvar);
● printf("Conteúdo da variável: %d \n",
*pvar);
Ponteiros

Operações importantes
– Definir uma variável do tipo ponteiro
● int var = 20; var
● int *pvar; 20
– Atribuir o endereço de uma variável para o
ponteiro
● pvar = &var;
– Acessar o valor da variável pelo ponteiro
● printf("Endereço da variável: %x \n",
pvar);
● printf("Conteúdo da variável: %d \n",
*pvar);
Ponteiros

Operações importantes
– Definir uma variável do tipo ponteiro
● int var = 20; var
● int *pvar; 20
– Atribuir o endereço de uma variável para o
ponteiro
● pvar = &var;
– Acessar o valor da variável pelo ponteiro pvar
● printf("Endereço da variável: %x \n",
pvar);
● printf("Conteúdo da variável: %d \n",
*pvar);
Ponteiros

Operações importantes
– Definir uma variável do tipo ponteiro
● int var = 20; var
● int *pvar; 20
– Atribuir o endereço de uma variável para o
ponteiro
● pvar = &var;
– Acessar o valor da variável pelo ponteiro pvar
● printf("Endereço da variável: %x \n",
pvar);
● printf("Conteúdo da variável: %d \n",
*pvar);
Ponteiros

Ponteiros NULL
– Palavra-chave para ponteiros não definidos

int *ptr = NULL;

Aritmética de ponteiros
– Ponteiros podem ser somados e subtraídos

Apontam para a próxima ou a anterior posição contígua de memória, baseado no tamanho do tipo
do ponteiro

Faz sentido em algumas situações, como arrays
– Memória contígua

Ponteiros para ponteiros
– Encadeamento de referências
Obrigado

leandro@utfpr.edu.br
http://lapti.ct.utfpr.edu.br

Você também pode gostar