Skip to content

hatsumi2301/CStudies

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Estudos da linguagem C

Estou usando como guia de estudos o livro "C completo e total". Terceira edição. Herbert Schildt.

Printf

O printf imprime textos na tela.

Para utilizar a função printf, é necessário importar a biblioteca <stdio.h> com o comando #include <stdio.h>.

Utilização

Caso deseje imprimir valores de variáveis, é necessário utilizar especificadores de conversão.

Valor Exemplo
texto printf("<texto>")
char printf("%c", '<char>')
int printf("%d", <int>)
float printf("%f", <float>)
double printf("%f", <double>)
pointer printf("%p", <pointer>)
long unsigned decimal integer printf("%lu", <long_unsigned_decimal_integer>)

Constantes de caracteres de barra invertida são utilizados para imprimir determinados elementos:

Código Significado
\b Retrocesso (BS)
\f Alimentação de formulário (FF)
\n Nova linha (LF)
\r Retorno de carro (CR)
\t Tabulação horizontal (HT)
\" Aspas duplas
\' Aspas simples
\0 Nulo
\\ Barra invertida
\v Tabulação vertical
\a Alerta (beep)
\N Constante octal (onde N é uma constante octal)
\xN Constante hexadecimal (onde N é uma constante hexadecimal)

Exemplos de printf

Método O que faz
void Saida(void) Imprime o texto "Olá mundo!"

Scanf

O scanf obtém dados digitados pelo teclado.

Para utilizar a função scanf, é necessário importar a biblioteca <stdio.h> com o comando #include <stdio.h>.

Utilização

Caso deseje colocar valores em variáveis, é necessário utilizar especificadores de conversão.

Valor Exemplo
char scanf("%c", &<char>)
int scanf("%d", &<int>)
float scanf("%f", &<float>)
double scanf("%f", &<double>)

Exemplos de scanf

Método O que faz
void EntradaNumero(void) Obtém um número digitado pelo teclado
void EntradaTexto(void) Obtém um texto digitado pelo teclado

Variáveis

Variável é um espaço na memória para guardar um determinado dado.

As variáveis locais devem ser declaradas no início do bloco em que elas são definidas.

Os nomes das variáveis devem ser únicos em cada contexto. Um contexto pode ser uma função, um arquivo (caso a variável seja static veremos esse conceito mais para frente) ou até mesmo o programa inteiro (caso a variável seja do tipo global, também estudaremos mais adiante).

Modificando os tipos básicos

Modificador Descrição
signed Valores positivos e negativos
unsigned Apenas valores positivos
long Faixa de valor maior
short Faixa de valor menor

Tipos de variáveis com seus modificadores

Tipo bits Faixa mínima
char 8 -127 a 127
unsigned char 8 0 a 255
signed char 8 -127 a 127
int 16 -32.767 a 32.767
unsigned int 16 0 a 65.535
short int 16 -32,767 to 32,767
unsigned short int 16 0 a 65.535
long int 32 -2.147.483.647 a 2.147.483.637
unsigned long int 32 0 a 4.294.967.295
float 32 seis dígitos de precisão
double 64 dez dígitos de precisão
long dougle 80 dez dígitos de precisão

Exemplos de variáveis

Método O que faz Observações
void TiposDeVariaveis(void) Tipos de variáveis em C -
void NomeDaVariavel(void) Esse método possui uma variável com o nome x Os métodos NomeDaVariavel(), NomeDaVariavelRepetido() e NomeDaVariavelRepetidoEmOutraClasse() possuem uma variável com nomes iguais. Os dois primeiros métodos estão na mesma classe e o último em uma classe separada.
void NomeDaVariavelRepetido(void) Esse método possui uma variável com o nome x Os métodos NomeDaVariavel(), NomeDaVariavelRepetido() e NomeDaVariavelRepetidoEmOutraClasse() possuem uma variável com nomes iguais. Os dois primeiros métodos estão na mesma classe e o último em uma classe separada.
void NomeDaVariavelRepetidoEmOutraClasse(void) Esse método possui uma variável com o nome x Os métodos NomeDaVariavel(), NomeDaVariavelRepetido() e NomeDaVariavelRepetidoEmOutraClasse() possuem uma variável com nomes iguais. Os dois primeiros métodos estão na mesma classe e o último em uma classe separada.

Loops

Loops, também conhecidos como laços, são repetições de um determinado trecho do código que obedece uma determinada condição.

Tipos de loops:

Loop Pseudocódigo Utilização
for Enquanto (valor_inicial até a condição_final passo n) faça
Inicio
     Instruções
Fim

valor_inicial é uma instrução de atribuição do valor inicial do laço para a variável de controle
condição_final é a condição que controla o laço
passo é o incremento ou decremento do laço
for(valor_inicial; condição_final; valor_incremento_ou_decremento){
     Instruções;
}
while Iniciar a variável de controle
Enquanto (condição) faça
Início
     Instruções;
     Atualizar a variável de controle;
Fim;

condição é a condição que controla o laço
while(condição){
     Instruções;
}
do ... while Iniciar a variável de controle
Início
     Instruções;
     Atualizar a variável de controle;
Enquanto (condição) faça
Fim;

condição é a condição que controla o laço
do{
     Instruções;
}while(condição)

Exemplos de loops

Método O que faz Observações
void VerificarCaractereNaString(void) Obtém uma palavra e um caractere como dados de entrada, informados pelo usuário e verifica se a palavra contém o caractere informado -
int VerificarCaractereNaString2(char *s, char c) Verifica se a palavra contém a letra. Os dados devem ser passados como parâmetros. Retorna 1 se a palavra contém a letra e 0 se a palavra não contém a letra. Exemplo VerificarCaractereNaString2("teste", "e") verifica se a palavra "teste" contém a letra "e"
void LoopFor(void) Loop do tipo for -
void LoopWhile(void) Loop do tipo while -
void LoopDoWhile(void) Loop do tipo do...while -
void DiferencaEntreLoopWhileAndDoWhile(void) Exemplo da diferença entre os loops while e do...while -

Condicionais

Verifica se uma determinada condição é verdadeira ou falsa para executar o código dentro do contexto da mesma.

