Você está na página 1de 34

Introdução à Programação em Linguagem C

1- Características da Linguagem C:

-É uma linguagem de programação estruturada;


Definição: Programação estruturada é uma forma de se desenvolver programas (um
paradigma da programação) de computadores que aplica nos seus programas
estruturas como:
1- Sequência: As instruções são executadas uma após a outra.
2- Decisão (Seleção): Uso de comandos específicos que, após comparações,
executam outros comandos de acordo com o resultado das citadas comparações.
3- Iteração: Estrutura que realiza repetições sucessivas de um comando ou um
bloco de comandos (ver no glossário a definição de bloco de comandos).

-A linguagem C Foi desenvolvida e implementada por Dennis Ritchie e Brian


Kernighan (entre 1970 e 1978);

-É uma linguagem de médio nível (por combinar elementos das linguagens de alto
nível com as funcionalidades da linguagem assembly);
Obs: Das funcionalidades da linguagem assembly podemos citar: manipulação de
bits, bytes e endereços e, em alguns casos, a implementação de código assembly
dentro de programas em C.

-Atualmente é padronizada (via ANSI: American National Standards Institute);

-Todo comando interno da Linguagem C está definido na língua inglesa. Então, esteja
ciente de que o significado dos referidos comandos só é mais bem entendido após
tradução para o português.

-O seu código é portátil (é possível compilar um mesmo código fonte em C em


diversos compiladores diferentes em sistemas operacionais diferentes).
Obs: Aqui a portabilidade se refere apenas ao código fonte. O executável em geral
não é portátil, pois é executado apenas no sistema operacional para o qual foi
compilado.

-Permite modularização: Um programa pode ser subdividido em funções tornando o


código mais fácil de ser compreendido e de sofrer manutenção.

2-Considerações sobre o desenvolvimento de programas em Linguagem C

2.1-Para o desenvolvimento dos nossos programas vamos utilizar um IDE, que é um


Ambiente de Desenvolvimento Integrado. O seu uso facilita bastante o aprendizado e
o desenvolvimento de programas nesta linguagem.
2.2-O IDE utilizado será o Dev-C++, que poderá ser obtido gratuitamente via Internet.
2.2-Qualquer programa que desenvolvermos será criado através de um projeto
específico no IDE. Portanto para cada programa teremos um novo projeto.

1
3- A estrutura de um programa escrito em Linguagem C:

Todo programa escrito em Linguagem C é fundamentalmente formado por funções e


precisa possuir uma função principal. Esta função principal é o “ponto de entrada”
do programa, ou seja, quando iniciar a execução de um programa, a primeira linha de
código da função principal será executada, depois a segunda e assim sucessivamente
até a última instrução do bloco de comandos dentro da função principal, portanto, em
Linguagem C, assim se escreve, de forma simplificada, a função principal:

