Linguagem: ANSI C

Share

Uma linguagem de Alto Nível: ANSI C

A linguagem de programação que utilizaremos para implementar nossos algoritmos será a ANSI C, desenvolvida na década de 70 por Dennis Ritchie. O ANSI C é uma linguagem estruturada muito poderosa e possui compiladores em praticamente todas as arquiteturas existentes.

Este texto não é um curso completo de C e sim apenas uma grande “cola” para quem está fazendo o curso de algoritmos. Para maiores informações sobre a linguagem consulte a bibliografia recomendada nas referências.

A estrutura básica de um programa em ANSI C é:

int main()
{
	Declarações de variáveis</i>
	Comando;
	Comando;
	Blocos de comandos;
}

Quando quisermos utilizar passagem de parâmetros e algum retorno para o sistema operacional, usamos a seguinte estrutura:

int main(int argc, char* argv)
{
	Declarações de variáveis</i>
	Comando;
	Comando;
	Blocos de comandos;
	return 0;
}

3.1 – Tipos básicos

A maioria dos tipos básicos do portugol têm suas representações diretas em ANSI C:

PORTUGOL                       
inteiro: idade;
idade ← 18;

real: peso;
peso ← 56.4;

lógico: aprovado, emCurso;
aprovado ← verdadeiro;
emCurso ← falso;

ANSI C

int idade;
idade = 17;
float peso;
peso = 56.4;
 
int aprovado, emCurso;
aprovado = 1; // Verdadeiro
emCurso = 0; // Falso

3.2 – Conjunto de caracteres

O tipo caractere em PORTUGOL se limita a um tipo no ANSI C representando apenas uma letra: o char para guardar apenas um símbolo. O conjunto de caracteres “string” para se guardar uma seqüência de símbolos será construído posteriormente. Os valores literais para caracteres devem ser delmitados por aspas simples (‘a’) e os literais string por aspas duplas (“palavra”).

PORTUGOL            
caractere: letra;
letra ← "A"           

caractere: nome;
nome ← "Manoel da Silva"

ANSI C

char letra;
letra = 'A';
char[16] nome;
nome = "Manoel da Silva";

As strings são terminadas com um caractere vazio ‘\0’ e por isso quando formos definir uma variável deste tipo, devemos lembrar de adicionar um elemento a mais para este caractere. No nosso exemplo acima, “Manoel da Silva” tem 15 letras, mas a string para guardar este literal tem que ter 16 posições, mas cuidado para não confundir na hora de acessar as letras: o primeiro termo tem o índice 0. Quando passamos uma literal, o próprio C inclui o ‘\0’ para nós.

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
‘M’ ‘a’ ‘n’ ‘o’ ‘e’ ‘l’ ‘ ‘ ‘d’ ‘a’ ‘ ‘ ‘S’ ‘i’ ‘l’ ‘v’ ‘a’ ‘\0’

3.3 – Variáveis

A declaração de variáveis começa pela palavra reservada referente ao tipo e pode ser definida em qualquer parte do bloco de instruções.

int main(){
	int idade;
	float peso;
 
	idade = 18;
	peso = 56.7;
	char aprovado, emCurso;
	aprovado = 1;
	emCurso = 0;
}

3.4 – Constantes

As constantes são um recurso para se evitar incluir literais em seu código. Na prática são variáveis que têm seu valor iniciado apenas no início do programa (em tempo de compilação). São declaradas como variáveis comuns, mas com palavra reservada const antes do tipo.

int main(){
	const float pi = 3.14;
	const char[28] msgErro = 'Dados de entrada inválidos!';
	int idade;
	float peso; 
}

3.5 – Expressões e Operadores

Uma expressão segue combina operandos e operadores para retornar um único valor. A ordem de operadores pode ser descrita pela tabela abaixo:

Operadores Tipo
++
Incremento, Decremento (unários)
() Parênteses
+
Positivo e Negativo (unários)
! Não (unário)
*
/
%
Produto, Divisão e Módulo
+
Adição e Subtração
>
>=
Maior que, Maior ou igual a
<
<=
Menor que, Menor ou igual a
==
!=
Igual a, Diferente de
&&
||
E , OU

No C não temos o operador para potências X**Y. Para isto usaremos uma biblioteca externa math.h que possui uma função pow(base, expoente).

3.6 – Comando de atribuição

O comando de atribuição de valores em ANSI C é o “=” ao invés do “←” do PORTUGOL. Este comando joga o valor do resultado da expressão à esquerda na posição de memória correspondente ao identificador à direita:

PORTUGOL

idade ← 18;
media ← (N1+N2)/2;

ANSI C

idade = 18;
media = (N1+N2)/2;

3.8 – Declaração de entrada e saída

Os comandos de entrada e saída leia() e escreva() devem ser substituídos pelas funções de leitura e escrita formatada: scanf() e printf() da biblioteca stdio.h .

PORTUGOL

leia(idade);                
leia(peso,altura);          
escreva(idade);             
escreva(peso," ",altura);   

ANSI C

scanf("%d", &idade);
scanf("%f %f", &peso, &altura);
printf("%d", idade);
printf("%f %f", peso, altura);

O scanf() com várias variáveis lê os valores digitados no teclado separados por espaço. Para leitura de textos que possuem espaços em seus valores usamos o scanf(“%[^\n]”, &linha) que espera que o ENTER seja pressionado.

E de forma similar, prinft(“\n”) imprime o conteúdo com uma quebra de linha no final.

Para mais detalhes sobre as funções scanf() e printf() confira a apostila.

PORTUGOL