Tipos de condicionais

if, else e else if.

Exemplos de condicionais

Método O que faz Observações
void Condicionais(void) Condicionais if, else if e else Informar o número 1 para executar o comando do if, informar o número 2 para executar o comando do else if e informar qualquer outro número para executar o comando do else

Variáveis globais

Variáveis globais são reconhecidas pelo contexto global do programa e podem ser utilizadas em qualquer parte do código. Se a variável global for utilizada em outra classe do código, deve-se utilizar o extern para sinalizar que a variável é global. Elas estão acessíveis durante toda a execução do programa.

Utilização

Basta declarar a variável fora de qualquer função e ao utilizar em outra classe, declarar a variável com o extern.

Exemplos de variáveis globais

Método O que faz
void FuncaoQueUtilizaAsVariaveisGlobais(void) Utiliza a variável x global que foi declarada na mesma classe que o método
void FuncaoQueUtilizaAsVariaveisGlobais2(void) Utiliza as variáveis x e y globais que foram declaradas em outra classe
void FuncaoQueUtilizaAsVariaveisGlobais3(void) Utiliza a variável y global que foi declarada em outra classe

Modificadores de tipo de acesso

const

O uso do const no parâmetro de entrada do método, faz com que o código da função não seja capaz de modificar o objeto apontado pelo parâmetro. Apenas um evento externo pode modificar uma variável do tipo const.

Exemplos de const

Método O que faz
void VariavelDoTipoConst(const char *frase) Troca os espaços da frase por "-" e imprime a frase com a modificação, ou apenas imprime a frase inteira

volatile

O modificador volatile é usado para informar ao compilador que o valor de uma variável pode ser alterado de uma maneira não explicitamente especificada pelo programa. Exemplo, um endereço de uma variável global pode ser passado para a rotina de relógio do sistema operacional e usado para guardar o tempo real do sistema.

Exemplos de volatile

Método O que faz
void VariavelDoTipoVolatile(void) Esse método altera o valor da const por meio de um ponteiro

Especificadores de tipo de classe de armazenamento

extern

C permite que módulos do programa sejam compilados separadamente e por conta disso é necessário que haja uma maneira de informar a todos os arquivos sobre as variáveis globais solicitadas pelo programa. Ao declarar a variável global em um determinado arquivo e utilizar ela em outro, será necessário usar o extern, para indicar que aquela é uma variável global.

Exemplos de extern

Método O que faz Observações
void FuncaoQueUtilizaAsVariaveisGlobais2(void) Utiliza as variáveis x e y globais que foram declaradas em outra classe Esse método está na classe do Capítulo 05
void FuncaoQueUtilizaAsVariaveisGlobais3(void) Utiliza a variável y global que foi declarada em outra classe Esse método está na classe do Capítulo 05

static

Ao declarar uma variável como static, o compilador cria um armazenamento permanente para ela quase da mesma forma que cria um armazenamento para uma variável global.

Com variáveis estáticas é possível preservar um valor entre as chamadas das funções.

Poderiam ser utilizadas variáveis globais no lugar de variáveis estáticas, no entanto, haveriam outras preocupações. Toda vez que a função é usada, seria necessário lembrar-se de declarar a variável global (como extern) e garantir que ela não conflite com nenhuma outra variável global já declarada.

Elas não são reconhecidas fora de sua função ou arquivo, mas mantém seus valores entre chamadas. Uma variável global estática é apenas reconhecida no arquivo no qual a mesma foi declarada.

Exemplos de static

Método O que faz
void IniciarSerie(int semente) Inicializa a variável estática global
int Serie(void) Utiliza a variável estática global para somar um valor à ela
int VariavelEstatica(void) O número vai ser inicializado com o valor 10 somente na primeira execução, pois a variável estática continua existindo após a função ser finalizada. A variável não é destruída e na segunda chamada dessa função, a variável já vai ter seu valor inicializado.

register

Os objetos são colocados nos registradores da CPU. Portanto, o acesso ao objeto é o mais rápido possível.

São usadas onde são feitas muitas referências a uma mesma variável.

Só é possível aplicar o especificador register a variáveis locais e parâmetros formais (os parâmetros da função na sua declaração são chamados parâmetros formais. Na chamada da função os parâmetros são chamados parâmetros atuais/reais) de uma função.

As variáveis register podem ser armazenadas em um registrador da CPU e podem não ter endereços.

Exemplos de register

Método O que faz
int EspecificadorRegister(register int m, register int e) Exemplo em um loop de um especificador register

Operadores

Atribuição

nome_da_variavel = expressão

Conversão de tipos em atribuições

Situação em que variáveis de um tipo são misturadas com variáveis de outro tipo.

Regra de conversão: valor do lado direito é convertido no tipo do lado esquerdo.

Tipo do destino Tipo da expressão Possível informação perdida
signed char char Se valor > 127, o destino é negativo
char short int Os 8 bits mais significativos
char int Os 8 bits mais significativos
char long int Os 24 bits mais significativos
int long int Os 16 bits mais significativos
int float A parte fracionária e possivelmente mais
float double Precisão, o resultado é arredondado
double long double Precisão, o resultado é arredondado

Exemplos de tipos em atribuições

Método O que faz
void ConversaoTiposDeValores(void) Conversão de tipos de valores

Atribuições múltiplas

C permite que você atribua o mesmo valor a muitas variáveis usando atribuições múltiplas em um único comando.

Utilização

tipo variavel1 = ... = variaveln = valor

Exemplos de atribuições múltiplas

Método O que faz
void AtribuicoesMultiplas(void) Atribuições múltiplas

Operadores aritméticos

Operador Ação Observação
- Subtração, também menos unário -
+ Adição -
* Multiplicação -
/ Divisão -
% Módulo da divisão (resto) Não pode ser usado nos tipos em ponto flutuante
--x Decremento Subtrai 1 ao seu operando
x = x - 1 imediatamente e aplica na linha atual.
x-- Decremento Subtrai 1 ao seu operando
x = x - 1, mas aplica o resultado após a linha atual.
++x Incremento Soma 1 ao seu operando
x = x + 1 imediatamente e aplica na linha atual.
x++ Incremento Soma 1 ao seu operando
x = x + 1, mas aplica o resultado após a linha atual.