main( ) {

ATENÇÃO: a palavra main, que está em inglês, significa principal em português.

Um programa em Linguagem C incui:


-Delimitadores como parênteses e chaves;
-Linhas de comentário;
-Linhas em branco;
-Linhas de comando.

●Delimitadores como parênteses e chaves:


Toda função escrita em C exige um identificador, que é nome da função
seguido de um par de parênteses. O par de parênteses é a forma como identificamos
uma determinada função quando lemos um código em C. Mais adiante será
apresentada uma seção com um estudo bem mais detalhado sobre a programação de
funções em C.
O corpo da função principal é delimitado pelas chaves “{ }”. É entre elas que
deve ser escrito o bloco de código que compõe este corpo.

●Linhas de comentário:
Servem para inserir comentários em qualquer parte do programa.
Auxiliam na documentação de um programa.
São ignoradas pelo compilador no momento da geração do executável, ou seja,
as linhas de comentário não tem ação efetiva sobre a execução de um programa.

A forma de se introduzir diversas linhas de comentário em um programa em C


é colocar o conteúdo do comentário entre os delimitadores /* e */:
Exemplo:

/* Este é um conjunto de
linhas de comentário.
Estas linhas não serão
executadas quando o
programa rodar. */

Para apenas uma linha de comentário, podemos utilizar as barras duplas:


Exemplo:

//Esta é a primeira linha de comentário. Ela não é executada no programa.

2
//Esta é a segunda linha de comentário. Não depende da linha anterior.

●Linhas em branco:
As linhas em branco não são executadas em um programa em C. Servem para
introduzir espaçamento entre as linhas de código, melhorando a sua apresentação
para leitura e manutenção. Programadores bem disciplinados utilizam linhas em
branco para organizar o código dando-lhe um bom aspecto.

●Linhas de comando:
São as linhas que dizem o que o programa deve executar. Sua disposição deve
ocorrer em uma sequência lógica, para fazer corretamente o passo-a-passo do
programa.
A maior parte do nosso estudo sobre a programação em Linguagem C se
concentra em aprender o funcionamento e o uso dos comandos em C.
Uma informação importante: toda linha executável em C deve terminar com um
ponto e vírgula “ ; ”.

Palavras reservadas em C: As palavras apresentadas a seguir são consideradas


reservadas para uso exclusivo na linguagem C. Estas palavras já têm uma aplicação
específica dentro de um programa em C e não devem ser utilizadas para nenhuma
outra finalidade. Um erro muito comum é o programador usar estas palavras para dar
nome a variáveis e funções.

4- Funções para saída e entrada de dados em C:


Após sabermos que um programa em C se organiza em torno da função
principal main( ), vamos agora aprender uma função de muito uso em C: o printf( ).

4.1-A função de saída formatada printf():


A printf( ) é uma função de saída de dados na Linguagem C. Qualquer
informação que se deseje apresentar na interface de saída do usuário pode ser
através do uso do printf( ). Isso para programas definidos como aplicações de
console escritas em Linguagem C.

Esta função tem a seguinte sintaxe:

printf (“cadeia_de_formatação”, arg1, arg2, ..., argN);

3
Onde:
cadeia_de_formatação: é formada por cadeias de caracteres e códigos
especiais (os especificadores de formato e caracteres de controle). É esta cadeia que
gera a forma da apresentação de frases na tela do usuário.
arg1, arg2, ..., argN: são os argumentos dos especificadores de formatos
que, na verdade, são valores ou variáveis do programa os quais queremos que sejam
exibidos em tela para o usuário. O número de argumentos se apresenta na mesma
quantidade em que colocamos especificadores de formato na cadeia de formatação.
Outro ponto bastante importante é que, na Linguagem C, a função printf( ) é
definida dentro da biblioteca stdio e esta informação precisa ser passada ao
compilador para que, durante o processo de geração do programa executável, a
função printf( ) possa ser encontrada e não ocorrendo erro de compilação pela sua
falta. Este recurso será implementado mais adiante, no primeiro programa em
Linguagem C.

Para se construir uma cadeia_de_formatação utilizamos os especificadores


de formato apresentados na Tabela 1.

Tabela 1- Especificadores de Formato.

Os especificadores de formato exibem, na tela do computador, os tipos de


dados descritos na sua representação.
A Tabela 2 mostra os caracteres de controle que também podem ser inseridos
na cadeia_de_formatação. Os carecteres de controle causam efeitos na apresentação
conforme descrito nesta tabela.

Tabela 2 – Caracteres de Controle.


4
4.2-A função de entrada scanf():
A scanf( ) é uma função de entrada de dados na Linguagem C. Os seus
parâmetros estabelecem o formato de entrada e os valores introduzidos, pelo teclado,
são atribuídos ás variáveis presentes na lista de parâmetros

Esta função tem a seguinte sintaxe:


scanf (“%d %c”, x , y );
Onde:
● %d e %c: São especificadores de formatos conforme a Tabela 1, já
apresentada, observando que ao contrário de exibir, a variável associada a este
especificador receberá este valor, em uma operaçãode escrita, dos dados que vêm do
teclado.
● x e y: São as variáveis que receberão os dados de entrada. A variável x
receberá um valor do tipo numérico e a variável y receberá um valor do tipo caractere.

Observe que, quanto mais caracteres especificadores de formato, igual número


de variáveis para receber esses tipos de dados scanf() terá.
A função scanf() também é definida na biblioteca stdio, então o arquivo de
cabeçalho stdio.h precisa ser incluído através da diretiva #include antes da função
main(). Isso para todos os programas que usam a função scanf().

5- Escrevendo um programa em Linguagem C:


Agora estamos prontos para experimentar tanto o uso da função pricipal
main(), no desenvolvimento de aplicação escrita em Linguagem C, como o uso da
importante função printf( ) para exibir valores (ou resultados) nas aplicações
desenvolvidas, o Exemplo 1 apresenta uma pequena aplicação desenvolvida apenas
com estes recursos.
Exemplo 1:
//Para usar a função printf() é preciso incluir, usando a diretiva #include,
//o arquivo de cabeçalho stdio.h. Se não for incluído, ocorre erro de compilação:
#include <stdio.h>

main() {
//Exibe a string "Caractere :" e o caractere 'A'
//e o cursor vai para o início da outra linha.
printf("%s %c\n", "Caractere :", 'A');

//Exibe o número 703 em três bases diferentes:


// Octal, Decimal e Hexadecimal
//Obs.: Em cada printf() o cursor vai para o
// início de uma nova linha.
printf("O numero 703 em base octal: %o\n", 703);
printf("O numero 703 em base decimal: %d\n", 703);
printf("O numero 703 em base hexadecimal: %x\n", 703);

//Observe que se utilizarmos o especificador de formato %x,


// a função printf() exibe as "letras" dos números hexadecimais
// em caracteres minúsculos e, se o especificador for %X, a
// exibição ocorre em caracteres maiúsculos:
printf("O numero 703 em base hexadecimal: %X\n", 703);
}
5
Exemplo 2:
Este é um exemplo de programa em C, que faz uso da função scanf() e da
função printf():

#include <stdio.h>

main() {
char nome[120];
int idade;
float altura;

printf("Qual o nome: ");


scanf("%s", &nome);
printf("\nForneca a idade: ");
scanf("%d", &idade);
printf("\nForneca a altura: ");
scanf("%f", &altura);

printf("\n\nExibindo os dados de entrada:\n");


printf("Nome: %s\n", nome);
printf("Idade: %d anos\n", idade);
printf("Altura: %3.2f m\n", altura);
}

6-Tipos de Dados, Operadores e Comandos utilizados em C:


Após ensaiarmos uma preliminar de programação em Linguagem C, agora
estamos quase preparados para experimentar outros tipos de exercícios desta
programação.
Antes de começar será preciso saber que tipos de dados e de comandos
poderiam ser escritos dentro da função principal main( ).

6.1-Tipos de Dados:
Na linguagem C existem diversos tipos de dados que podem ser manipulados
por um programa.

6.1.1-Dados Básicos ou Primitivos:


São aqueles que já vêm definidos na linguagem, ou seja, o programador não
precisará defini-los.
Na linguagem C são cinco os tipos de dados básicos, mostrados na Tabela 3.

Tipo de Dado Significado Tamanho Escala


char caractere 1 byte -128 até +127
int inteiro 2 bytes −32768 até +32767
float flutuante 4 bytes 3.4e−38 até 3.4e+38
double duplo 8 bytes 1.7e−308 até 1.7e+308
void sem valor nenhum sem valor
Tabela 3- Tipos básicos de Dados em C.

ATENÇÃO: Ao escrever números reais em C utilizar sempre o ponto como o


separador da parte decimal.

6
6.1.1.1- Declarando Variáveis em C:
A declaração de variáveis em C é útil para que se possam ter locais onde os
dados do programa sejam armazenados, operados e manipulados na execução de
um programa.
As variáves declaradas são criadas como posições de memória onde esses
dados ficam armazenados e disponíveis para o programa em execução.
Para a declaração de variáveis utiliza-se a sintaxe apresentada a seguir:

<tipo> <identificador>;
Onde:
tipo: é o Tipo de Dado da Tabela 3.
e
identificador: é iniciado com letra (maiúscula ou minúscula) e ser
composto exclusivamente por letras, dígitos e sublinhas.

Seguem os exemplos de declaração de variáveis.

Exemplo 3: Declaração de variável do tipo caractere:

char carac1; //Declaração da variável do tipo char, identificada por carac1.


carac1 = 45; //Atribuição do valor 45 à variável carac1.

Exemplo 4: Declaração de variável do tipo caractere com atribuição direta do código


ASCII do caractere A:

char carac2 = ‘A’; //Declaração da variável do tipo char, identificada por carac2.

Exemplo 5: Declaração de variável do tipo inteiro:

int inteiro1; //Declaração da variável do tipo int, identificada por inteiro1.


inteiro1 = 120; //Atribuição do valor 120 à variável inteiro1.

Examplo 6: Declaração de variável do tipo inteiro com atribuição direta de valor:

int inteiro2 = 200; //Declaração da variável do tipo int com identificador inteiro2.
//e atribuição direta do valor 200.

Exemplo 7: Declaração de variável do tipo float:

float flut1; //Declaração da variável do tipo float, identificada por flut1.


flut1 = 10.723; //Atribuição do valor 10.723 à flut1.

Exemplo 8: Declaração da variável do tipo double:

double doub1; // Declaração de variável do tipo double, identificada por doub1.


doub1 = 10.723e30 //Atribuição do valor 10.723x10³º à variável doub1.

7
As atribuições de valores a variáveis não se dá apenas na base decimal. Um
programador poderá desejar atribuir valor a uma variável em base binária, octal ou
mesmo hexadecimal. O exemplo 9 apresenta as sintaxes para cada caso:

Exemplo 9: Atribuindo números de bases diferentes a variáveis:

#include <stdio.h>
#include <stdlib.h>

main() {
int x;

//Atribuição de um número na base binária a x:


//Um número binário é precedido de 0b.
x = 0b1011000011001010;
printf("x = %X\n", x);

//Atribuição de um número na base hexadecimal a x:


//Um número em hexadecimal é precedido de 0x.
x = 0xB0CA;
printf("x = %X\n", x);

//Atribuição de um número na base octal:


//Um número octal é precedido apenas de 0.
//ATENÇÃO: Em C, escrever 0123 é diferente de 123.
x = 0130312;
printf("x = %X\n", x);
}

É importante observar que na declaração de quaisquer variáveis sempre é


possível de se fazer atribuição direta de valores. Alguns autores chamam esta prática
de “inicializar a variável”.

6.1.1.2-Declarando constantes em C:
Uma constante é um valor fixo que não sofre alteração durante toda a
execução de um programa. Um exemplo típico de constante é o valor de
, empregado na geometria e na trigonometria. Se um programa tem que
usá-lo, devemos declará-lo como constante.
A declaração de uma constante traz algumas vantagens como: evitar se
escrever valores com muitos dígitos além de identificar a constante por um nome, fato
que facilita a leitura e a manutenção do programa.
Uma constante é declarada no início do programa, conforme a sintaxe
apresentada abaixo (uso da diretiva de pré-processador #define). Observe que neste
tipo de linha de comando não existe o ponto e vírgula (pois se existisse ele seria
interpretado como parte da constante):

#define <nome_da_constante> <valor>

8
Exemplos:

#define PI 3.14159265

#define FORMATO “Variável x = %d\n”

Exemplo 10: Formatando a saída de dados através de uma constante:


#include <stdio.h>
#include <stdlib.h>

#define FORMATO "Valor de x=%d\n"

main() {
int x=251;

printf(FORMATO, x);
}

Resultado da execução:

6.1.2-Tipos de Dados Modificados:


A linguagem C também permite que se declarem tipos de dados
modificados. A Tabela 4 mostra os seus detalhes.

Tipo Modificado Significado Tamanho Escala


unsigned char caractere sem sinal 1 byte 0 até 255
unsigned int inteiro sem sinal 2 bytes 0 até 65535
long int inteiro longo 4 bytes-2.147.483.648 até
+2.147.483.647
Tabela 4- Tipos de Dados Modificados em C.

ATENÇÃO: O bit mais significativo (mais à esquerda) de um caractere ou de um


inteiro funciona como um bit de sinal. O computador usa este bit para saber se o valor
da variável é positivo ou negativo. Observe a figura seguinte:

9
Signed: o compilador
considera o bit de sinal. Variável do tipo char:
Conta de -128 até +127.

Unsigned: o compilador
não considera o bit de
sinal. Conta de 0 até
255.

6.2-Tipos de Dados Agregados:


Na linguagem C é possível de se criar estruturas de dados que reúnam
conjuntos de dados que sejam:

1-Do mesmo tipo: chamadas Homogêneas (representadas por de Vetores ou


Matrizes).

2-De tipos diferentes: chamadas de Heterogêneas (Representadas por


Registros). ATENÇÃO: Podemos criar Vetores ou Matrizes cujos elementos sejam
Registros.

6.2.1-Declarando Tipos de Dados Homogêneos (Vetores e Matrizes):

Matrizes são multidimensionais, ou seja, possuem dimensões que podem até


ultrapassar espaços tridimensionais. Sua declaração em C segue a seguinte sintaxe:

<tipo> <identificador>[x1] [x2] ... [xn];


Vetores são unidimensionais, ou seja, só possuem uma linha (ou uma coluna).
São casos particulares de matrizes e a sua declaração em C segue a seguinte
sintaxe:
<tipo> <identificador>[x];
Exemplo 11-Declarando em C a matriz bidimensional de inteiros representada
pela figura:

A matriz de inteiros possui 5 linhas e 6 colunas, então:

int M [5] [6]; //Declarando a matriz M: Sem introduzir dados.

Ao declararmos a matriz M podemos introduzir os dados da seguinte forma:

10
int M[5][6] = { { 1, 2, 3, 4, 5, 6}, //Declarando a Matriz M e
{ 7, 8, 9, 10, 11, 12}, // introduzindo os inteiros
{13, 14, 15, 16, 17, 18}, //(dados).
{19, 20, 21, 22, 23, 24},
{25, 26, 27, 28, 29, 30} };

Observe que esta é uma forma um tanto trabalhosa de se declarar e iniciar os


valores de uma matriz. Adiante será visto um método que inclui comandos de
repetição para tornar esta tarefa mais prática.

Exemplo 12-Declarando em C o Vetor de inteiros representado pela figura:

O vetor possui seis valores inteiros

int v[6]; //Declarando o vetor sem valores.

Declarando o vetor e inserindo os valores inteiros:

Int v[6] = { 1, 2, 3, 4, 5, 6 };

6.2.2-Declarando Tipos de Dados Heterogêneos (Registros):

Imagine uma variável que comporte mais de um tipo de dados. São os


registros.
Na Linguagem C é preciso antes construir um tipo de dado para o registro. A
este tipo de dado do registro damos o nome de “estrutura”
As estruturas permitem com que possamos construir tipos de dados utilizando
conjuntamente os tipos primitivos (ou básicos) de dados já estudados anteriormente.
Para esta criação utiliza-se a palavra reservada para esta finalidade “struct”.
A criação de uma estrutura em C é feita utilizando a seguinte sintaxe:

struct <nome_da_estrutura>{
<tipo1> var1;
<tipo2> var2;

<tipoN> varN;
};

Após a criação da estrutura é possível de se criar variáveis que sejam


registros, conforme o seguinte:

<nome_da_estrutura> <nome_do_registro>;

Confira no Exemplo 13 a forma de se definir, na Lingaugem C, um registro com o uso


de uma estrutura:
Exemplo 13:

Vamos definir um tipo de dado que tenha a forma do seguinte registro:

11
struct Aluno{
char nome[100];
int matricula;
float nota;
};

Observe e analise a construção do tipo de dado registro apresentado. Nesta


análise você deve perceber o emprego do termo struct no início da definição da
estrutura, seguido do nome da estrutura, as variáveis, e seus respectivos tipos, que
servem de “campos” da estrutura. É importante observar o emprego das chaves e
também quando e onde empregar o ponto e vírgula “ ; ” na construção desses tipos
de dados.
Agora vamos criar a variável do registro para Aluno:

struct Aluno alu1;

Com isso cria-se apenas um registro para se manipular com apenas um aluno,
ou seja, a variável alu1 do tipo struct Aluno é um registro para aluno.
E se fosse uma turma com trinta alunos, como poderia ser feito tal criação?
Veja no Exemplo 14:

Exemplo 14:
Criando um vetor cujos elementos têm a forma da estrutura Aluno:

struct Aluno turma1[30];

Pode parecer estranho, mas quando declaramos variáveis que empregam os


tipos básicos utilizamos apenas um termo como: char, int ou float para identificar o
tipo. Tudo bem que com tipos modificados há a presença dos modificadores de tipos
acrescentando mais uma palavra na especificação do tipo de dado.

Na Linguagem C existe uma maneira de se criar termos únicos que


representem outros conjuntos de termos. Isso simplifica a escrita de um programa da
seguinte forma: ao invés de se digitar duas ou mais palavras é possível resumi-las em
apenas uma palavra: usando comando typedef, é possível de se criar um “apelido”
(ou “alias”) para um conjunto de termos. O Exemplo 15 apresenta a aplicação deste
comando.

12
Exemplo 15:
main() { //2-Podemos então declarar uma
//1-Se não declarássemos uma struct própria e // Estrutura assim:
//necessitássemos de criar várias variáveis
//(registros) com o formato da struct, struct EstrA{
//deveria então ser feito assim: char letra;
int numero;
struct { };
char letra;
int numero; main() {
} r1; //E criar as variáveis de registro assim:

struct { struct EstrA r1;


char letra;
struct EstrA r2;
int numero;
} r2; struct EstrA r3;
}
struct {
char letra;
int numero;
} r3;
}

Continuação do Exemplo 15: O uso do typedef:


O typedef tem a seguinte sintaxe:
typedef texto_a_ser_substituido novo_nome;

//3-Se o typedef for utilizado,


//a escrita do tregho de código
//se simplifica ainda mais:

typedef struct{
char letra;
int numero;
} EstrA;

main() {
//E criar as variáveis de registro assim:

EstrA r1;

EstrA r2;

EstrA r3;
}

13
6.2.2.1- Acessando os membros de uma struct (Uso do operador ponto “ . ”):
Quando um tipo struct é declarado como variável, para que possamos ter
acesso aos membros (campos ou variáveis) de uma struct, ou seja, ler os dados ou
escrever dados nesses campos utiliza-se o operador ponto (“ • “). Observe o Exemplo
16:

Exemplo 16:

#include <stdio.h>
typedef struct{
char letra;
int numero;
} EstrA;
main() {
//Emprego do operador ponto para leitura e escrita dos membros de uma estrutura:
//Declarando os registros:
EstrA r1;
EstrA r2;
EstrA r3;
//Uso do operador ponto para escrita nos membros dos registros r1, r2 e r3:
r1.letra='R'; //Cracteres são declarados entre apóstrofos.
r3.numero=15;
r2.letra='A';
r1.numero=12;
r2.numero=10;
r3.letra='K';
//Leitura dos membros de um registro:
printf("Registro r1:\n\tletra: %c\n\tnumero: %d\n\n", r1.letra, r1.numero);
printf("Registro r2:\n\tletra: %c\n\tnumero: %d\n\n", r2.letra, r2.numero);
printf("Registro r3:\n\tletra: %c\n\tnumero: %d\n\n", r3.letra, r3.numero);
}

6.2.2.2 - O endereço de memória onde fica uma variável declarada:


Ao se executar um programa que foi escrito em C, as variáveis declaradas
possuem nomes pelo qual os seus programadores as acessam. Tais nomes são
representações simbólicas dos endereços de memória onde elas são armazenadas e
que são úteis apenas na fase da programação. Depois que o programa for compilado,
no momento da sua execução, esses nomes se tornam na verdade números que
indicam a posição real da memória física onde está a referida variável. Na Linguagem
C, a maneira de se saber este número é utilizar o “&” que é chamado de operador de
endereço. Veja o seguinte exemplo com programa e mapa de memória:

14
Exemplo 17: Lendo o endereço de uma variável:

#include <stdio.h>

main() {
//Criando duas variáveis:
char x= 'A';
int y= 10;

//Exibindo o endereço
//das duas variáveis:
printf("O caractere x = %c esta no endereco: %X\n", x, &x);
printf("O inteiro y = %d esta no endereco: %X\n", y, &y);
}

E na figura abaixo o resultado da sua execução: É importante lembrar que o valor


22FEBFH não será o mesmo em diferentes computadores, uma vez que isso depende
das aplicações que tiverem sido carregadas na máquina antes da execução da
aplicação Dev-C++.

6.2.2.3 - Ponteiros:
Conforme foi dito, variáveis em C são nomes simbólicos para referenciar
endereços de memória que armazenam dados. Ponteiros também são variáveis,
porém estas armazenam apenas valores que são endereços de memória.

Os ponteiros representam outra forma, que não seja através de uma variável
declarada, de se acessar os dados que estão na memória do computador. Eles
permitem acesso a qualquer parte da sua memória, bastando que o endereço
armazenado no ponteiro seja definido pelo programador. Com isso, a
responsabilidade do programador em gerenciar ponteiros é bem maior devido à sua
complexidade. Um acesso indevido, principalmente para atribuição (escrita) de um
dado, por um endereço de memória atribuído de forma errada ao ponteiro, pode
provocar diversos problemas, tais como:

- perda de dados.
- paralização de programas.
- danos à execução do Sistema Operacional.

15
Ponteiros são declarados da mesma forma como variáveis, diferenciando-se
apenas na indicação do ponteiro que usa o operador asterisco “ * “.
Após a sua declaração e antes da sua utilização, os ponteiros precisam ser
inicializados com o valor do endereço para onde apontam, isto significa que o
programador tem que atribuir ao ponteiro um valor de endereço de um local de
memória já definido. Há diversas formas de se atribuir valores de endereços a
ponteiros:
- Utilizar o endereço de variáveis já declaradas empregando o operador de
endereço &.
- Utilizar funções de alocação dinâmica de memória (ver seção 6.2.2.4).
- Utilizar atribuição de um valor já conhecido direto ao ponteiro (menos usual).

No exemplo seguinte é mostrado como é feita a declaração e a utilização de


ponteiro:
Exemplo 18:
#include <stdio.h>

main() {
int i=10; //Declaração da variável.
int *p; //Declaração do ponteiro p.
p=&i; //Atribuição de endereço ao ponteiro p.

printf("Conteudo do ponteiro: p= %X\n", p);


printf("Conteudo apontado: *p= %d\n", *p);
printf("Conteudo da variavel i= %d\n", i);
printf("Endereco da variavel i: %X\n", &i);
}
Resultado da execução: Observe que a variável i e *p (fala-se: o conteúdo apontado
pelo ponteiro p), por fazerem referência ao mesmo endereço de memória, têm o
mesmo conteúdo.

6.2.2.4 - A alocação dinâmica de memória:


A implementação da alocação dinâmica de memória em C é caracterizada
por:
-Permitir reservar e liberar espaços de memória de qualquer tamanho.
-Sua reserva ser limitada à disponibilidade de memória do computador.
-Ser feita através de funções específicas para esta finalidade que retornam o
endereço do início do bloco de memória alocado, que em geral é atribuído a um
ponteiro pelo programador.

16
Funções de alocação dinâmica de memória:
As funções de alocação dinâmica de memória atendem ao programador e à
aplicação em dois passos:
1º Passo: Encontram o endereço da quantidade de memória solicitada no
parâmetro da função.
2º Passo: Retornam este endereço para quem chamou (geralmente sendo
atribuído a um ponteiro).

Em C as funções relacionadas à questão da alocação dinâmica são:


-malloc( ):Reservar espaço de tamanho definido na memória.
-calloc( ):Reservar espaço de tamanho definido na memória
preenchendo com zeros.
-realloc( ): Redimensionar um espaço já definido por malloc.
-free( ): libera um espaço de memória

As sintaxes de cada uma dessas funções são:

(tipo *) calloc ( Número_de_elementos , Tamanho do elemento );

(tipo *) malloc ( Tamanho_da_área_de_memória);

(tipo *) realloc ( Ponteiro, Novo_tannho);


Os exemplos seguinte apresenta o uso dessas funções (observe o emprego da
função sizeof( ) para definir o tamanho da alocação)

Exemplo19:

Para que seja possível explorar mais espaço em memória é necessário que se
saiba manipular os parâmetros das funções malloc e calloc. O exemplo seguinte
mostra formas de se definir espaços de memória maiores com auxílio da função
sizeof ( ).

17
Exemplo20:

6.2.2.5- Acessando os membros de uma struct (Uso do operador seta “->”):


Na seção 6.2.2.1 falou-se do acesso aos membros de uma struct pelo uso do
operador ponto. Quando se declara uma struct em um ponteiro, o operador de
acesso aos membros da struct é o operador seta (“->”).
Declarar qualquer objeto com base em um ponteiro exige que o ponteiro esteja
associado a uma área de memória definida. Então é comum que, algumas vezes,
quando são declarados ponteiros, seja utilizada a alocação dinâmica de memória.
Então, nesta linha de raciocínio, observe o exemplo seguinte, que apresenta
uma struct declarada como ponteiros e a alocação de espaço de memória para cada
um deles:
Exemplo 21:
#include <stdio.h>

typedef struct{
char letra;
int numero;
} EstrA;

main() {
//Emprego do operador seta para leitura e escrita dos membros de uma estrutura:
//Declarando os registros:
EstrA *p1;
EstrA *p2;
EstrA *p3;

//Necessário alocação de memória, pois a declaração de ponteiro não


//aloca espaço como na declaração de variáveis:
p1=malloc(sizeof(EstrA));
p2=malloc(sizeof(EstrA));
p3=malloc(sizeof(EstrA));
18
//Uso do operador seta para escrita nos membros dos registros nos ponteiros
// p1, p2 e p3:
p1->letra='R';
p3->numero=15;
p2->letra='A';
p1->numero=12;
p2->numero=10;
p3->letra='K';

//Leitura dos membros de um registro:


printf("Registro *p1:\n\tletra: %c\n\tnumero: %d\n\n", p1->letra, p1->numero);
printf("Registro *p2:\n\tletra: %c\n\tnumero: %d\n\n", p2->letra, p2->numero);
printf("Registro *p3:\n\tletra: %c\n\tnumero: %d\n\n", p3->letra, p3->numero);
}

Resultado da execução:

7- Os Operadores na Linguagem C:

Estão disponíveis na Linguagem C, os seguintes operadores:


-Atribuição;
-Aritméticos;
-De comparação;
-De deslocamento de bits;
-Lógicos;

7.1-Operador de Atribuição:
É o sinal de igualdade ( = ). A sua função é atribuir um valor a uma variável ou
memória.
Após a declaração de uma variável, na maioria das vezes, armazenamos
valores nas mesmas, ou seja, usamos um operador de atribuição para fazê-lo.
Exemplo 22:
int comprimento; //Declaração da variável comprimento.
comprimento = 15; //Atribuição do valor 15 à variável comprimento.

7.2- Operadores Aritméticos:


Implementam, em linha de comando, operações matemáticas como adição,
subtração, multiplicação, divisão, módulo(resto), incremento e decremento.

19
Estes operadores estão relacionados na Tabela 5:

Tabela 5 – Operadores Aritméticos empregados na Linguagem C.

Exemplo 23:
Problema: Utilizando operadores como atribuição e aritméticos, faça um
programa em C que converta um número inteiro de base decimal em um número em
base binária com 8 bits. O número binário deverá ser armazenado em um vetor de
inteiros, onde cada elemento do vetor representa um bit do número binário.

#include <stdio.h>
#include <stdlib.h>

main() {
int nB10 = 13; //Número em base decimal
int bit[8]={0,0,0,0,0,0,0,0}; //Composição do número binário

//Método de conversão:
bit[0] = nB10%2;
bit[1] = (nB10/2)%2;
bit[2] = (nB10/4)%2;
bit[3] = (nB10/8)%2;
bit[4] = (nB10/16)%2;
bit[5] = (nB10/32)%2;
bit[6] = (nB10/64)%2;
bit[7] = (nB10/128)%2;

printf("%d em binario e: %d%d%d%d%d%d%d%d\n",


nB10, bit[7], bit[6], bit[5], bit[4],
bit[3], bit[2], bit[1], bit[0] );
}

20
Combinando operadores aritméticos e atribuição:
Algumas “abreviaturas” práticas são obtidas na Linguagem C com a
combinação entre os operadores aritméticos e o operador de atribuição, os quais são
apresentados na Tabela 6:

Tabela 6 – Operadores de atribuição associados à aritmética em C.

7.3-Operadores de Comparação:
Os operadores de comparação são operadores binários, ou seja, necessitam
de dois operandos para realizarem as suas operações que comparam tais operandos
avaliando-os através de igualdade, se um é maior, se um é menor, se maior ou igual,
se menor ou igual, ou mesmo se são diferentes.

A Tabela 7 relaciona os operadores de comparação empregados na


Linguagem C:

Tabela 7 – Operadores de Comparação em C.

7.4-Operadores de deslocamento de bits:


São operadores que transferem os bits das suas posições para as posições à
esquerda ou à direita. A Tabela 8 apresenta a relação desses operadores, seguido de
exemplos.

21
Tabela 8 – Operadores de Deslocamento de Bits.

O resultado destas operações é exemplificado no quadro abaixo:

Observe estes outros exemplos e tire as suas conclusões:

22
Exemplo24: Operações de deslocamento de bits à direita e à esquerda e os seus
efeitos:

#include <stdio.h>
#include <stdlib.h>

main() {
char a = 0b00001000;//Número em base binária.

printf("a= %d\n\n", a);


printf("Deslocando 2 bits para a esquerda\n\n");
a<<=2;
printf("a= %d\n\n", a);
printf("Cada bit deslocado para esquerda, multiplica o numero por 2.\n\n");
printf("Deslocando 3 bits para a direita\n\n");
a>>=3;
printf("a= %d\n\n", a);
printf("Cada bit deslocado para direita, divide o numero por 2.\n");
}

Resultado da execução:

7.5-Operadores Lógicos (sobre bits):


Servem para realizar operações lógicas com e, ou, ne, nou, xou, etc...
A Tabela 9 resume os operadores lógicos básicos. Observe que para se obter
ne, ou nou, é preciso a combinação do complemento com o operador E ou o
operador Ou.

23
Tabela 9 – Operadores de Lógicos sobre Bits.

Exemplo 25: Adaptando o programa do exemplo 23, podemos verificar o


funcionamento dos operadores lógicos sobre bits.

24
Resultado da execução do exemplo:

8-O controle de fluxo na linguagem C:


Na linguagem C o controle de fluxo é realizado por algumas estruturas
definidas, relacionadas abaixo:
-Comando if
-Comando switch
-Comando for
-Comando while
-Comando do
-Comando break
-Comando continue
8.1-O comando if:
O comando if compõe uma estrutura de decisão que controla o fluxo de um
programa, permitindo a execução condicional de outros comandos.

Há duas formas de empregá-lo:

1-Na sua forma mais simples:

if ( condição ) comando; ou {bloco de comandos}


Onde o comando (ou o bloco de comandos) será executado se a condição for
verdadeira.

2-Na sua forma completa (uso do comando else):

If ( condição ) comando1; ou {bloco de comandos 1}


else comando2; ou {bloco de comandos 2}

Nesta forma o comando 1 ou o bloco 1 vai ser executado apenas se a condição


for verdadeira, do contrário o comando 2 ou o bloco 2 será executado.

Vamos aos exemplos:

25
Exemplo 26: Uso do comando if na sua forma simples:

#include <stdio.h>
#include <stdlib.h>

main() {
int num;

printf ("Digite um numero: ");


scanf ("%d",&num);

if (num>10) printf ("\n\nValor maior que 10");


if (num==10){
printf ("\n\nOk! O valor e igual a 10.");
}
if (num<10) printf ("\n\nValor menor que 10");
return(0);
}

Exemplo 27: Uso do comando if na sua forma completa (chamado if-else):

#include <stdio.h>
#include <stdlib.h>

main() {
int num;

printf ("Digite um numero: ");


scanf ("%d",&num);

if (num>10) printf ("\n\nValor maior que 10");


else {
printf ("\n\nOk! O valor e menor ou igual a 10.");
}

return(0);
}

Exemplo 28: Há também uma variação do comando if na forma if-else-if, que é uma
extensão do if-else. Veja o exemplo:

#include <stdio.h>
#include <stdlib.h>

main() {
int num;

printf ("Digite um numero: ");


scanf ("%d",&num);

if (num>10) printf ("\n\nValor maior que 10");


else if (num==10) printf ("\n\nO valor e igual a 10.");
else if (num<10) printf ("\n\nO valor e menor que 10.");

return(0); 26
}
8.2-O comando switch:
O comando switch também é comando de decisão. Sua aplicação ocorre
quando se deseja testar uma variável para diversos valores. O switch tem a seguinte
estrutura:
switch ( variável )
{
case valor1:
declaração1; ou {bloco1}
break;
case valor2:
declaração2; ou {bloco2}
break;

case valorN:
declaraçãoN; ou {blocoN}
break;
default:
declaraçãoDefault; ou {blocoDefault}
}

Observa-se que o comando switch emprega o comando break. O funcionamento e


emprego do comando break é apresentado na seção 8.6.

Exemplo 29: Comando switch empregado como “filtro” para diversos números:
#include <stdio.h>
#include <stdlib.h>

main() {
int num;
printf ("Digite um numero: ");
scanf ("%d",&num);

switch(num)
{
case 1:
printf("Numero 1\n");
break;
case 2:
printf("Numero 2\n");
break;
case 3:
case 4:
printf("Numero 3 ou 4\n");
break;
default:
printf("Numero diferente de 1, 2 e 3\n");
}

return 0;
}
27
8.3-O comando for:
É uma estrutura de repetição controlada. Serve para repetir um comando ou
um bloco de comandos. O seu formato é:

for ( inicialização ; condição ; incremento ) comando; ou {bloco de comandos}

Exemplo 30: Utiliza um comando de repetição for para exibir os números inteiros de 1
até 10:

Resultado da execução:

Outras aplicações do comando de repetição for:

8.3.1- O loop infinito, com o seguinte formato:

for ( inicialização ; ; incremento ) comando; ou {bloco de comandos}

É um loop ou laço que não tem fim, a falta da condição é considerada como
verdadeira e o comando ou o bloco de comandos será executado indefinidamente.

28
Exemplo 31: Loop infinito interrompido ao se pressionar a tecla ‘A’ ou a tecla ‘a’:

8.3.1-O loop for vazio ou for sem conteúdo (temporizador):


É um loop que não executa comando algum, pois não há declarações. É útil
quando se deseja temporizar a execução de algum trecho do programa.
O formato deste loop é:

for ( inicialização ; condição ; incremento );

Exemplo 32: Um loop que atrasa o fim do programa:

8.4-O comando while:


O comando while também é uma forma de se implementar loops em C. A
condição de verificação é feita antes da execução de qualquer comando inserido no
loop. A sua sintaxe é a seguinte:

while ( condição ) comando; ou {bloco de comandos}

29
Exemplo 33: Uso do while: Exibindo números de 1 a 10.

8.4.1- Criando loops infinitos com o comando while:


Para se criar loops infinitos com o while, basta fazer a condição ser sempre
verdadeira. Se este estado não mudar a execução fica “presa” no loop.

Exemplo 34: Loop infinito com while. Observe que neste exemplo o aprisionamento
da execução no loop é interrompido pelo comando break, quando a condição c==’A’
ou c==’a’ é fornecida.

Exemplo 35: Loop infinito com while. A saída do loop depende da mudança do valor
da variável x, que ocorre após a tecla A ser pressionada.

30
8.5-O comando do-while:
O comando do-while é utilizado para a implementação de loops. Neste caso, a
verificação da condição é feita sempre após a execução do(s) comando(s) inseridos
no loop, ou seja, pelo menos uma vez o comando ou bloco de comandos é
executado. Sua sintaxe é:

do{
comando1;
comando2;

comandoN;
} while (condição);

Exemplo 36: Uso do do-while: Exibindo números de 1 a 10.

8.5.1- Loop infinito com o comando do-while:


A sua implementação também requer a condição dentro dos parêntesis do
while sempre verdadeira.

Exemplo 37: Um loop infinito com do-while. O programa só termina quando a tecla
ESC é presionada. Qualquer outra tecla pressionada é mostrada na tela.

31
8.6-O comando break:
Serve para interromper uma iteração (ou repetição: comandos for, while e do-
while) e também serve para separar (interromper) os “cases” do comando switch.

Exemplo 38: Emprego do comando break de um forma diversificada. Observe que há


situações em que a sua ausência é aplicável. Neste exemplo, a se digitar uma vogal o
tratamento será o mesmo. A tecla ESC termina o programa e, por isso, recebe
tratamento especial. As demais teclas são tratadas pela condição default. Outros
exemplo de emprego do comando break já foram apresentados anteriormente.

8.7-O comando continue:


Serve para avançar para a próxima iteração, ignorando os comandos que o
sucedem. Geralmente o comando continue é utilizado dentro de uma condição na
iteração.

Exemplo 39: Neste exemplo a sequência 1 2 3 4 5 e 10 é exibida. O intervalo 6 7 8 e


9 não é exibido por ação do comando continue.

32
Resultado da execução do exemplo 39:

33
Glossário

Assembly: Linguagem de programação utilizada pelos microprocessadores.

Assember (ou Montador Assembly): Nome do programa que serve para “montar”
(transformar o código assembly em linguagem de máquina) um programa escrito em
linguagem assembly.

Bloco de Comandos: É um conjunto delimitado de linhas de código que reúne


diversos comandos em uma sequência lógica.

Biblioteca (de funções): Conjuntos de arquivos que reúnem todas as funções


disponíveis em determinada linguagem de programação. Algumas linguagens
permitem que os usuários criem as suas próprias bibliotecas (prática recomendada
pelas boas práticas da Engenharia de Software por viabilizar grandemente a
reutilização de código).

Compilador: É um ou um conjunto de programas que, partindo de um código fonte de


uma linguagem (textual), definida como compilada, cria um programa equivalente em
outra linguagem, geralmente um código dito objeto, ou seja, ou compilador traduz o
código de uma linguagem textual que os humanos entendem para uma linguagem de
máquina que funciona em um processador específico.

IDE (Integrated Development Environment = Ambiente de Desenvolvimento


Integrado): É a reunião de um conjunto de ferramentas de software, ou seja,
programas, em única aplicação que, ao ser utilizado, apresenta um ambiente de
desenvolvimento como um editor para a escrita de programas em uma linguagem
específica e também possui um compilador para tornar o programa desenvolvido
executável. Um IDE pode incorporar também ferramentas de ajuda à programação
que aceleram o desenvolvimento das aplicações como aquelas que auxiliam no
desenvolvimento de interfaces do usuário através de janelas.

Iteração: repetição; programa de repetição; iterar em computação significa: executar


várias vezes a mesma sequência de comandos.

Interação: (Derivado do Latim onde: inter=entre; ação=ato) Ação que ocorre


mutuamente entre duas ou mais coisas. Influência recíproca entre dois elementos,
objetos ou pessoas.

Loop (ou Laço): Termo largamente empregado na informática referindo-se a um


trecho de um programa que é responsável pela execução de forma repetida (iterativa)
de um comando ou bloco de comandos.

34

Você também pode gostar