leia(nomeCompleto);        
escreva(idade);            

ANSI C

scanf("%[^\n]", nomeCompleto);
printf("%d\n", idade);

3.9 – Estruturas de controle

As estrutura de controle são praticamente traduções dos comandos em PORTUGOL. Uma seqüência de comandos simples podem ser agrupadas em um único comando pelo chamado bloco de código. Os comandos são escritos separados por “;” e devem estar dentro de um {}.

Condicional

PORTUGOL

se <condição> então     
   comando1;
   comando2;
     ...             
fim-se;

ANSI C

if(condição) {
   comando1;
   comando2;
    ...
}

PORTUGOL

se condição então     
   comando1;          
   comando2;          
     ...                
senão
	comandoA;
	comandoB;
	...
fim-se;

ANSI C

if(condição) {
   comandoA1;
   comandoA2;
    ...
} else {
   comandoB1;
   comandoB2;
    ...
}
escolha <Expressão>
	caso v11,v12,...v1n: C1;
	caso v21,v22,...v2n: C2;
	...
	caso vn1,vn2,...vnn: Cn;
	senão Cs;
fim-escolha;

switch(Expressão){
   case  v11,v12,...v1n:
      comando1;
   break;
   case  v21,v22,...v2n:
      comando2;
   break;
   case  v31,v32,...v3n:
      comando3;
   break;
   case  v41,v42,...v4n:
      comando4;
   break;
   ...
   case  vn1,vn2,...vnn:
      comandoN;
   else
      comandoT;
}

Repetição

PORTUGOL                     
enquanto (condição) 
   comando1;                 
   comando2;                   
     ...                       
fim-enquanto;

ANSI C

while(condição){
   comando1;
   comando2;
   ...
}
repita
   comando1;
   comando2;
     ...
até <condição>
do {
   comando1;
   comando2;
     ...
} while (condição)
                             
para <variável> de <início> até <fim> faça
   comando1;
   comando2;
     ...
fim-para    
for(variável=início; condição; incremento) {
   comando1;
   comando2;
     ...
}

3.10 – Estruturas de dados

Tipo definidos pelo usuário são os vetores, matrizes e registros. O ANSI C dá os recursos para que o usuário crie estas estruturas deixando seus dados em um nível de abstração mais alto, mais próximo da realidade.

Vetores

Um vetor em ANSI C é um tipo de dados declarado pelo programador que agrupa várias variáveis do mesmo tipo em uma única declaração. Cada elemento deve ser referenciado através do índice. Os índices começam de 0.

Em PORTUGOL:
	tipo <identificador> = vetor[<inicio>:<fim>] <tipo>;

	tipo TReais = vetor[1:40] real;
	TReais: notas;
	
	tipo TTextos = vetor[1:40] caracter;
	TTextos: nomes;

Em ANSI C:

float notas[40];
notas[39] = 98.9;
 
char nomes[40][255];
nomes[5] = "Pedro";

Matrizes

Uma matriz em ANSI C é definida como um vetor de mais uma dimensão. Para cada dimensão há um índice associado.

	tipo <identificador> = matriz[d1i:d1f, d2i:d2f, ...] de  <tipo>;
	tipo
		TReais = matriz[1:40, 1:3] de real;
	tipo
		TReais: notas;
float notas[40][4];
notas[23][0] = 100.00;
notas[23][1] = 90.00;
notas[23][2] = 80.00;
notas[23][3] = 100.00;

Registros

Os registros ou estruturas são tipos não homogêneos definidos pelo programador. Devem ser definidos usando o comando struct antes de se ter variáveis declaradas.

Em PORTUGOL:
tipo TPessoa = registro
                 caracter: nome;
                 inteiro: idade;
                 lógico: sexo;
                 real: peso;
               fim-registro;

Em ANSI C:

struct TPessoa {
		char nome[255];
		int idade;
		char sexo;
		float peso;
	<u>}</u>;
struct TPessoa p;

3.11 – Procedimentos e funções

Os procedimentos e funções devem estar definidos antes dos blocos onde serão utilizados e seguem a sintaxe abaixo:

Em PORTUGOL:

procedimento <identificador>(<parâmetros>);
<declaraçao de parâmetros>
início
	C1;
	C2;
	...
	Cn;
fim;

Em ANSI C:

void identificador(tipo parâmetro){
	C1;
	C2;
	...
	Cn;
}

Onde a declaração dos parâmetros é feita como uma definição das variáveis
normal em ANSI C, mas separados por vírgulas “,”. Se o identificador de uma declaração de parâmetro for precedida por um asterísco * este parâmetro é passado por referência e caso contrário, por cópia. Parâmetros passados
por referência podem ter seu valor global ao procedimento alterado, sendo muito utilizados
como variáveis de retorno de procedimentos e funções.

Um função se comporta exatamente como um procedimento, exceto pelo fato de ela própria ter
um valor de retorno. O valor de retorno de uma função é definido dentro do seu corpo quando
se usa o comando return. Este comando é obrigatório em funções mas proibido em procedimentos!

Em PORTUGOL:

função <identificador>(<parâmetros>):<tipo>;
<declaraçao de parâmetros>
início
	C1;
	C2;
	...
	<identificador> ← <valor>;
	...
	Cn;
fim;

Em ANSI C:

tipo identificador(declaraçao de parâmetros){
{
	C1;
	C2;
	...
	...
	Cn;
        return valor;
}

Exemplo:

int somaDosPrimeiros(int n){
    int soma = 0;
    int c;
    for(c = 0; c<n; c++){
        soma = soma+c;
    }
    return soma;
}
Share

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

*