Exemplos de operadores aritméticos

Método O que faz
void Subtracao(void) Subtrai 1 de 2
void Adicao(void) Soma 2 e 1
void Multiplicacao(void) Multiplica 2 e 1
void Divisao(void) Divide 4 por 2
void Modulo(void) Calcula o módulo de 5 por 2 e o módulo de 1 por 2
void Incremento(void) Exemplo de incremento
void Decremento(void) Exemplo de decremento

Operadores relacionais e lógicos

Operador relacional refere-se às relações que os valores podem ter uns com os outros.

Operador Ação
> Maior que
>= Maior que ou igual
< Menor que
<= Menor que ou igual
== Igual
!= Diferente

Operador lógico refere-se às maneiras como essas relações podem ser conectadas.

Operador Ação
&& AND
| OR
! NOT

Embora C não tenha um operador lógico OR exclusivo, é possível criar uma função que execute essa tarefa usando os outros operadores lógicos.

Operadores lógicos e relacionais podem ser verdadeiros ou falsos. Falso é igual a 0 e verdadeiro é qualquer valor diferente de 0.

p q p AND q p OR q !p
0 0 0 0 1
0 1 0 1 1
1 1 1 1 0
1 0 0 1 0

Precedência relativa

Operador
Maior !
> >= < <=
== !=
&&
Menor ||

Exemplos de operadores relacionais e lógicos

Método O que faz
void MaiorQue(void) Exemplos de maior que
void MaiorQueOuIgual(void) Exemplos de maior que ou igual
void MenorQue(void) Exemplos de menor que
void MenorQueOuIgual(void) Exemplos de menor que ou igual
void Igual(void) Exemplos de igual
void Diferente(void) Exemplos de diferente
int xor(int a, int b) Método de ou excluviso
void PrintXor(void) Imprime o resultado de alguns valores utilizando o ou exclusivo

Operador bit a bit

Testar, atribuir ou deslocar os bits efetivos em um byte ou uma palavra, que correspondem aos tipos de dados char e int e variantes do padrão.

Operações bit não podem ser usadas em float, double, long double, void ou outros tipos mais complexos.

Operações bit a bit encontram aplicações mais frequentemente em "drivers"de dispositivos - como em programas de modems, rotinas de arquivos em disco e rotinas de impressoras - porque as operações bit a bit mascaram certos bits, como o bit de paridade (confirma se o restante dos bits em um byte não se modificaram, é normalmente o bit mais significativo em cada byte).

São frequentemente usados em rotinas de criptografia.

Operador Ação
& AND
| OR
^ OR exclusivo (XOR)
~ Complemento de um
>> Deslocamento à esquerda
<< Deslocamento à direita

Tabela verdade

A B A & B A | B A ^ B ~A
0 0 0 0 0 1
0 1 0 1 1 1
1 0 0 1 1 0
1 1 1 1 0 0

Deslocamentos

Desloca x bits para a direita ou esquerda, podendo ocorrer a perda de algum bit nesse deslocamento.

unsigned char x cada execução da sentença valor de x
x = 7 00000111 7
x = x << 1 00001110 14
x = x << 3 01110000 112
x = x << 2 11000000 448
x = x >> 1 01100000 224
x = x >> 1 00011000 112

Exemplos de operadores bit a bit

Método O que faz
void And(void) Exemplo do operador AND
void Or(void) Exemplo do operador OR
void Xor(void) Exemplo do operador XOR
void ComplementoDeUm(void) Exemplo do operador complemento de um
void Deslocamentos(void) Exemplo do operador deslocamento à direita e à esquerda
char Codificar(char) Recebe um caractere e devolve o complemento de um desse caractere

Operador ternário

O operador ternário é equivalente à um if com else.

expressão1 ? expressão2 : expressão3

expressão1 é avaliada e se ela for verdadeira, expressão2 é avaliada e se torna o valor da expressão, senão, expressão3 é avaliada e se torna o valor da expressão.

Utilização

x = 10;

y = x > 9 ? 100 : 200;

Esse código é equivalente a:

x = 10;

if(x > 9) y = 100;

else y = 200;

Exemplos de operador ternário

Método O que faz
void OperadorTernario(void) Exemplo de operador ternário
void ExemploComIfElseOperadorTernario(void) O mesmo exemplo do método acima, mas com if e else

Ponteiros

Ponteiro é um endereço na memória de uma variável. Uma variável de ponteiro é uma variável especialmente declarada para guardar um ponteiro para seu tipo especificado.

Funções

  • Fornecer uma maneira rápida de referenciar elementos de uma matriz.

  • Permite que funções em C modifiquem seus parâmetros de chamada.

  • Suportam listas encadeadas e outras estruturas dinâmicas de dados.

Operador de ponteiro *

Operador unário que devolve o valor da variável localizada no endereço que o segue.

Utilização

  • ch é um ponteiro

    char *ch;
  • y é um ponteiro

    int x, *y, count;

Operador de ponteiros &

Operador unário (que utiliza apenas um operando) que devolve o endereço na memória de seu operando.

Utilização

m = &count;

m recebe o valor do endereço na memória da variável. Posição interna da variável no computador.

Exemplos de operadores de ponteiros

Método O que faz
void OperadoresPonteiros(void) Exemplo de operadores de ponteiros

Operador sizeof

Operador em tempo de compilação unário que retorna o tamanho, em bytes, da variável ou especificador de tipo, em parênteses, que ele precede.

Exemplos de operadores sizeof

Método O que faz
void GravarDisco(int rec[6], FILE *fp) Escreve 6 inteiros em um arquivo em disco

Operador ponto e seta

Referenciam elementos individuais de estruturas e uniões.

Ponto é usado quando se está referenciando a estrutura.

Seta é usado quando um ponteiro para uma estrutura é usado.

Exemplos de operadores ponto e seta

Método O que faz
void OperadoresPontoSeta(void) Atribui o valor 123.23 ao elemento salario da estrutura trab

Delimitadores com operadores

Parênteses são delimitadores que indicam o aumento da precedência das operações dentro deles.

