Post on 24-Oct-2021
Prof. José Augusto Cintra
http://www.josecintra.com/blog
Com exercícios resolvidos no GITHUB
Introdução à Linguagem de Programação
C
Revisão 2 – Julho/2020 (Quarto mês da quarentena)
Apresentação
Este curso de Introdução à Linguagem C é uma continuação do
curso Algoritmos e & Lógica de programação.
Supõe-se, portanto, que o estudante já possua conhecimento
teórico das estruturas básicas dos algoritmos, bem como noções
sobre os tipos e estruturas de dados elementares como Vetores e
Strings.
Para um melhor aproveitamento do curso acesse os exercícios
resolvidos no GITHUB2
Temporada 1
Conceitos básicos
3
Histórico
Criada por Denis Ritchie na década de
1970 para uso em um computador DEC
PDP-7 em Unix, a linguagem C Foi
baseada na linguagem B, de Kenneth
Thompson.
4
O sistema Unix, assim como a maioria dos software de base foram
escritos em C, que ainda é uma das linguagens mais utilizadas no
mundo, existindo compiladores para praticamente todos os
processadores existentes.
Não confunda C e C++. A segunda é uma extensão orientada a
objetos da primeira e foi criada por Bjarne Stroustrup em 1985.
Ranking das Linguagens
Fonte: Tiobe
5
Ambientes de Desenvolvimento
Existem diversos compiladores e IDEs para a linguagem C. Nestecurso estou utilizando o GCC (The GNU Compiler Collection),pré-instalado na maioria das distribuições LINUX, juntamente coma IDE Geany. A Geany está disponível para sistemas Windowstambém.
Outras opções open source:
Pelles C → Ambiente completo de desenvolvimento, exclusivopara a linguagem C em Windows
Mingw64 → GCC para Windows
My-Dev-CPP→ IDE que inclui o GCC para Windows
Além disso, é possível configurar a maioria das IDEs populares,como o Visual Studio Code, para trabalhar com várioscompiladores C.
6
Estrutura Básica de um Programa C
Um arquivo de código-fonte padrão da linguagem C segue oseguinte esqueleto:
// diretivas para o pré-processamento
// declaração de variáveis globais
main ()
{
// declaração de variáveis locais
// Sequência de comandos
}
A seguir, explicaremos cada uma dessas linhas...
→7
Diretivas de Pré-processamento
Antes de compilar a aplicação, o compilador C realiza algumastarefas iniciais chamadas de etapa de pré-processamento ou pré-compilação.
O desenvolvedor pode então colocar no início do código-fontealgumas instruções chamadas de diretivas.
Essas diretivas possuem o prefixo “#”.
Não é do escopo desse trabalho descrever todas as diretivas, mas voucitar duas delas como exemplo.
A diretiva #define permite definir uma abreviatura conhecida comoMACRO.
Exemplo: #define MAX 100
Dessa forma, o pré-processador vai substituir no código todas asocorrências de MAX por 100.
Pode-se definir abreviaturas que envolvam inclusive comandos dalinguagem C 8
A Diretiva “include”
O núcleo da linguagem C é bem compacto e sua arquitetura émodularizada. Dessa forma, grande parte das funcionalidades sãodefinidas em grupos de arquivos, os quais recebem o nome deBiblioteca Padrão da Linguagem C.
A Diretiva de pré-processamento #include permite incluir umabiblioteca que contenha funções pré-definidas que podem serutilizadas nos programas
Vejamos as principais:
Funções de texto#include <string.h>
Funções matemáticas#include <math.h>
Funções padrão#include <stdlib.h>
Funções de entrada e saída#include <stdio.h>
9
Considerações Sobre o “include”
Uma biblioteca é um conjunto de funções agrupadas em um arquivo fonte. Em C écomum, porém opcional, a criação de arquivos de cabeçalho (extensão .h). Essesarquivos agrupam as definições das funções utilizadas em cada pacote debiblioteca
A diretiva #include é usada para avisar ao compilador que vamos usar umabiblioteca externa no nosso programa. Dessa forma, o código dessa biblioteca éincluído na compilação e seus comandos/funções serão validados e ficarãodisponíveis para utilização.
Exemplo:
#include <stdio.h>
#include “my_library.h”
Quando usamos < >, avisamos ao compilador para procurar o arquivo na pastapadrão das bibliotecas do seu compilador (bibliotecas do sistema).
Quando usamos “ ”, avisamos ao compilador que vamos usar uma bibliotecadefinida pelo usuário ou de terceiros. Nesse caso, o compilador vai procurar nocaminho que está definido dentro das aspas, que pode ser a pasta atual.
10
Comentários
Os comentários, em qualquer linguagem, são inserções explicativas
no código fonte que são ignoradas pelo compilador, mas ajudam a
documentar as aplicações. No entanto, excesso de comentários ou
explicações óbvias, mais atrapalham que ajudam. Por isso use com
moderação e sabedoria.
Em C, os comentários, são identificados por // ou /* */.
Veja:
/*Isto é um comentário ocupando várias
linhas */
// Isto é um comentário de uma linha só
11
// Alô Mundo na linguagem C
#include <stdio.h>
int main()
{
printf("Alô Mundo!");
}
Um programa em C é composto por um conjunto de funções. A função pela
qual o programa começa a ser executado deve chamar-se main.
As chaves {} marcam o início e fim de funções e blocos de código
A função printf, definida em stdio.h, imprime uma expressão no dispositivo
padrão (Tela do Monitor).
As instruções C são sensíveis ao caso. PRINTF é diferente de printf.
Todos os comandos devem terminar com ponto e virgula (;).
Um arquivo de código deve possuir a extensão C. Nesse exemplo, alo.c
Alô Mundo!
12
Comentário
Inclusão da biblioteca de IO
Função principal
Imprime a mensagem
Demarca o início da função principal
Demarca o fim da função principal
Compilando...
Na IDE Geany em Linux ou Windows, o processo de compilação
consiste simplesmente em selecionar a opção Build (Construir) no
menu e depois a opção Execute.
Para quem está usando GCC no Windows e quer compilar “na
mão”:
gcc alo.c –o alo.exe
13
Tipos de Dados
• O modificador UNSIGNED define um número positivo (sem faixa negativa)
• O tamanho do tipo int depende do processador 14
Tipo Tamanho Faixa de valores
char 1 byte -128 até 127
unsigned char 1 byte 0 até 255
signed char 1 byte -128 até 127
int 2 ou 4 bytes -32,768 até 32,767 ou -2,147,483,648 até 2,147,483,647
unsigned int 2 ou 4 bytes 0 até 65,535 ou 0 até 4,294,967,295
short 2 bytes -32,768 até 32,767
unsigned short 2 bytes 0 até 65,535
long 8 bytes -9223372036854775808 até 9223372036854775807
unsigned long 8 bytes 0 até 18446744073709551615 - 6 decimal places
float 4 byte 1.2E-38 até 3.4E+38 - 6 decimal places
double 8 byte 2.3E-308 até 1.7E+308 - 15 decimal places
long double 10 byte 3.4E-4932 até 1.1E+4932 - 19 decimal places
Declaração de variáveis
Diferentemente do Portugol, a variáveis em C podem serdeclaradas em qualquer ponto do programa. Não existe uma áreaVAR para declarações.
Os nomes das variáveis devem conter apenas letras, dígitos ou ounderscore. E devem iniciar com letra ou underscore.
C diferencia letras maiúsculas de minúsculas!
De início, trabalharemos com os tipos abaixo:
Portugol C
inteiro int
real float
15
Declaração de variáveis
Em Portugol
var
media : real
idade : inteiro
Na Linguagem C
float media;
int idade;
16
Obs: O processo de declarar uma variável consiste em definir seunome e tipo de dado. O compilador então irá reservar um espaçona memória de acordo com tipo da variável.
O processo de inicialização é outra etapa e consiste em atribuir umvalor inicial para a variável declarada.
O compilador C, diferente do VisuALG, não inicializa as variáveiscom nenhum valor. Dessa forma as variáveis declaradas noexemplo acima conterão o que chamamos de LIXO em seuconteúdo. Ou seja, CUIDADO, a inicialização precisa ser feitapelo programador
Operação de Atribuição
A operação de atribuição consiste em fornecer um valor para avariável. Como vimos, a declaração apenas reserva um espaço emmemória, sem atribuir nenhum valor. Para atribuir um valor para avariável, usamos o operador de atribuição
O operador de atribuição do C é o sinal de igual (=) que seria oequivalente ao <- do Portugol.
Exemplo:
int idade, nova_idade;
idade = 18;
nova_idade = nova_idade + 1;
Ocorrerá um erro, caso o valor atribuído seja de um tipodiferente do declarado.
Podemos declarar e inicializar a variável no mesmo comando:int idade = 18 17
Operadores de atribuição
Equivale a x = x % yx %= y%=
Equivale a x = x / yx /= y /=
Equivale a x = x * yx *= y *=
Equivale a x = x – yx -= y-=
Equivale a x = x + yx += y +=
Atribui o valor de y a xx = y=
ComentárioExemploOperador
18
Entrada de Dados
O que chamamos aqui de entrada de dados seria a atribuição deum valor para a variável pelo próprio usuário do programa emtempo de execução. Para isso usaremos a função “scanf” que será oequivalente à função “leia” do Portugol.
scanf ("formatos", &var1, &var2,...)
O primeiro parâmetro da função scanf, chamado de string deformato descreve como deve ser convertida a sequência decaracteres da entrada. O prefixo “&” na frente dos nomes davariáveis é um operador de endereço e é obrigatório. Veremos maisdetalhes sobre esse operador quando falarmos de ponteiros
De início, usaremos os seguintes formatos
“%d” → Números inteiro (int)
“%f” → Números de ponto flutuante(float)
19
Entrada de Dados
Em Portugol
Para as variáveis
N1 do tipo inteiro e
N2 do tipo real
leia(N1)
leia(N2)
leia(N1,N2)
Na Linguagem C...
Para as variáveis
n1 do tipo int e
n2 do tipo float
scanf ("%d",&n1);
scanf ("%f",&n2);
scanf (“%d%f”,&n1,&n2);
20
Saída de dados
Para exibir uma expressão no dispositivo padrão (tela docomputador) usaremos a função printf que será o equivalente àfunção escreva do Portugol.
printf ("formatos", var1, var2,...)
Os formatos que usaremos, por enquanto são:
“%d” → inteiro (int)
“%f” → Ponto Flutuante (float)
Obs: Veja que as variáveis do printf não são precedidas de “&”.
21
Saída de Dados
Em Portugol
Para as variáveis
N1 do tipo inteiro e
N2 do tipo real
escreva(N1)
escreva(N2)
escreva(N1,N2)
Na Linguagem C...
Para as variáveis
N1 do tipo int e
N2 do tipo float
printf ("%d“,n1);
printf ("%f“,n2);
printf (“%d%f”,n1,n2);
22
Considerações sobre a Função “printf”
Como vimos, a função printf é usada para imprimir qualquer tipode expressão envolvendo variáveis e constantes literais e aceitaalguns caracteres de controle para formatar a saída. As constantesliterais, como vimos na aplicação Alô Mundo, devem estar entreaspas duplas e podem incluir caracteres ESCAPE de controle quedevem ser precedidos do sinal “\”.
Os principais são:
\n – NewLine = Pula uma linha
\t - Tabulação horizontal = Equivale à tecla TAB
O sinal de % , como vimos, é para formatação de variáveis
Exemplos:
printf(“Alô Mundo\n”); // Imprime a frase e pula linha
printf(“O valor da variável x é igual a %d”,x);
Nesse exemplo, veja que a variável x não está entre aspas e vai serimpressa na posição onde aparece o código %d (inteiros)
23
O tipo de dado char, como vimos representa um único caractere
de texto, mas internamente são tratados como um tipo inteiro de
um byte e, inclusive, podemos realizar operações aritméticas com
eles.
Exemplo:
char c = 'A’;
c++;
printf ("%c \n",c);
printf ("%d \n",c);
Irá imprimir:
B
66
O tipo “char”
24
Veja que valores do tipo char devem
ser delimitados por aspas simples
Imprimindo a variável com o
formato de caracteres
Imprimindo a mesma variável
com o formato de inteiros
Código ASC da letra ‘B’
Somando 1 ao caractere ‘A’
Operações e Operadores matemáticos
Decrementa em 1 o valor de xx----
Incrementa em 1 o valor de xx++++
Resto da divisão de x por yx % y %
Divide x por y x / y /
Multiplica x e yx * y*
Subtrai y de xx – y -
Soma x e yx + y+
ComentárioExemploOperador
25
Exemplo de um Programa C Típico
// Cálculo da média entre 2 números informados pelo usuário
#include <stdio.h>
main()
{
//Declaração de variáveis
float nota1, nota2, media;
//Entrada de dados
printf ("Digite primeira nota: ");
scanf ("%f" ,¬a1);
printf ("Digite segunda nota: ");
scanf ("%f" ,¬a2);
//Processamento
media = (nota1 + nota2) / 2;
// Saída de dados
printf (“A média é igual a %f", media);
} 26Confira mais exercícios resolvidos no GITHUB
Temporada 2
Estruturas de Decisão
27
Estruturas de Decisão
28
São estruturas que, dada a avaliação de uma expressão lógica
(condição), permitem a escolha de um fluxo de instruções a ser
executado
No máximo só podem existir dois fluxos de instruções:
Um, se a condição for Verdadeira, e outro se a condição for Falsa
Para avaliar as expressões, podemos usar os operadores relacionais
e os operadores lógicos
Operadores Relacionais (Comparação)
29
O conteúdo de x é maior que o de y?x > y>
O conteúdo de x é menor que o de y?x < y <
O conteúdo de x é maior ou igual ao de y?x >= y >=
O conteúdo de x é menor ou igual ao de y?x <= y<=
O conteúdo de x é diferente do de y?x != y !=
O conteúdo de x é igual ao de y?x == y==
SignificadoExemploOperador
Importante: Não confunda o operador de atribuição (=) com o
operador comparação por igualdade (==)
&& (E lógico): retorna verdadeiro se ambos os operandos são
verdadeiros e falso nos demais casos.
Exemplo: if (a > 2 && b < 3).
|| (OU lógico): retorna verdadeiro se pelo menos um dos
operandos é verdadeiro, e falso se ambos são falsos.Exemplo: if (a > 2 || b <3).
! (NÃO lógico): usada com apenas um operando. Retorna
verdadeiro se o operando é falso ou vice-versa.
Exemplo: if (!(a > 2)).
As expressões lógicas em C retornam:
0 = Falso
Qualquer outro valor = Verdadeiro.
Operadores Lógicos
30
F ou F → FF e F → F
F ou V → VF e V → F
Não V → FV ou F → VV e F → F
Não V → FV ou V → VV e V → V
Tabela NÃOTabela OUTabela E
Tabela Verdade
31
Em portugol, o
comando de decisão
tem a seguinte
sintaxe:
se <condição> entao
<bloco de comandos>
senao
<bloco de comandos>
fimse
Estrutura de Decisão
Na linguagem C a
sintaxe é esta:
if (<condiçao>) {
<bloco de comandos>
}
else {
<bloco de comandos>
}
32
Observações:
Em C, a condição deve estar entre parênteses;
Não existe a cláusula entao ou fimse;
O bloco de comandos deve estar entre chaves{} (a menos que
seja um único comando);
A cláusula else é opcional;
A expressão é avaliada. Se ela for verdadeira, o bloco if éexecutado. Caso contrário, o bloco do else (se existir) éexecutado;
Lembre-se: Apenas o código associado ao if ou else seráexecutado, nunca ambos.
Estrutura de Decisão
33
// Ler uma idade e determinar se é maior de idade
#include <stdio.h>
main (){
int idade;
printf ("Digite a idade da pessoa: ");
scanf ("%d", &idade);
if (idade >= 18) {
printf ("Pessoa é maior de idade.\n");
} else {
printf ("Pessoa é menor de idade.\n");
}
}
Exemplo “if-else”
34
A estrutura if-else-if em C permite selecionar entre mais de duas Alternativasde decisão.
Exemplo: Determinar se um número é positivo, negativo ou zero (trêsalternativas):
#include <stdio.h>
int main ()
{
int num;
printf ("Digite um numero: ");
scanf ("%d",&num);
if (num>0) {
printf ("O numero e Positivo");
} else if (num == 0) {
printf ("O numero e igual a 0");
} else {
printf ("O numero e negativo");
}
}
Exemplo “if-else-if”
35Confira mais exercícios resolvidos no GITHUB
É uma forma de reduzir a complexidade de decisões encadeadas.
O conteúdo de uma variável é comparado sucessivamente com
um valor constante, e caso a comparação seja verdadeira, um
determinado comando é executado.
switch (variável){
case constante1:
Instruções;
break;
case constante2:
Instruções;
break;
default
Instruções;
}
Estrutura de Decisão “switch case”
36
#include <stdio.h>
main () {
int valor;
printf ("Digite um valor de 1 a 7: ");
scanf("%d", &valor);
switch ( valor ) {
case 1 :
case 7 :
printf ("Fim de semana\n");
break;
case 2 ... 5 :
printf ("Dia de semana\n");
break;
default :
printf ("Valor invalido!\n");
}
Exemplo “switch case”
37
Temporada 3
Estruturas de Repetição
38
São estruturas que permitem executar um trecho de código váriasvezes de acordo com uma condição de parada.
Na linguagem C podemos escolher entre três tipos de estruturas derepetição:
while (avalia a condição no início do laço)
do while (avalia a condição no fim do laço)
for (usada principalmente em contagens)
Como veremos a seguir...
Estruturas de Repetição
39
while (condição){
<blocos de comandos>
}
Não esquecer dos parênteses;
O bloco de comandos será executado enquanto a
condição for verdadeira;
O programador deve cuidar para que a condição fique
falsa em algum momento, do contrário o programa
fica indefinidamente repetindo os comandos.
Estrutura “while”
40
Exemplo “while”
//Exibir números de 1 a 10 usando while
#include <stdio.h>main(){
int cont = 1 ;while(cont <= 10) {
printf ("%d \n", cont); cont++;
}
}
Pergunta: O que vai acontecer se você inicializar a variável contcom o valor 11?
41
do {
<blocos de comandos>
} while (condição);
• Não esquecer dos parênteses;
• Os comandos serão executados pelo menos uma vez. E
continuarão sendo executados enquanto a condição for
verdadeira;
• O programador deve cuidar para que a condição fique falsa em
algum momento, do contrário o programa fica indefinidamente
repetindo os comandos.
Estrutura “do while”
42
Exemplo “do while”
//Exibir números de 1 a 10 usando while
#include <stdio.h>
main(){
int cont = 1 ;do {
printf ("%d \n", cont); cont++;
} while (cont <=10)
}Pergunta: O que vai acontecer se você inicializar a variável contcom o valor 11?
43
for (var=inicio; condição; incremento){
<bloco de comandos>
}
Não esquecer dos parênteses; Os comandos serão executados enquanto a condição for
verdadeira O incremento ou decremento é executado automaticamente
após a execução dos comandos
Estrutura “for”
44
//Exibir números de 1 a 10 usando FOR
#include <stdio.h>
main()
{
int cont ;
for (cont = 1; cont <= 10; cont++ )
{
printf ("%d \n", cont);
}
}
Exemplo “for”
45
E para forçar o término da repetição? Use um break.
Exemplo: Saída:
1
2
3
4
5
Após o FOR: 5
#include <stdio.h>
#include <stdlib.h>
main(){
int i;
for (i=1; i<=10; i=i+1){
printf ("%d\n",i);
if (i==5) break;
}
printf(“Após o FOR: %d\n",i);
}
Comando “break”
46Confira mais exercícios resolvidos no GITHUB
Temporada 3
Estruturas de Dados Básicas
47
As estruturas de dados básicas, disponibilizadas nativamente nalinguagem C são os tipos de dados compostos, que são formadosa partir dos tipos de dados primitivos.
São divididos em Homogêneos, quando compostos de apenas umtipo e Heterogêneos, com tipos de dados diferentes:
Homogêneos: Arrays (Vetores e Matrizes) e Strings (Cadeias decaracteres).
Heterogêneos: Structs (Registros) e Unions (Não abordadanesse curso).
Estruturas de Dados Básicas
48
Vetores (Array)
Um vetor (= array de uma dimensão) é uma estrutura de dados
que armazena uma sequência de valores (variáveis), todos do
mesmo tipo, em posições consecutivas da memória.
Cada elemento do vetor é identificado por sua posição dentro do
vetor (índice do vetor).
São conhecidos como Estruturas de Dados Unidimensionais
Homogêneas. Unidimensionais, pois forma uma sequência
linear de valores consecutivos. Homogêneas, pois todos os
valores são do mesmo tipo
49
Vetores (Arrays)
A quantidade de elementos (tamanho do vetor) e seu tipo devem
ser definidas no momento da declaração e são imutáveis;
Os elementos possuem ordinalidade, cada um pode ser
identificado pela sua posição (índice do vetor);
Em C, os índices dos vetores começam em 0 (zero) e vão até
(tamanho-1)
Cada elemento do vetor, por meio do seu índice, pode ser
acessado como uma variável individual.
No vetor abaixo de nome “idades”, o valor do elemento de índice
4 é 81.
idades
Índices
Valores
50
17 33 21 67 81 10 45 29 79 98
0 1 2 3 4 5 6 7 8 9
Sintaxe: <tipo> <nome> [ tamanho];
Exemplo:
int vet[5];
vet[0] = 3;
vet[1] = 5;
vet[2] = 13;
vet[3] = 10;
vet[4] = 5;
Declaração e Inicialização de Vetores
51
Endereço Conteúdo Índice vet
0022FF74 3 0 vet[0]
0022FF76 5 1 vet[1]
0022FF78 13 2 vet[2]
0022FF80 10 3 vet[3]
0022FF82 5 4 vet[4]
Localização na memória
Nome do vetor
Cada uma
das variáveis
identificadas
pelo índice
Declaração
Inicialização de cada elemento do vetor.
Veja que o índice vai de 0 até tamanho - 1
No exemplo acima,
declaramos e
inicializamos um vetor de
nome vet com
capacidade para 5
números inteiros. Outra
forma rápida de fazer
isso, seria:
int vet[] = {3,5,13,10,5};
Leitura e Escrita de Vetores
Podem ser manipulados como variáveis comuns, bastando indicar
o índice.
Exemplo:
int vet[5];
printf("Digite o valor do primeiro elemento: ");
scanf("%d",&vet[0]);
printf("O valor do primeiro elemento é %d",vet[0]);
52
#include <stdio.h>
int main()
{
int vet[10];
int i = 0;
for(i = 0; i < 5; i++) {
vet[i] = i * 2;
printf(“índice = %d e valor = %d \n",i,vet[i]);
}
} Na tela: Na memória:
Resultado:
Exemplo de Algoritmo com Vetor
53
indice = 0 e valor = 0
indice = 1 e valor = 2
indice = 2 e valor = 4
indice = 3 e valor = 6
indice = 4 e valor = 8
Este exemplo cria um vetor inteiro com 5 elementos
e inicializa cada elemento com o valor do dobro de
seu próprio índice, usando uma estrutura for.
Repetição variando i de 0 até 4
0 1 4 6 8
0 1 2 3 4
Confira mais exercícios resolvidos no GITHUB
De forma abstrata, Uma string é um tipo de dado que representa
um texto, uma palavra ou frase qualquer, ou seja, um conjunto de
caracteres.
A linguagem C não possui um tipo específico para strings. Ao
invés disso uma string é um vetor de caracteres (array of chars)
terminada pelo caractere nulo (\0).
Por exemplo: A string “ALGORITMO” seria representada na
memória como:
Strings
54
A L G O R I T M O \0
0 1 2 3 4 5 6 7 8 9Índices
String
Terminador
As strings em C devem ser inicializadas na declaração, de
modo similar aos vetores, de acordo com os exemplos:
char frase[] = “minha string”;
OU
char frase[13] = “minha string”;
OU
char frase[20] = “minha string”;
OU
char frase[6] = {‘t’, ‘e’, ‘s’, ‘t’, ‘e’, 0};
A operação abaixo NÃO é permitida:
char frase[];
frase = “minha string”;
Declaração e Inicialização de Strings
55
Para ler e imprimir strings podemos usar as funções printf e
scanf com o código de formatação “%s”.
Exemplo:
#include <stdio.h>
main() {
char nome[50];
printf("Digite seu nome: ");
scanf(“%s”,&nome);
printf("Olá %s!",nome);
}
Leitura e Impressão de Strings
56
Cuidado com a função scanf com strings.
Essa função não verifica se a entrada
ultrapassou o tamanho da string.
Uma alternativa para isso é a função fgets
que toma esse cuidado.
A biblioteca padrão da linguagem C, através do header string.h,
oferece uma série de funções para manipulação de strings que.
Citaremos, a seguir as principais:
Função: strlen
Protótipo: int strlen (char *string)
Descrição: Retorna o número de caracteres de uma string (exceto o
caractere de fim de string).
Exemplo:
char nome[] = “José Cintra”;
printf (“O nome possui %d letras”, strlen(nome));
Manipulação de Strings
57
Função: strcpy
Protótipo:
char *strcpy (char *string1, char *string2)
Descrição:
Copia o conteúdo de string2 em string1
Exemplo:
char str1[10];
char str2[] = “Palavra”;
strcpy(str1, str2); // str1 também contém “Palavra”
Manipulação de Strings
58
Função: strcat
Protótipo:
int strcmp (char *string1, char *string2)
Descrição: Compara os conteúdos de string1 e string2 e retorna:
= 0 se string1 = string2
< 0 se string1 < string2
> 0 se string1 > string2
Manipulação de Strings
59
Exemplo:
char nome1[] = “José da Silva”
char nome2[] = “José Silva”;
if (strcmp (nome1, nome2) == 0) {
printf (“Nomes são iguais”);
} else {
printf (“Nomes são diferentes);
}
Função: strcmp
Protótipo:
strcat (char *str_destino, char str_origem)
Descrição: Concatena os conteúdos de string1 e string2
Exemplo:
char primeiro_nome[] = “José”
char sobrenome[] = “da Silva”;
char nome[30] = “”;
strcat(nome, primeiro_nome);
strcat(nome, sobrenome);
printf (“%s\n”, nome);
Manipulação de Strings
60
/* Concatena 2 strings informadas pelo usuário
e exibe a string resultante com o seu tamanho */
#include <stdio.h>
#include <string.h>
main () {
char str1[20],str2[20],str3[40];
int tamanho ;
printf("Informe a string 1: "); scanf("%s",&str1);
printf("Informe a string 2: "); scanf("%s",&str2);
strcat( str3, str1); strcat( str3, str2);
printf("%s\n", str3 );
tamanho = strlen(str3);
printf("Tamanho: %d\n", tamanho );
}
Strings - Exemplo
61Confira mais exercícios resolvidos no GITHUB
Structs são estruturas de dados compostas heterogêneas formadas
por um conjunto de variáveis, possivelmente, de tipos diferentes,
mas relacionadas entre si.
São muito parecidas com registros em tabelas de bancos de dados
e, por isso as variáveis que as compõem são comumente chamadas
de campos.
Sintaxe:
struct <identificador> {
<listagem dos tipos e campos>;
};
Para definir a variável do tipo struct:
struct <identificador> <variavel>;
Structs
62
Uma struct para representar uma pessoa poderia possuir a seguinte
definição:
struct registro_pessoa {
char[50] nome;
float peso;
float altura;
};
Para criar uma variável desse tipo, fazemos:
struct registro_pessoa joao;
Dessa forma, os campos podem ser acessados individualmente, por
exemplo, da seguinte forma:
joao.peso = 72.5;
printf(“%d”,joao.peso);
Structs
63
#include <stdio.h>
#include <string.h>
main() {
struct registro_pessoa {
char nome[50];
float peso;
float altura;
};
struct registro_pessoa joao;
strcpy(joao.nome,"José Cintra");
joao.peso = 72.5;
joao.altura = 1.68;
printf("Nome: %s\n",joao.nome);
printf("Peso: %f\n",joao.peso);
printf("Altura: %f\n",joao.altura);
}
Structs Exemplo
64
Structs são úteis quando utilizadas em conjunto com vetores para
utilização em arquivos ou bancos de dados:
struct registro_pessoa pessoas[10];
strcpy(pessoas[0].nome,"José Cintra");
pessoas[0].peso = 72.5;
pessoas[0].altura = 1.68;
printf("Nome: %s\n",pessoas[0].nome);
printf("Peso: %f\n",pessoas[0].peso);
printf("Altura: %f\n",pessoas[0].altura);
Nesse exemplo atribuímos valores apenas para o primeiro elemento
do vetor. O ideal seria trabalhar com estruturas de repetição para
manipular um grande números de registros.
Vetores de Structs
65
Criando um vetor de
nome pessoas com
10 elementos do tipo
struct
Ponteiros não são estruturas de dados compostas, mas são
importantíssímos para desenvolvermos programas profissionais em
C. Vamos dar uma visão geral sobre eles nesse curso.
Como sabemos, toda variável é armazenada em um local de
memória e todo local de memória tem um endereço bem definido.
Um ponteiro é uma variável cujo valor é o endereço de outra
variável, isto é, o endereço direto da localização da memória.
Existem dois operadores em C para manipularmos ponteiros e
endereços de memória:
Ponteiros
66
Operador Nome Objetivo
* “Derreferência”Retorna o valor armazenado em um endereço da
memória
& Referência Retorna o endereço de memória de uma variável
O operador de “derreferência” pode ser usado também para
declaramos um ponteiro, de acordo com o seguinte exemplo:
#include <stdio.h>
int main () {
int var = 5; // Declaração de uma variável simples
int *ip; // Aqui declaramos um ponteiro para int
ip = &var; // Atribuímos para ip o endereço da variável var
printf("Endereço da variável var: %x\n", &var );
printf("Endereço armazenado na ponteiro ip: %x\n", ip );
printf("Valor armazenado no ponteiro ip: %d\n", *ip );
printf("Valor armazenado na variável var: %d\n", var);
}
Endereço da variável var: 61fe14
Resultado: Endereço armazenado no ponteiro ip: 61fe14
Valor armazenado no ponteiro ip: 5
Valor armazenado na variável var: 5
Ponteiros Exemplo
67
%x é o formato para hexadecimal
em minúsculas
Temporada 3
Funções
68
Funções
Como vimos na apostila de algoritmos, uma função é uma técnica
de modularização que consiste em encapsular um bloco de
código que possui uma determinada funcionalidade de tal modo
que possa ser reutilizado por outros módulos do sistema.
Uma função C possui as seguintes características:
Possui um nome
Pode, opcionalmente, receber parâmetros de entrada de diversos
tipos
Retorna um único valor de um determinado tipo
Pode ser declarada dentro do próprio módulo que a chamou ou
ficar em módulos separados
Pode ser usada em expressões
Sua interface pode ser descritas em protótipos
69
Funções
Uma função em C é definida através da seguinte sintaxe:
<tipo_retorno> <nome_funcao>( [lista_parametros]) {
[corpo da função]
[return valor_retorno]
}
tipo_retorno → É o tipo de dado retornado pela função. Caso a
função não retorne valores, o tipo será void.
nome_função → É o nome da função que deve seguir as regras de
nomeação de identificadores.
lista_parâmetros → consiste na declaração dos parâmetros de
entrada recebidos pela função.
return → Determina o valor que será retornado para o módulo
chamador, quando o tipo do retorno é diferente void.70
Exemplo de uma função sem parâmetros de entrada nem valores de
retorno. Essa função imprime um asterisco na tela
#include <stdio.h>
void imprime() {
printf("*");
}
main () {
imprime();
}
Funções - Exemplos
71
Função sem retorno (void).
Função sem parâmetros de entrada.
Os parênteses são obrigatórios.
Chamada da função no código principal.
A função será executada e o programa
prosseguirá
Vai imprimir:
*
Com a mesma função definida anteriormente, vamos agora chamá-
la 5 vezes pelo programa principal:
#include <stdio.h>
void imprime() {
printf("*");
}
main () {
int i;
for(i = 1; i <= 5; i++){
imprime();
}
}
Funções - Exemplos
72
Vai imprimir:
*****
Vamos agora inverter a lógica. Alteramos a função para imprimir 5
vezes o asterisco. A função será chamada apenas 1 vez pelo
programa principal:
#include <stdio.h>
void imprime() {
int i;
for(i = 1; i <= 5; i++){
printf(“*”);
}
}
main () {
imprime();
}
Funções - Exemplos
73
Vai imprimir:
*****
Agora alteramos a função e colocamos um parâmetro de entrada
para que ela imprima o asterisco o número de vezes solicitado:
#include <stdio.h>
void imprime(int vezes) {
int i;
for(i = 1; i <= vezes; i++){
printf("*");
}
}
main () {
imprime(3);
}
Funções - Exemplos
74
Vai imprimir:
***
O parâmetro inteiro vezes
será usado na repetição for
para determinar o número de
vezes que o texto será impresso
Aqui chamamos a função imprime passando
o valor 3 que será atribuído para o parâmetro
vezes da função
Dessa vez alteramos a função e colocamos um segundo parâmetro
de entrada para que ela imprima qualquer caractere e não mais só o
asterisco:
#include <stdio.h>
void imprime(int vezes, char chr) {
int i;
for(i = 1; i <= vezes; i++){
printf("%c",chr);
}
}
main () {
imprime(7,'@');
}
Funções - Exemplos
75
Vai imprimir:
@@@@@@@
Como vimos até agora, quando trabalhamos com funções existem
dois momentos distintos:
A definição da função (sua assinatura).
A chamada à função que pode ser na função main ou qualquer
outra função do sistema.
Na definição da função podemos especificar os parâmetros que
serão usados no corpo da função
Na chamada da função Podemos passar os valores para os
parâmetros. Esses valores recebem o nome de argumentos.
Argumentos e parâmetros não precisam possuir o mesmo nome
(identificador) mas precisam ser do mesmo tipo.
Vamos ver a seguir um exemplo de função que possui parâmetros
de entrada e valor de retorno e poderemos entender melhor os
conceitos aqui apresentados.
Funções – Parâmetros e Argumentos
76
#include <stdio.h>
// Função que soma dois números passados como parâmetros
float soma(float n1, float n2){
float resultado = n1 + n2;
return resultado;
}
main () {
float v1,v2,r;
printf("Informe o primeiro número: ");
scanf("%f",&v1);
printf("Informe o segundo número: ");
scanf("%f",&v2);
r = soma(v1,v2);
printf("a soma dos números %f e %f é: %f",v1,v2,r);
}
Funções – Parâmetro e Argumentos
77
Aqui definimos uma função de nome soma
com 2 parâmetros do tipo float e retorno do
tipo float.
No corpo da função é calculada a soma
dos parâmetros e o resultado é retornado
para a função main.
Na chamada da função são passados 2 argumentos
do tipo float: v1 é atribuído ao parâmetro n1 e
v2 ao parâmetro n1
O valor de retorno da função soma é atribuído à
variável r
Existem duas formas de passarmos os valores dos argumentos para
os parâmetros das funções:
Passagem por valor: o valor das variáveis dos argumentos não se
alteram, mesmo que os parâmetros sejam modificado na função.
Passagem por referência: Os valores das variáveis dos
parâmetross refletem nos argumentos.
Na linguagem C, as variáveis passadas como argumentos para as
funções são sempre passados por valor e, portanto, seus valores
não são alterados dentro da função.
Para passamos valores por referência, Podemos usar o operadores
de referência (&) que vimos no estudo dos ponteiros. Dessa forma
passamos o endereço da variável.
Passagem por Valor ou Referência
78
#include <stdio.h>
void f(int a, int *b){
a = 2;
*b = 2;
printf("%d\n",a); // Imprime: 2
printf("%d\n",*b); // Imprime: 2
}
main () {
int c = 1;
int d = 1;
f(c,&d);
printf("%d\n",c); Imprime: 1
printf("%d\n",d); Imprime: 2
}
Passagem por Valor ou Referência
79
Neste exemplo, o parâmetro a é passado
por valor e o parâmetro b por referência.
Veja que o valor da variável d foi alterado
pela função f() pois foi passado por referência
O mesmo não aconteceu com a variável
c que foi passada por valor.
O escopo de variáveis tem a ver com o princípio do ocultamento
de informações e permite que as variáveis só possam ser acessadas
de dentro da função que as criou. Isso é mais seguro, pois não
permite que módulos externos interfiram na lógica das funções.
A linguagem C possui os seguintes escopos de variáveis:
Global: São as variáveis declaradas fora de qualquer função e
são acessíveis em todo o Sistema. O tempo de vida dessas
variáveis se encerra quando o programa se encerra.
Local: São variáveis declaradas dentro de uma função ou bloco
de Código e são vistas somente na função/bloco em que foram
declaradas. O tempo de vida dessas variáveis se encerra quando
a função/bloco se encerra
Estática: Variáveis locais que mantém seus valores entre as
chamadas. São identificadas pelo modificador static. Tempo de
vida: “Global”.
Escopo de Variáveis e Tempo de Vida
80
#include <stdio.h>
int a = 1; int b = 1;
void f(){
int c = 2;
static int d = 3;
printf("%d\n",c);
printf("%d\n",d);
c++; d++;
}
main () {
int a = 4; int e = 5;
printf("%d\n",a);
printf("%d\n",b);
//printf("%d\n",c);
//printf("%d\n",d);
printf("%d\n",e);
f(); f();
}
Escopo de Variáveis Exemplo
81
Variáveis a e b são globais, visíveis em todo módulo
Variável c é local e visível somente na função f()
A variável d é local e estática, visível somente
na função f()
Somente a variável d vai ser incrementada, pois
é estática. A variável c vai manter sempre o
mesmo valor
As variáveis a e e são locais,
As variáveis c e d não são acessíveis aqui.
Vai ocorrer um erro. Por isso estão comentados
O valor da variável local a vai prevalecer
sobre a variável global a
As chamadas para a função f() vão mostrar que
somente a variável d será incrementada
Outras considerações:
Parâmetros de funções são variáveis locais.
Variáveis criadas dentro de blocos de códigos são locais.
Exemplo:#include <stdio.h>
int main(int argc, char **argv)
{
int i = 1;
for (int i = 0; i <= 10; i++){
printf("%d\n",i); // O valor final da variável i é 11
}
printf("%d\n",i); // Imprime 1
return 0;
}
Escopo de Variáveis e Tempo de Vida
82
Nesse caso, a variável i declarada
na função main é diferente da variável i
declarada dentro do bloco for
O tempo de vida da variável i do bloco
termina quando termina o for
Vetores são passados, por padrão, por referência. Vamos modificar
a função imprime para receber um vetor de caracteres (uma
string) ao invés de um char:
void imprime(int vezes,char *texto) {
int i;
for(i = 1; i <= vezes; i++){
printf(texto);
}
}
main () {
char str[] = “abc";
imprime(2,str);
}
Passando Vetores como Parâmetros
83
Vai imprimir:
abcabc
Considerações Sobre a Função “main”
A função main é uma função como todas as outras, mas tem um
comportamento especial. Ela é obrigatória em programas
executáveis e indicam o ponto de partida onde a execução do
programa vai iniciar.
Quando a função main se encerra, o programa também se encerra e
o valor de retorno de main será recebido pelo sistema operacional
indicando se o programa executou com sucesso ou não. Um
retorno 0 (zero) indica que o programa foi executado sem erros.
Ela pode receber parâmetros de entrada que representam os
parâmetros da linha de comando passados quando o programa foi
executado. Uma assinatura completa da função main então seria:
int main(int argc, char **argv)
E, no corpo da função main, deve haver um comando de retorno:
return 0;84
Exercícios Propostos1) Um sistema de equações lineares do tipo: pode ser resolvido
segundo:
Escreva um algoritmo em C que lê os coeficientes a,b,c,d,e e f e calcule de x e y.
2) Escreva um algoritmo em C que leia 3 números inteiros e mostre o maior deles.
3) Leia um número N e escreva os N número maiores que N.
Exemplo: N = 4 → escrever: 5,6,7,8
4) Leia um vetor com 5 números inteiros e um número inteiro N. Calcule o produto
escalar entre o número N e o vetor.
5) Escreva uma função em C para verificar se uma palavra informada pelo usuário é
palíndroma ou não. 85
FIMObrigado!
Neste curso fizemos uma pequena introdução à linguagem C com o
objetivo de dar condições ao aluno para se aprofundar nos estudos e
nos assuntos não abordados aqui, tais como:
Aritmética de ponteiros
Headers e protótipos de funções
Estruturas de dados complexas
Manipulação da linha de comando
Etc...
Veja a bibliografia a seguir para mais informações.86
Saiba mais...
Links
https://www.tutorialspoint.com/cprogramming/index.htm
https://www.learn-c.org/
https://www.pucsp.br/~so-comp/cursoc/index.html
https://www.it.uc3m.es/pbasanta/asng/course_notes/ctut.pdf
Livros
Linguagem C, por Luis Damas
C: Como Programar, por Deitel
Exercícios resolvidos
GitHub
http://www.josecintra.com/blog87