Colchetes são utilizados para indicar a indexação de uma matriz.

Precedências

Todos os operadores, com exceção de operadores unários e ?, associam da esquerda para a direita.

Operadores unários *, &, - e ? associam da direita para a esquerda.

Precedência Elemento
Maior () [] ->
! ~ ++ -- - (tipo) * & sizeof
* / %
+ -
<< >>
< <= > >=
== !=
&
^
!
&&
| |
?
= += -= *= /=
Menor ,

Exemplos de parênteses e colchetes

Método O que faz
void Array(void) Exemplo de um array (operação utilizando colchetes)
void Parenteses(void) Exemplo de como os parenteses alteram a ordem de execução das operações

Expressões

Ordem de avaliação: o padrão C ANSI não estipula que as subexpressões (expressões dentro de uma expressão) de uma expressão devam ser avaliadas em uma ordem especificada.

Por exemplo, x = f1() + f2(); não garante que f1() vai ser executada antes de f2().

Conversão de tipos

O compilador C converte todos os operandos no tipo do maior operando, o que é denominado de promoção de tipo.

SE um operando é long double ENTÃO o segundo é convertido para long double

SE um operando é double ENTÃO o segundo é convertido para double

SE um operando é float ENTÃO o segundo é convertido para float

SE um operando é unsigned long ENTÃO o segundo é convertido para unsigned long

SE um operando é long ENTÃO o segundo é convertido para long

SE um operando é unsigned int ENTÃO o segundo é convertido para unsigned int

Caso especial

SE um operando é long E o segundo é unsigned int E SE valor de unsigned int não pode ser representado por um long ENTÃO os dois operandos são convertidos para unsigned long

Exemplos de conversão de tipos

Método O que faz
void ConversaoDeTipos(void) Exemplo de conversão de tipos

Casts

Forçar expressão a ser de determinado tipo.

Utilização

(tipo) expressão

Exemplos de casts

Método O que faz
void Cast(void) Exemplo de uma divisão de um número inteiro sem utilizar o cast e utilizando o cast

C Reduzido

Algumas operações podem ser escritas de maneira reduzida em C.

x = x + 10;

pode ser escrito de uma maneira reduzida:

x += 10;

+= atribui a x o valor de x mais 10.

Essas operações existem para todos os operadores binários em C.

var = var operador expressão

é equivalente a

var operador = expressão

Exemplos de operações reduzidas

Método O que faz
void SomaReduzida(void) Exemplo de uma soma reduzida
void SubtracaoReduzida(void) Exemplo de uma subtração reduzida
void MultiplicacaoReduzida(void) Exemplo de uma multiplicação reduzida
void DivisaoReduzida(void) Exemplo de uma divisão reduzida
void ModuloReduzido(void) Exemplo de um módulo reduzido

Condicional

if e else (opcional), switch e ? .

If e ?

if e ? são comandos condicionais.

O comando else sempre se refere ao comando if mais próximo, que está dentro do mesmo bloco do else e não está associado a outro if.

Exemplo de else

if(i){
    if(j) comando1;
    if(k) comando2; //Este if
    else comando3; //está associado a este else
}
else comando4; //Associado ao if(i)

Utilização

  • If e else
if(expressão1) comando1;
if(expressão2) comando2;
else if(expressão3) comando3;
else comando4;

Se a expressão1 for verdadeira, o comando1 será executado.

Se a expressão2 for verdadeira, o comando2 será executado.

Se a expressão2 for falsa, a expressão3 vai ser verificada. Se a expressão3 for verdadeira, o comando3 será executado.

Se a expressão3 for falsa, será executado o comando4.

  • Operador ternário
expressao1 ? comando1 : comando2

Se a expressao1 for verdadeira, então o comando1 será executado, senão o comando2 será executado.

Exemplos de if e ?

Método O que faz Observações
void AdivinharONumero(void) Utiliza o if e o else para verificar se o usuário adivinhou o número gerado aleatoriamente pelo programa -
void AdivinharONumeroComIfElseIf(void) Utiliza o if e o else if para verificar se o usuário adivinhou o número gerado aleatoriamente pelo programa -
void AdivinharONumeroComOperadorTernario(void) Utiliza o operador ternário ? para verificar se o usuário adivinhou o número gerado aleatoriamente pelo programa -
void CalcularQuadradoDeUmNumeroComOperadorTernario(void) Utiliza o operador ternário ? para calcular a raiz quadrada de um número -
void OperadorTernarioComFuncoes(void) O operador ternário também pode ser utilizado chamando funções Utiliza os dois métodos abaixo
void funcao1(int numero) Imprime o número passado como parâmetro Método utilizado pelo método OperadorTernarioComFuncoe
void funcao2(void) Imprime a mensagem "foi o número digitado." Método utilizado pelo método OperadorTernarioComFuncoe
void VerificaSeONumeroEhZero(void) Verifica se o segundo número informado pelo usuário é 0 utilizando o if A condição if(b) poderia ser escrita como if(b != 0), porém esta forma é redundante

Ifs aninhados

If aninhado é um comando if dentro de um outro if ou else.

Exemplos de ifs aninhados

Método O que faz
void AdivinharONumeroComIfAninhado(void) Utiliza o ifs aninhados para verificar se o usuário adivinhou o número gerado aleatoriamente pelo programa

Switch

É um comando de verificação múltipla. Esse comando testa sucessivamente o valor de uma expressão contra uma lista de constantes inteiras ou de caractere. Quando o valor coincide, os comandos associados à aquela constante, são executados.

Também é possível fazer um switch aninhado, ou seja, um comando switch dentro de um case de um outro switch.

Utilização

switch(expressão){
    case constante1:
        sequência de comandos
        break;
    case constante2:
        sequência de comandos
        break;
    case constante3;
        sequência de comandos
        break;
    .
    .
    .
    default:
        sequência de comandos
}

default é opcional e é executado caso nenhuma coincidência seja detectada.

Observações

  • O comando switch difere do comando if, porque o switch só pode testar igualdade, enquanto o if pode avaliar uma expressão lógica ou relacional.

  • Duas constantes case no mesmo switch não podem ter valores idênticos.

  • Se constantes de caractere são usadas em um comando switch, elas são automaticamente convertidas para seus valores inteiros.

Exemplos de switch

Método O que faz
void ComandoSwitchMenu(void) Exemplo de utilização do switch
void ComandoSwitchSemBreak(void) Exemplo de utilização do switch sem o break
void ComandoSwitchDeclarandoVariaveis(void) Exemplo de declaração de variável dentro de um switch
void ComandoSwitchComBlocosDeCodigo(void) Exemplo de blocos de código dentro de um switch*
void SwitchAninhado(void) Exemplo de switch aninhado

Iteração

for, while e do while.

For

Laço de repetição que inicializa o valor de controle, verifica se a condição de finalização já foi atingida e incrementa/decrementa o valor de controle.

Utilização do for

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

inicialização é, geralmente, um comando de atribuição que é usado para colocar um valor na variável de controle do laço.

condição é uma expressão relacional que determina quando o laço acaba.

incremento define como a variável do laço varia a cada vez que o laço é repetido.

Exemplos de for

Método O que faz Observações
void ForIncremento(void) Exemplo de utilização do for incrementando o valor a cada rodada -
void ForDecremento(void) Exemplo de utilização do for decrementando o valor a cada rodada -
void ForNaoSeraExecutado(void) Exemplo de for que não será executado, pois a condição é falsa -
void ForComDoisControles(void) É possível utilizar o comando for com duas variáveis de controle -
void ForCondicao(void) A condição do for pode ser alguma outra expressão lógica -
void ForComFuncoes(void) As expressões que controlam o for também podem ser funções Utiliza os métodos int QuadradoDeUmNumero(int numero), int LerNumero(void) e int ImprimirTexto(void)
void ForSemParteDaDefinicao(void) Não é necessário que existam todas as expressões na definição de um for para que ele funcione adequadamente -
void ForInfinito(void) For irá rodar infinitamente até parar o programa -
void ForSemCorpo(void) É possível criar um for sem um corpo. Esse for é um for de atraso de tempo -

While

O laço se repete enquanto a condição for verdadeira.

Utilização

while(condição) comando;

comando pode ser sem comando, uma expressão ou um bloco de expressões.

Exemplos de while

Método O que faz Observações
void ComandoWhile(void) Enquanto o caractere A não for digitado, o bloco de código será executado É necessário limpar o buffer para corrigir o problema de imprimir duas vezes a mensagem
void ComandoWhileCondicaoVerdadeira(void) Caso a condição do while já seja verdadeira, o bloco de código dentro do while não será executado -
void ComandoWhileSemCorpo(void) O comando while não precisa ter um corpo, ele ficará sendo executado até que o usuário digite a letra "A" -

Do-while

Os laços for e while testam a condição do laço no começo. O do-while testa a condição do laço no final, isso significa que o laço do-while sempre será executado pelo menos uma vez.

Utilização

do{
    comando;
}while(condição);

Exemplos de do-while

Método O que faz
void ComandoDoWhile(void) O comando do-while foi utilizado para a seleção de menu, enquanto um menu válido não for selecionado, ele será executado

Desvio

return, goto, break e continue.

Return

Utilizado para retornar de uma função, ele retorna para o ponto em que a chamada à função foi feita.

Pode ser utilizado em qualquer parte do código.

Se o return tem um valor associado a ele, esse valor é o valor de retorno da função. Se não existe nenhum valor associado à variável de retorno, apenas lixo é retornado.

Utilização

return expressão;

expressão é opcional.

Exemplos de return

Método O que faz Observações
int ReturnInt(void) Método retorna um int -
char ReturnChar(void) Método retorna um char -
void SemRetunr(void) Método sem retorno é um método do tipo void -
float ReturnFloat(void) Método retorna um float -
int ReturnVazio(void) Método retorna um int que não foi atribuído nenhum valor a ele. Por conta disso, o valor retornado, é um valor de lixo de memória. Esse método está comentado para evitar warnings.

Goto

O goto vai para uma área demarcada com <nome_da_area>: no código.

Uma preocupação da maioria dos programadores sobre o goto é a sua tendência de tornar os programas ilegíveis.

Pode ser utilizado em qualquer parte do código.

Utilização

goto rótulo;
.
.
.

rótulo:

Exemplos de goto

Método O que faz
int ComandoGoto(void) Exemplo de loop com goto

Break

Pode ser utilizado para terminar um case em um comando switch ou pode ser usado para forçar uma terminação imediata de um laço, evitando o teste condicional normal do laço.

Exemplos de goto

Método O que faz
int ComandoBreak(void) Exemplo de loop com break
int SwitchCaseComBreak(void) Exemplo de switch com break

Exit

Da mesma forma que você pode sair de um laço, pode sair de um programa usando a função exit().

Força uma terminação imediata do programa inteiro, forçando um retorno ao sistema operacional.

Utilização

void exit(int codigo_de_retorno);

O valor de codigo_de_retorno é retornado ao processo chamador, que normalmente é o sistema operacional.

Código de retorno 0 indica terminação normal do programa.

Exemplos de exit

Método O que faz Observações
int ComandoExit(void) Finaliza o programa Esse exemplo é utilizado no menu do main

Continue

Força para que ocorra a próxima iteração do laço, pulando qualquer código intermediário.

Exemplos de continue

Método O que faz
int ComandoContinue(void) Exemplo de continue em um loop

Comandos de expressões

Uma expressão válida em C (um comando que não gera um erro no compilador) seguida por um ponto e vírgula.

Utilização

  • Chamada a uma função
func();
  • Comando de atribuição
a = b + c;
  • Comando válido que não faz nada
b + f();
  • Comando vazio
;

Exemplos de comandos de expressão

Método O que faz
void Expressoes(void) Exemplo de comandos de expressão

Blocos de comando

Grupos de comandos relacionados que são tratados como uma unidade. Os comandos que constituem um bloco estão logicamente conectados.

Um bloco começa com uma chave e termina com uma chave correspondente.

Exemplos de comandos de bloco de código

Método O que faz
void Bloco(void) Exemplo de um bloco de código

Matriz

Coleção de variáveis do mesmo tipo que é referenciada por um nome comum.

Um elemento específico em uma matriz é acessado por meio de um índice. Em C, todas as matrizes consistem em posições contíguas na memória. O menor endereço corresponde ao primeiro elemento e o maior, ao último elemento.

Matrizes unidimensionais

Como outras variáveis, as matrizes devem ser explicitamente declaradas para que o compilador possa alocar espaço para elas na memória.

O primeiro índice de uma matriz em C é o 0.

Utilização

tipo nome[tamanho];

tipo declara o tipo de base da matriz.

tamanho define quantos elementos a matriz irá guardar.

Quantidade de armazenamento

A quantidade de armazenamento necessário para guardar uma matriz está diretamente relacionada ao seu tamanho e seu tipo. Para uma matriz unidimensional, o tamanho total em bytes é calculado da seguinte maneira:

total em bytes = sizeof(tipo) * tamanho da matriz

A linguagem C não controla se o programador está acessando um index que não pertence à matriz. Por conta disso, deve-se tomar cuidado e atenção, pois você ultrapassar o tamanho máximo da matriz escrevendo ou imprimindo dados indevidos.

Exemplos de matrizes unidimensionais

Método O que faz Observações
void Matriz(void) Exemplo de uma matriz com tamanho 10 Esse método não é chamado no menu do main, pois ele não imprime nenhum valor na tela
void UltrapassaLimiteDaMatriz(void) Exemplo de um for que ultrapassa o limite de tamanho de uma matriz Esse método não é chamado no menu do main, pois ele não imprime nenhum valor na tela

Ponteiro

Você pode gerar um ponteiro para o primeiro elemento de uma matriz simplesmente especificando o nome da matriz, sem nenhum índice.

Também é possível especificar o endereço do primeiro elemento de uma matriz utilizando o operador &.

int matriz[10];

matriz e &matriz[0] produzem os mesmos resultados.

Exemplos de ponteiros

Método O que faz Observações
void PonteiroNaMatriz(void) Exemplo de ponteiro em uma matriz Esse método não é chamado no menu do main, pois ele não imprime nenhum valor na tela

Passagem de matrizes unidimensionais para funções

Em C, você não pode passar uma matriz inteira como um argumento para uma função. Porém é possível passar um ponteiro para uma matriz para uma função, especificando, o nome da matriz sem um índice.

Exemplos de passagem de matrizes unidimensionais para funções

Método O que faz Observações
void MatrizFuncao(void) Exemplo de como passar uma matriz para uma função Esse método não é chamado no menu do main, pois ele não imprime nenhum valor na tela

String

Matriz de caracteres terminada por um nulo.

Nulo = '\0'

Por este motivo, é necessário que o tamanho das matrizes de caracteres sejam uma unidade maior do que o requisitado.

Para utilizar as funções de string é necessário incluir o <string.h> no header.

Atenção

Ao atribuir individualmente os valores à uma matriz de string, você deve-se lembrar de inserir o nulo.

char[4] = {'O', 'l', 'a', '\0'}

Funções

Nome Função
strcpy(s1, s2) Copia s2 em s1
strcat(s1, s2) Concatena s2 ao final de s1
strlen(s1) Retorna o tamanho de s1
strcmp(s1, s2) Retorna 0 se s1 e s2 são iguais; menor que 0 se s1 < s2; maior que 0 se s1 > s2
strchr(s1, ch) Retorna um ponteiro para a primeira ocorrência de ch em s1
strstr(s1, s2) Retorna um ponteiro para a primeira ocorrência de s2 em s1

OBS: para utilizar essas funções é necessário adicionar o cabeçalho "string.h""

Exemplos das funções de strings

Método O que faz
void String(void) Exemplo de utilização das funções de string

Matrizes bidimensionais

O primeiro índice da matriz indica a linha e o segundo índice indica a coluna.

Quando uma matriz bidimensional é usada como argumento para uma função, apenas um ponteiro para o primeiro elemento é realmente passado. Porém, uma função que recebe uma matriz bidimensional como um parâmetro, deve definir pelo menos o comprimento da segunda dimensão. Isso ocorre, porque o compilador C precisa saber o comprimento de cada linha para indexar a matriz corretamente.

Tamanho necessário em bytes para armazenamento na memória

bytes = tamanho do 1º índice * tamanho do 2º índice * size of(tipo base)

Exemplo de cálculo de bytes

int matriz[10][5];

Tem o tamanho 10 * 5 * 2 (tamanho em bytes do tipo int de 16 bits) que seriam 100 bytes.

Utilização

Matriz bidimensional de tamanho 10, 20:

int d[10][20];

Acessando o ponto 1, 2:
d[1][2];

Exemplo de chamada de função

void funcao(int x[][10]){
.
.
.

}

Visualização da matriz

Coluna 1 Coluna 2 Coluna 3
Linha 1 ch[0][0] ch[0][1] ch[0][2]
Linha 2 ch[1][0] ch[1][1] ch[1][2]
Linha 3 ch[2][0] ch[2][1] ch[2][2]
Linha 4 ch[3][0] ch[3][1] ch[3][2]

Exemplos de matrizes bidimensionais

Método O que faz
void MatrizBidimensional(void) Exemplo de uma matriz bidimensional
void NotasDosAlunos(void) Exemplo de uma matriz bidimensial

Matrizes de strings

Uma matriz que armazena várias strings.

Utilização

char string_array[30][81];

Uma matriz de 30 strings, cada qual com o comprimento máximo de 80 caracteres.

Acessar uma string

gets(string_array[2]);

Acessa a string na posição de índice 2.

O comando acima é equivalente a:

gets(&string_array[2][0]);

Exemplos de matrizes de strings

Método O que faz
void MatrizDeString(void) Exemplo de uma matriz de string

Matrizes de 3 ou mais dimensões

Não são frequentemente usadas devido à quantidade de memória de que elas necessitam.

Utilização

tipo nome[tamanho1][tamanho2][tamanho3]...[tamanhoN];

Exemplo de cálculo de bytes

int matriz[10][6][9][4];

Tem o tamanho 10 * 6 * 9 * 4 * 2, que seria equivalente à 4.320 bytes.

Passagem de matrizes multidimensionais para funções

int m[4][3][6][5];
void funcao(int[][3][6][5]){
.
.
.

}

Exemplos de matrizes multidimensionais

Método O que faz
void MatrizMultidimensional(void) Exemplo de uma matriz multidimensional

Indexando ponteiros

Um nome de matriz sem um índice é um ponteiro para o primeiro elemento dela mesma.

//Considere a matriz
char p[10];

//As seguintes sentenças são equivalentes
p;
&p[0];

Outro exemplo:

int * p;
int i[10];

p[5] = 100; //Atribui o valor 100 no sexto elemento de i
*(p+5) = 100; //Atribui usando aritmética de ponteiros, será explicado posteriormente

Analogamente, essa regra também vale para matrizes de duas ou mais dimensões.

a[j][k]; //É equivalente a
*a(a+(j*comprimento das linhas)+k);

Exemplo:

a;
&a[0][0];

a[0][4];
*(a+4);

a[1][2];
*(a+12);

A aritmética de ponteiros é geralmente mais rápida que a indexação de matrizes.

Exemplos de index e ponteiros

Método O que faz
void ImprimeLinha(int j) Exemplo de ponteiros em uma matriz

Inicialização de matrizes

A inicialização de matrizes é semelhante à de outras variáveis:

especificador_de_tipo nome_da_matriz[tamanho1]...[tamanhoN] = {lista_de_valores};

lista_de_valores é uma lista separada por vírgulas de valores compatíveis com o especificador_de_tipo.

int i[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

Matrizes que contêm strings permitem a inicialiçazão abreviada:

char nome_da_matriz[tamanho] = "string";
char string[30] = "Eu gosto de legumes.";

//Bem melhor do que escrever
char string[30] = {'E', 'u', ' ', 'g', 'o', 's', 't', 'o', ' ', 'd', 'e', ' ', 'l', 'e', 'g', 'u', 'm', 'e', 's', '.', '\0'}
//Nessa atribuição é necessário incluir o terminador nulo
//Pois o compilador não fará isso automaticamente como no caso da atribuição abreviada

Matriz multidimensionais são inicializadas da seguinte forma:

int matriz[10][2] = {
    1,1,
    2,4,
    3,9,
    4,16,
    5,25,
    7,49,
    8,64,
    9,81,
    10,11
}

Exemplos de inicialização de matrizes

Método O que faz
void InicializacaoMatriz(void) Exemplo de inicialização de uma matriz de int
void InicializacaoMatrizString(void) Exemplo de inicialização de uma matriz de caracteres (string) e compara o modo abreviado com o convencional de inicialização
void InicializacaoMatrizMultidimensional(void) Exemplo de inicialização de uma matriz multidimensional

Inicialização de matrizes não-dimensionais

As matrizes não dimensionais é quando você deixa que o compilador C calcule automaticamente o tamanho dessas matrizes. Para fazer isso é necessário não especificar o tamanho da matriz ao inicializa-la.

Outra vantagem de utilizar matrizes não dimensionadas é poder alterar os valores que estão nessas matrizes sem se preocupar de ultrapassar o tamanho máximo da matriz.

Matriz multidimensionais podem ser não dimensionais também. Para utiliza-las basta não informar a primeira dimensão, todas as outras devem ser informadas para que o compilador possa indexar corretamente elas.

Utilização

  • Matriz dimensionada
char string1[17] = "Erro de leitura\n";
char string2[17] = "Erro de escrita\n";
char string3[29] = "Arquivo não pode ser aberto\n";
  • Matriz unidimensional não dimensionada
char string1[] = "Erro de leitura\n";
char string2[] = "Erro de escrita\n";
char string3[] = "Arquivo não pode ser aberto\n";
  • Matriz multidimensional não dimensionada
int strings[][2] = {
    1, 2,
    3, 4,
    5, 6, 
    7, 8,
    9, 10,
    11, 12
}

Exemplos de matrizes não dimensionais

Método O que faz
void InicializacaoMatrizNaoDimensionada(void) Exemplo de inicialização de uma matriz de unidimencional não dimensionada
void InicializacaoMatrizMultidimensionalNaoDimensionada(void) Exemplo de inicialização de uma matriz de multidimensional não dimensionada

Jogo da velha

Foram criadas dois códigos do jogo da velha.

Exemplo jogo da velha versão Hatsumi

Método O que faz
void JogoDaVelhaVersaoHatsumi(void) Realiza a chamada do jogo
void InicializaOTabuleiro(void) Inicializa o tabuleiro com hífens
void Verificar(void) Verifica se ainda existem espaços em branco no tabuleiro ou se algum jogador venceu o jogo
void ImprimirTabuleiro(void) Imprime os valores do tabuleiro
void ReceberValor(void) Recebe o valor da jogada do usuário
void VezDoRobo(void) Realiza a jogada do robô colocando um 0 no primeiro espaço vazio encontrado

Exemplo jogo da velha versão do livro

Método O que faz
void JogoDaVelhaLivro(void) Realiza a chamada do jogo
void InicializarMatriz(void) Inicializa a matriz com espaços em branco
void ObterJogadaDoJogador(void) Recebe a jogada do usuário
void ObterJogadaDoComputador(void) Realiza a jogada do computador
void Checar(void) Verifica se algum jogador ganhou
void ImprimirMatriz(void) Imprime a matriz

Ponteiros

É uma variável que contém um endereço de memória.

Endereço na memória Variável na memória Observação
1000 1003 Aponta para o endereço de memória 1003
1001
1002
1003
1004

É preciso ter atenção ao utilizar ponteiros, pois as variáveis ponteiro sempre devem apontar para o tipo de dado correspondente.

Alguns compiladores C não exibirão nenhum erro de compilação caso um ponteiro do tipo int, por exemplo, aponte para um ponteiro do tipo float. No entanto, como esses tipos possuem tamanhos diferentes, ocorrerá um erro posteriormente (int tem 2 bytes e float tem 8 bytes, só serão salvos os dois primeiros bytes na variável ponteiro).

Utilização

tipo *nome;

tipo define o tipo de variáveis que o ponteiro pode apontar.

Exemplos com ponteiros

Método O que faz Observações
void VariavelPonteiroTipoDiferente(void) Exibe um exemplo da atribuição do endereço de uma variável float a um ponteiro do tipo int O código foi comentado para evitar a exibição de warnings. O código não é chamado no main, pois não produz nenhuma saída na tela.

Atribuição de ponteiros

Para atribuir um valor a um ponteiro, basta realizar o comando:

int x = 1;
int *p1;

//Ponteiro p1 recebe o endereço da memória de x
p1 = &x;

Também é possível...

int x = 1;
int *p1;
int *p2;

//Ponteiro p1 recebe o endereço da memória de x
p1 = &x;
//Ponteiro p2 recebe o endereço que está em p1
//Que é o endereço de x
p2 = p1;

Exemplos de atribuições de ponteiros

Método O que faz
void AtribuicaoDePonteiros(void) Atribui ao ponteiro p1 o endereço de memória de x e atribui ao ponteiro p2 o endereço de memória que está em p1

Aritmética de Ponteiros

É possível utilizar duas operações aritméticas com ponteiros, a adição e a subtração.

Não é possível utilizar nenhuma outra operação com ponteiros. Assim como não é possível adicionar ou subtrair valores do tipo float e double de ponteiros.

Ao incrementar ou decrementar uma unidade em um ponteiro, o valor final do ponteiro será a posição de memória do próximo/anterior elemento do seu tipo base.

Para entender melhor o que acontece, vamos ver um exemplo.

Exemplo

Ponteiro p1 aponta para um inteiro com o valor 2000. Considere que os inteiros são de 2 bytes. Após a operação:

p1++;

p1 fica com qual valor?

2001? Errado!

2002!! O que acontece é que cada vez que incrementamos uma unidade no ponteiro p1, ele aponta para o próximo inteiro, que possui, no mínimo, 2 bytes. O mesmo ocorre com o decremento.

p1--;

Ficará com o valor 1998.


Também é possível adicionar ou subtrair valores inteiros dos ponteiros:

p1 = p1 + 12;

Essa operação faz com que p1 aponte para o décimo segundo elemento do tipo de p1 após o elemento que p1 está apontando atualmente.

Exemplos de aritmética de ponteiros

Método O que faz
void AritmeticaDePonteiros(void) Exemplo de operações aritméticas com ponteiros

Comparação de ponteiros

É possível realizar comparações de ponteiros. Normalmente essas comparações são feitas quando os ponteiros apotam para um objeto em comum.

Exemplos de aritmética de ponteiros

Método O que faz Observações
void Push(void) Realiza a comparação de dois ponteiros para verificar se o tamanho máximo da pilha foi excedido Método chamado pelo método Pilha()
int Pop(void) Realiza a comparação de dois ponteiros para verificar se o último elemento da pilha foi removido Método chamado pelo método Pilha()
void Pilha(void) Método que realiza a chamada dos dois métodos anteriores -

Ponteiros e matrizes

Para acessar elementos de matrizes é possível utilizar a aritmética de ponteiros ou a indexação de matrizes. A aritmética de ponteiros pode ser mais rápida que a indexação de matrizes.

Utilização

char string[80];
char *ponteiro;

//Ponteiro foi incializado com o primeiro elemento da matriz
ponteiro = string;

Para acessar o quinto elemento da matriz:

string[4]; 

//Ou também
*(ponteiro+4)

Exemplos de ponteiros e matrizes

Método O que faz
void MatrizComIndexacao(char *s) Exemplo de acesso aos elementos da matriz com indexação
void MatrizComPonteiro(char *s) Exemplo de acesso aos elementos da matriz com ponteiro

Matrizes de ponteiros

É possível criar uma matriz de ponteiro.

Utilização

int *matrizDePonteiro[10];

Para atribuir um valor:

matrizDePonteiro[0] = &variavel;

Para obter o valor da variavel:

*matrizDePonteiro[0];

Exemplos de matrizes de ponteiros

Método O que faz Observações
void ExibirArray(int *matrizPonteiros[]) Exemplo de função que recebe uma matriz como parâmetro sem informar o tamanho da mesma Função chamada pela função ExibirArrayChamada
void ExibirArray2(int *matrizPonteiros[10]) Exemplo de função que recebe uma matriz como parâmetro informando o tamanho da matriz Função chamada pela função ExibirArrayChamada
void ExibirArray3(int *matrizPonteiros[]) Exemplo de função que recebe o ponteiro que aponta para uma matriz como parâmetro Função chamada pela função ExibirArrayChamada
void ExibirArrayChamada(void) Exemplo de utilização de matriz de ponteiros e chamada das funções acima -

Indireção múltipla ou ponteiro para ponteiros

É quando um ponteiro aponta para um ponteiro que aponta para o valor.

Para entender um pouco mais, veja a imagem a seguir:

É possível utilizar ponteiros que apontam para ponteiros que apontam para ponteiros e assim sucessivamente, no entanto, raramente é necessário mais de um ponteiro para um ponteiro.

Utilização

float **ponteiro;

ponteiro é um ponteiro para um ponteiro do tipo float.

ATENÇÃO

ponteiro NÃO é um ponteiro para um número float.

Exemplos de ponteiros de ponteiros

Método O que faz
void PonteiroDePonteiro(void) Exemplo de utilização de ponteiro de ponteiro

Inicialização de ponteiros

Caso um ponteiro seja utilizado sem ser inicializado, pode ocorrer um erro inesperado, pois ao instanciar um ponteiro, ele já possui um valor desconhecido.

Uma convenção entre a maioria dos programadores de C é inicializar o ponteiro com o valor nulo.

No entanto, um ponteiro com o valor nulo, não garante que não correrão erros ao utilizá-lo. Caso o programador utilize o ponteiro do lado esquerdo de um comando de atribuição, ocorrerá um erro.

Exemplos de ponteiros de ponteiros

Método O que faz Observações
void PonteiroSemInicializar(void) Exemplo de utilização de ponteiro que não foi inicializado O código está comentado para evitar warnings. O código não é chamado pelo main(), pois está comentado e no meu computador, ele gerou um erro em tempo de execução

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published