Académique Documents
Professionnel Documents
Culture Documents
Isto no foi feito com base cientfica. No assumam que tudo est certo,
isto apenas um conjunto de notas que fiz para ajudar o pessoal a
perceber mais sobre programao.
Noes Base:
Todos os programas em C tm que ter funo main() e librarias/includes.
A funo main a funo que chamada no incio do programa e por tanto a funo onde
tudo comea e da ser necessria.
Librarias ou includes so ficheiros que contm funes, definies, etc. j criadas. Estas so
necessrias para poder usar funes especficas, mas no so todas necessrias. Para adicionar
uma include ao programa a sintaxe : #include <LIBRARIA.h>
O fim de uma instruo tem de ser sempre seguido por um ; . Nem sempre corresponde ao fim
de linha.
Um exemplo de um programa hello world:
#include
#include<stdio.h>
<stdio.h>
/*/*
Comentrio
Comentrio
*/*/
//Comentrio
//Comentrio
void
voidmain()
main()
{{
printf("Hello
printf("HelloWorld");
World");
}}
Variveis:
Variveis so expresses onde so guardados valores e, como o nome indica, podem ser
alterados a qualquer momento.
As variveis podem ser globais (criadas fora de uma funo e podem ser usadas/alteradas em
qualquer funo) ou locais (criadas numa funo e apenas existem dentro delas).
-Tipos e declarao:
Ao declarar (criar) uma varivel tem que se dizer qual o tipo de varivel. Os tipos de variveis
bsicas so as seguintes:
Tipo
Caractere
Inteiro
Real
Real preciso dupla
Booleana
Declarao
char
int
float
double
bool
Formatao1
c
d
f
lf
1
2
-Inicializao:
A inicializao dar um valor a uma varivel. importante inicializar uma varivel antes de a
usar para prevenir erros, sem inicializar todas as variveis vo ter um valor que considerado
lixo.
A inicializao de variveis pode ser feita na declarao, depois da declarao ou pedindo ao
utilizador com a funo scanf.
Para atribuir um valor a uma varivel usa-se um =. Para variveis do tipo char e arrays por
favor ver o captulo referente a arrays.
Exemplos:
#include <stdio.h>
//varivel global
int x=5; //incializao direta.
float y;
void main()
{
//variveis locais
int a,b;
a=b=6; //incializao depois da declarao
scanf("%f",&y);
printf("x=%d y=%f a=%d b=%d\n",x,y,a,b);
}
Operadores:
-Matemticos:
Operadores matemticos so operadores que fazem operaes matemticas.
NOTA: o incremento e decremento podem ser feitos de 2 maneiras: ++x ou x++ (sendo x o
nome da varivel). Porm tm diferenas. Para um exemplo pratico: y = ++x; e y = x++; y ir ter
valores diferentes em ambos os casos, isto porque quando o ++ aparece antes da varivel
primeiro incrementada a varivel e depois usada, se for depois da varivel, primeiro
usada e depois incrementada. Os exemplos podiam ser assim escritos: x+=1;y=x; e y=x;x+=1;
respetivamente.
Se for para fazer uma operao com o valor da varivel pode ser usado um = juntamente com
o operador da operao antes do igual. Por exemplo, multiplicar o valor de uma varivel por 2,
pode ser feito das seguintes maneiras:
x = x*2;
X *= 2;
NOTA: A diviso pode ser de 2 tipos, inteira ou real. Se for a diviso entre 2 inteiros ir
retornar um inteiro (aproximao por defeito, isto : 2,9 ir dar 2), se um dos valores for um
float ir retornar um float. Para retornar um real da diviso entre 2 inteiros tem que se
converter pelo menos um em float3
-Lgicos:
Operadores de lgica que retornam verdadeiro ou falso (true/false)
&& : E
|| : Ou
! : Negao
-Relacionais:
Operadores de relao entre 2 valores. Retornam verdadeiro ou falso
Funes/Procedimentos:
Funes so bastante parecidas as funes matemticas, recebem valores (ou no) e retornam
(devolvem) um valor.
A diferena entre funes e procedimentos que um procedimento no devolve valor
nenhum. Para facilitar a coisa vou chamar tudo de funes.
-Declarao:
As funes so declaradas de maneira parecida as variveis. Tem que se especificar o tipo de
varivel a retornar, o nome da funo e os parmetros de entrada:
TipoVar NomeFuno(TipoVar NomePar)
Sendo TipoVar o tipo de valores a retornar (se for um procedimento, ou seja, no retorna
nada, ento no tipo escreve-se void).
As funes tm de ser declaradas antes de poderem ser chamadas.
3
Ver Casting
A parte do cdigo que a funo faz tem que estar entre chavetas ( { } ) mesmo que use apenas
uma linha. Ao fechar chavetas no precisa de ;
-Parmetros:
Os Parmetros de entrada podem ser quantos quiserem, para determinar os parmetros da
mesma forma que so declaradas variveis, s que os parmetros so separados por vrgulas e
cada parmetro tem de ter o tipo especificado.
As funes tambm podem ter parmetros de entrada opcionais. Para isso a inicializao do
parmetro feito quando especificado (Ateno: os parmetros opcionais tm que ser os
ltimos).
-Retorno (Devoluo)
Para retornar um valor numa funo usa-se a palavra reservada return.
Ateno: Depois de um return ser chamado j nenhum cdigo da funo ir ser executado.
-Chamada da funo:
Chamar uma simples, apenas tem que se escrever o nome da funo e depois entre
parenteses colocar as variveis ou constantes que serviram como parmetros de entrada
separadas por vrgula. A sintaxe tem que corresponder a definio da funo. Se no tiver
parmetros de entrada, deixa-se em branco entre os parenteses ou escrever void.
Para atribuir o valor retornado por uma funo a uma varivel apenas tem que se igualar (usar
o = ) a varivel funo.
Para usar como parmetro arrays ou saber mais sobre funes vai ao captulo das Funes
Parte 2.
Exemplo:
#include <stdio.h>
void Ola() //procedimento
{
printf("Procedimento: Ola\n");
}
int Soma(int x, int y) // funo que devolve 1 inteiro e com 2 inteiros como
parmetros de entrada
{
return x+y;
int z = x-y; // NUNCA VAI SER EXECUTADO!!
}
float Div(float x, float y=2.5) //funao que devolve 1 float com 2 floats como
parmetros de entrada e 1 como opcional
{
return x/y;
}
void main()
{
int s = Soma(2,3);
float f = Div(5);
Ola();
printf("Soma = %d\n",s);
printf("Divisao = %f\n",f);
}
Condies (testes):
As condies e/ou testes so uma das partes mais importantes da programao. Isto serve
para verificar valores e determinar o que fazer consoante o valor que for.
-ifelse ifelse
Teste para verificao de valores mais usual. Traduzido para portugus seria seseno se
seno.
O if (se) verifica se uma expresso verdadeira, se for faz o cdigo que for definido para ele
executar atravs de chavetas. Se for apenas uma instruo as chavetas sero desnecessrias.
O else if(seno se) e o else(seno) no so necessrios e sero executados se o if falhar. O
else ser chamado se o if e else if (se houver else if) derem falso. Pode conter quantos else if
quanto for necessrio.
A expresso que o if e else if verificam est dentro de parenteses a seguir a palavra. A
expresso pode conter um qualquer conjunto de instrues desde que o valor devolvido seja
um booleano. Por exemplo pode-se misturar operadores lgicos e relacionais.
NOTA: O bool apenas existe em verses recentes de C/C++. At l era usualmente usado um
char ou int para fazer as verificaes. false e true tambm no existiam, eram usado o 0 e 1. 0
false e 1 true.
Exemplo:
bool b=false, c=true;
int x=5;
if(b)
printf("b e verdadeiro.\n");
else if(x == 5 && !c)
{
printf("b e falso.\n");
printf("x e 5.\n");
printf("c e verdade.\n");
}
else
printf("O if e else if deram falso.\n"); //ir fazer este printf
-switch case
O switch permite agarrar o valor de uma expresso e comparar esta com constantes.
Primeiro usa-se switch para ir buscar o valor da expresso e depois abre-se um bloco para ele
(chavetas). Dentro desse bloco vai-se compara essa expresso com constantes atravs do case.
Os case no necessitam de chavetas, mas precisa de um : antes do bloco e sempre preciso
usar um break;4 no fim de cada case, para no executar o cdigo dos seguintes case. Caso
todos os case deem falso ir executar o cdigo do default (semelhante ao else), que
opcional.
Se vrios case forem executar o mesmo cdigo basta no colocar break;
Exemplo:
void main()
{
int x=2, y=3, sum;
char op = '-';
switch(op)
{
case '+':
sum = x+y;
break;
case '-':
sum = x-y;
break;
case '/':
sum = x/y;
break;
case '*':
sum = x*y;
break;
}
printf("%d\n",sum);
}
-Operador Ternrio:
O operador ternrio executado de maneira parecida ao ifelse, porem o que o operador
ternrio faz verificar se uma expresso verdadeira ou falsa e retornar um valor para cada
uma dessas. No serve para verificaes extensas ou com cdigo extenso.
O operador ternrio usa 2 smbolos que so ? e :
A sintaxe a seguinte:
Expresso ? resultado1 : resultado2
Verifica se a Expresso verdadeira, se for devolve o valor do resultado1, se for falso retorna
resultado2.
Exemplo:
void main()
{
int x=2,y;
bool multi = false;
y = multi ? x*2 : x/2; // y = 2/2 = 1
}
Ciclos:
Ciclos so estruturas que repetem um determinado cdigo as vezes que forem definidas, se
forem definidas.
-for:
O ciclo for dos mais usados porque permite fazer a inicializao, verificao e incrementao
numa s linha. Em portugus significa para e ainda em portugus a sintaxe seria algo do
gnero:
para var igual qualquercoisa enquanto expresso incrementa x
A sintaxe em C a seguinte:
for(var=com; expresso; var += incremento) { }
Como se pode ver o for composto por 3 campos:
1. Inicializao: aqui inicializa-se a varivel(variveis) que necessitem de ser inicializadas
neste ciclo.
NOTA: em C standard no era possvel criar uma varivel apenas para o ciclo neste
campo, porm em verses mais recentes de C j possvel.
2. Verificao: Aqui colocada a expresso que verificada em cada iterao do ciclo,
quando for falsa o ciclo termina.
NOTA: Cuidado com ciclos infinitos
3. Incremento: Aqui determinado o incremento da varivel(variveis) em cada iterao.
Este campo executado no fim de cada iterao antes da verificao.
Nenhum dos campos obrigatrio. Se o ciclo for apenas repetir uma instruo ento no
preciso chavetas, caso contrrio sempre preciso chavetas.
Exemplo: 5=1
void main()
{
int sum = 0;
for(int i=1; i<6; i++)
{ //no necessrio chavetas aqui
sum+=i;
}
printf("Somatorio = %d\n", sum);
}
-while
Em portugus enquanto, faz a verificao de uma expresso e enquanto for verdadeira
repete a seo de cdigo definida.
Sintaxe:
while(expresso){}
Mais uma vez, se for repetir apenas uma instruo as chavetas no so necessrias.
NOTA: A inicializao das variveis para a expresso tm de ser feitas antes do ciclo e o
incremento desta tem que ser feito dentro da seco do cdigo do ciclo.
Exemplo: 5=1
void main()
{
int sum = 0, i=1;
while(i<6)
sum+=i++;
printf("Somatorio = %d\n", sum);
}
-dowhile
Em portugus fazenquanto um ciclo como o while apenas com uma diferena: o cdigo
do ciclo sempre executado 1 vez pelo menos, ao contrrio do while e for em que a seco de
repetio pode nunca ser executada caso a expresso seja falsa.
Neste ciclo primeiro executado o cdigo e s depois feita a verificao. bastante usado
para fazer menus em que este tem que ser mostrado pelo menos a primeira vez.
A semelhana do resto, se for apenas executar uma instruo no precisa de chavetas.
Exemplo: 5=1
void main()
{
int sum = 0, i=1;
do
{
sum+=i;
i++;
}
while(i<6);
printf("Somatorio = %d\n", sum);
}
-Ciclos infinitos:
Ciclos infinitos, como o nome o indica, so ciclos sem fim determinado. So uteis para repetir
uma seco de cdigo sem fim previsto. Para sair dele necessrio usar um break;
muito usual ocorrerem ciclos infinitos por distrao, preciso ter cuidado com a correta
inicializao e incrementao de variveis, especialmente nos ciclos while.
Para criar um ciclo infinito pode-se usar, por exemplo:
for(;;) ou while(1)
-break;
O break uma definio usada para quebrar o cdigo de ciclos e switch case.
-continue;
O que o continue faz continuar o ciclo para a prxima iterao sem acabar o cdigo que falta
da seco. til, especialmente, em ciclos para fazer verificaes em arrays.
Input / Output:
A parte mais importante de um programa o contacto com o utilizador. Para isso preciso
mostrar-lhe mensagens e receber valores dele. A libraria stdio.h fornece 2 funes para esse
fim: scanf e printf
-printf:
O printf uma funo para mostrar uma mensagem no ecr. Esta funo serve para mostrar
mensagens fixas ou com os valores de variveis ou constantes.
Sintaxe:
printf(char[] string, [var]);
Sendo string a string a mostrar e var os valores a substituir na formatao da string e so
opcionais.
Os valores de var iram substituir na string os formats coretos para eles, estes esto definidos
atravs da combinao de % com o format da varivel, tm que corresponder o nmero de % e
na string de vars na funo. Para mais informaes ver String Formatting e Variveis.
Exemplo:
void main()
{
int x = 5;
printf("x = %d\n", x);
}
Output:
x=5
-puts
Faz o mesmo que o printf mas mais bsico, mostra um string sem format no ecr.
puts(char []input);
-scanf
O scanf serve para ler informao que o utilizador insira no ecr.
A sintaxe:
scanf(string,[vars,]);
A string uma string com os formats das variveis que pretendido ler. Pode-se ler mais do
que uma varivel de uma s ver. Vars as variveis que iram receber os valores.
Todos os tipos de variveis iram ter que levar um & antes do nome da varivel5 exceto
variveis do tipo string. No possvel ler strings com espao sem usar flags no formatting da
string.
O scanf retorna o nmero de variveis a qual atribuiu valores. Por exemplo se estiverem a
tentar pedir ao utilizador 5 valores mas por algum motivo no insere os numa varivel ele ira
retornar 4. Vejam a parte das funes mais usadas.
Sugiro darem uma vista de olhos aqui: http://www.cplusplus.com/reference/cstdio/scanf/
-gets
Vai buscar uma string que o utilizador introduza at encontrar o \n da nova linha. Assim podese ler uma string ignorando os espaos em branco.
Apenas tem um parmetro: a varivel em que vai guardar a string.
ATENAO: DEPRECADO!! PARA MAIS INFOMAES TENTAR USAR NO VS QUE ELE DA LOGO
ERRO E DIZ O QUE USAR!!
-getcar
Vai buscar um s char. til para fazer pausas no cdigo, s avana at o utilizador pressionar
enter.
Ver Ponteiros
String Formatting:
As strings so um conjunto de caracteres e um tipo de array que segue normas especificas.
Uma string sem ser em varivel especificada atravs do uso de aspas () (no caso de 1 s
caracter pelicas ()).
O fim de uma string especificado pelo caracter \0 (no caso de escrever uma string com as
no preciso especificar o \0 pois ele determinado automaticamente).
As strings podem conter vrios tipos de caracteres especiais:
No caso dos printf e scanf as strings ainda podem ter um conjunto de caracteres para a
colocao de valores (chamados placeholders, que literalmente guardam o local (traduo
literal) para uma varivel, mas quem quer saber do seu nome?):
%d ou %i : int
%u : unsigned int
%f : float
%c : char
%s : char[] (string)
Entre outros
Flags:
o
o
o
o
o
o
o
o
h : short int
l : long int
ll : long long int
#define:
#define uma instruo do pr-processador que pode dar nomes a cdigos. O #define
(sempre em minsculas) define um nome a um valor, instruo ou conjunto de instrues ou
at mesmo expresses.
bastante usado para definir um nome ao tamanho mximo de um array e assim tornando
muito mais fcil alterar o tamanho sem ir procurar e alterar em todo o cdigo, mas alterar
apenas no #define (mas no a nica maneira de o usar).
Exemplo:
#DEFINE MAX_PALAVRA 50
Isto vai sempre, que encontrar no cdigo, a expresso MAX_PALAVRAS pelo valor 50.
VER MACROS!!
Arrays:
J foi explicado mais ou menos o que so arrays. Basicamente so uma cadeia de variveis do
mesmo tipo seguidas.
Os arrays podem ter varias dimenses, podem-se assim formar vetores, matrizes, etc.
-Declarao:
Array unidimensional (vetor):
int x[50];
Array bidimensional (matriz):
int x[4][4];
Array tridimensional:
int x[2][2][2];
Etc.
Para ser mais fcil de perceber pode-se assumir que um array bidimensional um array de
array e o array dimensional um array de matrizes.
Na declarao de arrays o(s) nmero(s) indicam o nmero de clulas (espaos) desse array.
Este nmero tem que ser uma constante e pode usar termos criados com #define
-String:
char Nome[MAX_NOME];
Ir criar uma string chamada Nome com 50 espaos para caracteres.
As strings so um caso especial de arrays, isto porque se declararmos uma string com 50
clulas apenas podemos ter uma palavra/frase no mximo com 49 caracteres, porque tem que
se reservar sempre uma clula para o caracter \0 que indica o fim da string e por isso o
nmero de caracteres legveis que uma frase numa string pode ter o nmero de clulas -1.
Devido a esta formatao todo o cdigo para trabalhar com strings tem que ser diferente do
resto dos tipos de variveis, a libraria sting.h contm vaias funes para manipular strings,
como copiar, comparar, etc.
Podem usar um array de char sem ser string, por exemplo para guardar alguns caracteres e
nesse caso no preciso usar o \0 nem se usam as funes para strings. Tornam-se arrays
normais como se fosse de int ou float.
-Inicializao:
Para inicializar um array na declarao parecido as variveis, porem tem que se usar
chavetas e separar os valores de cada clula por vrgulas. No necessrio inicializar todas as
clulas, basta apenas algumas, todas as outras iram ter o valor 0 por defeito.
Exemplo:
int x[5] = {1,2,3};
O array x ir ter os valores 1,2,3,0,0 no array.
Caso seja do tipo char inicializado da mesma forma, mas os valores tm de estar entre plicas
().
char nome[5] = {N,o,m,e}; //no string, mas sim um array de char
char nome[] = Kimossab; // uma string, neste caso o \0 adicionado automaticamente
Ao inicializar um array desta forma no preciso indicar o nmero de clulas, por exemplo:
int y[] = {1,2,3};
Neste caso o array y vai ter os valores 1,2,3. Notar que diferente do x!
No caso de arrays bi/tri/whatever dimensionais a inicializao feita da mesma forma, porm
so usadas chavetas e vrgulas para separar as primeiras das outras clulas (da eu antes ter
dito que podia-se chamar de array de array), e s um conjunto que pode no ter um nmero
mximo de clulas.
int mat[][3] = { {1,2,3},{4,5,6}};
O array mat ir criar uma matriz igual a seguinte:
1
Para se perceber melhor em arrays grandes podem-se usar mais do que uma linha.
-Aceder a clulas:
Para aceder ao valor de uma clula bastante simples, apenas se tem que escrever o nome do
array e entre parenteses retos colocar o ndice da clula que se quer aceder.
NOTA: os ndices dos arrays comeam sempre no 0 e vo at ao nmero de clulas menos 1.
Cada clula funciona da mesma maneira que qualquer varivel do tipo do array.
Quando preciso aceder a varias clulas do array usa-se um ciclo para no estar a usar vrias
linhas de cdigo desnecessariamente.
Dito assim at parece complicado, por isso esto aqui alguns exemplos:
#define MAX_BAR 20
int foo[][3] = {{1,2,3},{4,5,6}};
void main()
{
int bar[MAX_BAR];
for(int i=0; i<MAX_BAR; i++)
bar[i] = i*i;
printf("foo[1][2] = %d * bar[10] = %d = %d\n", foo[1][2],bar[10],
foo[1][2]*bar[10]);
}
Output:
foo[1][2] = 6 * bar[10] = 100 = 600
-Outras consideraes:
Nos arrays nem sempre se vai usar todas as clulas a toda a hora, por isso convm usar uma
varivel com o tamanho do array a parte e usa-la para funes por exemplo.
As vezes queremos inserir ou remover um valor numa determinada posio, para isso
importante compreender que temos que movimentar todas as clulas a frente da que
queremos para a frente ou trs e para isso tem que se usar variveis auxiliares para guardarem
temporariamente um valor.
Ponteiros:
Agora que comea a confuso.
Ponteiros so variveis (dos vrios tipos que existem) em que o valor o endereo de
memria que esta ocupa.
Basicamente num ponteiro no temos o valor da varivel mas sim a sua localizao na
memria. Por isso que se chamam ponteiros (ou apontadores, ou como um ou outro stor diz
ponteros), porque apontam para a memria.
preciso ter cuidado a trabalhar com ponteiros porque estamos a trabalhar com a memoria e
no com valores, por isso fcil enganarmo-nos e irmos para endereos que no devemos e
crashar tudo.
Antes que haja confuso (ou para confundir mais) convm eu explicar uma cena. Os ponteiros
podem ser dos mais variados tipos (int, char, float, whatever), mas este tipo apenas indica o
tipo de valores que iram ser guardados na memria, porque na realidade o ponteiro sempre
um inteiro (pode ser hexadecimal ou octal se preferirem) porque ele tem como valor o
endereo!
Explicado mais ou menos isto, vamos para o porque de ponteiros: os ponteiros so usados
para poder alterar valores de variveis dentro de funes. Os parmetros de entrada das
funes so apenas uma cpia da verdadeira varivel para prevenir que esta se altere na
funo. Os ponteiros fazem com que a varivel seja a original.
-Declarao:
Para criar um ponteiro igual a criar uma varivel. A nica diferena que entre o tipo de
varivel e o nome tem que se colocar um asterisco (*).
int *ptrx;
-Inicializao:
Os ponteiros podem ser inicializados com o valor NULL, isto indica que o ponteiro naquele
momento no aponta para nenhuma varivel. Lembrem-se tudo tem que ser inicializado, nem
que seja a NULL.
Tambm se pode dar o endereo de memria de uma varivel diretamente a qualquer altura
-Ponteiro de ponteiro:
Os ponteiros ocupam espao na memria, portanto possvel criar ponteiros de ponteiros
assim apontar para a memria que aponta para outra memria, mas no vou sequer
aprofundar isso, deixo isso para vocs experimentarem.
-Ponteiros e arrays:
Como j foi dito os arrays usam vrias partes da memria seguidas (sejam uni, bi, tri, n
dimensionais, sempre tudo seguidinho) e por isso tm vrios endereos.
Os arrays e os ponteiros so bastante parecidos. Os arrays apontam para o primeiro endereo
que usam (o endereo da clula 0) e depois entre parenteses retos determina-se em que clula
se quer ir buscar a informao (a memria dos arrays est seguida). Os ponteiros funcionam
da mesma forma, eles apontam para o primeiro endereo e depois para apontar para os
outros pode-se usar parenteses retos ou somar o nmero de clulas a frente.
Para mostrar que so essencialmente o mesmo:
void main()
{
int v[4] = {0,1,2,3};
int *ptrv = v;
printf("%d\n",*ptrv);
printf("%d\n",*(ptrv+2));
printf("%d\n",ptrv[2]);
}
Output:
0
2
2
Funes 2:
Depois de perceber como funcionam os ponteiros e vetores vamos complicar as funes.
Os parmetros de entrada so variveis locais que iram receber os valores de outras variveis,
ou seja, estas so cpias das originais, por isso qualquer valor que aqui seja alterado apenas e
s alterado nesta funo, a original mantm-se como estava.
As funes apenas podem retornar 1 varivel! Por isso uma maneira de poder alterar vrios
valores dentro de uma funo usando ponteiros como parmetros de entrada, assim
alteramos a varivel original e no uma cpia.
Como j foi dito, arrays e ponteiros so fundamentalmente semelhantes e por isso ao alterar
um array numa funo ir ser alterado o original. esta a razo por no usar o & no scanf para
strings e usar para os outros tipos.
Exemplo que mistura varias coisas ditas anteriormente:
Output:
Array de tamanho: 5
Valor 3 adicionado na posicao: 2.
|1||2||3||4||5|
Estruturas:
Para alm dos outros tipos de dados que j foram falados existe o tipo struct. As estruturas
podem conter varias variveis de vrios tipos diferentes e assim sendo fcil de guardar vrios
tipos de dados numa s varivel.
-Declarao
A sintaxe simples:
struct NomeStruct
{
declarao_campos;
};
O NomeStruct o nome da estrutura que se quer dar. Dentro do bloco feita a declarao dos
campos (variveis) que iram fazer parte da estrutura. possvel fazer a inicializao destas na
declarao. O ponto e vrgula no fim do bloco necessrio.
-Criao de variveis:
Uma estrutura no uma varivel, mas sim um tipo. Assim sendo primeiro criamos uma
estrutura e depois criamos variveis com essa estrutura, estas podem ser, variveis normais,
ponteiros ou arrays.
Para isso do mesmo modo que a declarao de uma varivel mas substituindo o tipo por
struct NomeStruct .
Duas variveis com a mesma struct como tipo sero variveis diferentes e portanto os campos
da estrutura iram ter valores e endereos diferentes!
Tambm se podem criar as variveis quando se define a estrutura, pondo o nome das variveis
a frente do } e antes da ;
#include <stdio.h>
#define MAX_NOME 100
#define MAX_ALUNO 25
struct aluno
{
char nome[MAX_NOME];
int idade;
int numero;
float nota;
};
void AdicionarDadosAluno(struct aluno *a)
{
if(!a) //if(a == NULL)
return;
printf("\nInsira o numero do aluno: ");
scanf("%d", &a->numero);
printf("Insira o nome do aluno: ");
scanf("%s", a->nome);
printf("Insira a idade do aluno: ");
scanf("%d", &a->idade);
printf("Insira a nota do aluno: ");
scanf("%f", &a->nota);
}
void main()
{
struct aluno turma[MAX_ALUNO];
int tam;
printf("Insira o numero de alunos: ");
scanf("%d", &tam);
for(int i=0; i<tam; i++)
AdicionarDadosAluno(&(turma[i]));
}
typedef:
O nome typedef vem de type definition que significa definio de tipos. Basicamente isto
facilita bastante a criao de novos tipos para a criao mais fcil de variveis. Por exemplo
com o typedef podemos definir o tipo int* como ptrint e assim para criar um ponteiro apenas
temos que escrever ptrint e no int *.
O typedef bastante usado para criar um tipo de variveis para as estruturas e assim a criao
de variveis fica mais fcil porque no tem que se escrever struct. Neste caso no precisamos
de dar nome a estrutura.
possvel criar mais do que um tipo numa s definio, por exemplo numa struct podemos
criar uma definio para variveis normais e outra para ponteiros.
Seguindo o exemplo anterior se usarmos typedef o cdigo podia ficar como o seguinte:
#include <stdio.h>
#define MAX_NOME 100
#define MAX_ALUNO 25
typedef struct
{
char nome[MAX_NOME];
int idade;
int numero;
float nota;
}ALUNO, *PTALUNO; //PTALUNO > ponteiro
void AdicionarDadosAluno(PTALUNO a)
{
if(!a) //if(a == NULL)
return;
printf("\nInsira o numero do aluno: ");
scanf("%d", &a->numero);
printf("Insira o nome do aluno: ");
scanf("%s", a->nome);
printf("Insira a idade do aluno: ");
scanf("%d", &a->idade);
printf("Insira a nota do aluno: ");
scanf("%f", &a->nota);
}
void main()
{
ALUNO turma[MAX_ALUNO];
int tam;
printf("Insira o numero de alunos: ");
scanf("%d", &tam);
for(int i=0; i<tam; i++)
AdicionarDadosAluno(&(turma[i]));
}
Casting:
Casting o ato de alterar o tipo de varivel diretamente. H certas funes que no devolvem
um tipo de dados especfico7 e nesse caso usamos um casting para certificarmos que os dados
ficam corretos e o programa no dar warnings de tipos de variveis erradas.
Tambm converte alguns tipos de variveis para outros. Por exemplo, queremos fazer a
diviso de 2 int, mas queremos o resultado em float, para isso vamos ter que fazer um cast em
pelo menos 1 int.
Para fazer casting apenas temos que escrever o tipo de dados desejado entre parenteses antes
do nome da varivel a converter.
Ateno, nem todos os tipos, especialmente arrays, structs, d para converter diretamente par
outros.
7
Exemplo:
int x = 5, y=2;
float f = x/(float)y;
Neste caso f ir ficar com valor 2.5 em vez de 2 que seria o valor se no fosse feito casting.
A memria no infinita e pode nem sempre haver espao e nesse caso a alocao
no feita. Sempre que usarem uma destas funes verifiquem logo se deu NULL ou
no. Habituem-se para no se esquecerem.
A memria depois de alocada tem que ser desalocada quando j no necessria.
Cada vez que fazem malloc, calloc ou realloc (exceto se for para realocar, como disse
o realloc pode ser usado como malloc) usem logo a funo free para no se
esquecerem!
Se no usaram uma destas funes ento o free no preciso nem se pode usar.
Arrays no so alocados dinamicamente por isso o free no tem efeito neles.
Com o malloc no nBytes temos que indicar o nmero de Bytes que queremos alocar. Para isso
usamos a funo sizeof que retorna o tamanho de uma varivel ou tipo em Bytes. No caso de
arrays multiplicamos o resultado do sizeof com o nmero de clulas desejadas. Em caso de
arrays bi/tri/whatever dimensionais iremos multiplicar o sizeof pelos diferentes nmeros de
clulas. Exemplo:
Int *matriz = (int *)malloc(sizeof(int) * 2 * 3); //int matriz[2][3];
Nos casos que tm mais do que uma dimenso no possvel usar mais do que 1 conjunto de
parenteses retos, por isso temos que ir calcular a posio na memoria relativamente
primeira clula. Sejam nc e nl o nmero da clula desejada no mximo dos usados no exemplo
anterior (2 e 3 respetivamente). Para acedermos a esse valor temos que fazer do seguinte
modo:
matriz[nc*3+nl];
//ou *(matriz+nc*3+nl);
Isto o mesmo que matriz[nc][nl] caso no fosse um ponteiro. O 3 representa o nmero
mximo do segundo parenteses reto. Isto serve para qualquer ponteiro para arrays mais de 1
dimenso.
Exemplo:
void main()
{
int *matriz = (int *)malloc(sizeof(int) * 2 * 3);
if(!matriz)
return;
for(int i=0; i<2; i++)
for(int n=0; n<3; n++)
matriz[i*2+n] = (i+1)*n;
for(int i=0; i<2; i++)
for(int n=0; n<3; n++)
printf("|%d|", *(matriz+i*2+n));
free(matriz);
}
Recursividade:
Ah, a bela da recursividade xD
Como j devem ter percebido (se no deviam) as funes podem ser chamadas dentro de
outras funes e at ser usadas como argumentos. Da nada de novo. Porm as funes
tambm se podem chamar a si prprias e comeam assim um ciclo sem ser for nem while.
Em teoria recursividade quando algo est definido em funo de si mesmo. Basicamente
chamaste a ti mesmo para te acabar. o que aqui diz.
J agora, mtodo iterativo o que no recursivo, ou seja usa um ciclo for por exemplo.
A maior parte das vezes usando recursividade menos eficiente pela quantidade grande de
chamadas da funo que ocupam memria quando comparado com uma funo iterativa. No
entanto pode ser mais fcil de perceber/fazer e muitas vezes nem usa variveis auxiliares. Em
rvores binrias muito usado a recursividade em vez de um mtodo iterativo pela maior
facilidade de fazer e perceber, a maior parte dos exemplos ficar nessa seco!
Um exemplo muito usado e pedido uma funo que faa a sequncia de Fibonacci8
int Fib(int N)
{
if(N == 0 || N == 1)
return N;
else return Fib(N-1)+Fib(N-2);
}
Enumeraes:
O enum uma maneira fcil de criar expresses com um valor especfico.
Um exemplo as variveis booleanas. Apenas em verses mais recentes o bool j vem
implementado, mas antes disso para poder-mos ter o true e false usava-se um enum:
typedef enum {true;false}bool;
A sintaxe praticamente igual s estruturas. Porem os elementos no tm um tipo definido,
so apenas expresses. Se no lhes dermos um valor por predefinio so lhes atribudos os
valores a comear em 0 at ao numero de elementos -1. Se por exemplo quisermos os meses
do ano em nmero a comear em 1 bastava fazer um enum{janeiro =1, fevereiro,maro,
Deste modo o enum comea no numero 1 e vai dar o resto dos valores automaticamente.
Para aceder do mesmo modo que a varivel bool e no com pontos ou setinhas como nas
estruturas.
Ficheiros:
Trabalhar com ficheiros bastante importante para guardar e carregar dados.
Para trabalharmos com ficheiros temos que criar um ponteiro para o ficheiro do tipo FILE.
De certo modo funcionam como se fosse um livro, antes de inserires ou leres tens que abrir o
ficheiro em modos diferentes, por exemplo modo leitura ou modo escrita. Para guardar as
alteraes e prevenir perda de informao sempre que se abre um ficheiro tem que se fechalo no fim.
Google yourself!
possvel abrir um ficheiro no modo binrio. O modo binrio mais rpido que ficheiros de
texto normais. Para isso basta adicionar um b no fim no modo (por exemplo a+b).
-Escrever
Escrever num ficheiro feito da mesma forma que se escreve na caixa de comandos. Usam-se
as mesmas funes mas com o f antes do nome da funo e tm mais um parmetro, o
ponteiro para o ficheiro (fprintf, fputs, fputc).
Tambem existe a funo fwrite
size_t fwrite(void *ptr, size_t size, size_t count, FILE *f);
Esta funo permite escrever elementos de qualquer tipo no ficheiro.
Exemplo:
void main()
{
FILE *f = fopen ("array.bin", "wb");
int arr[] = {1,2,3,4,5,6,7,8,9,10};
fwrite (arr , sizeof(int), sizeof(arr), f);
fclose (f);
}
Esta funo vai criar um ficheiro binrio array.bin e escreve l o array arr.
-Leitura:
A leitura feita da mesma maneira que a leitura da caixa de comandos (fscanf, fgets, fgetc).
semelhana da escrita tambm tem uma funo que vai ler elemento a elemento:
size_t fread(void *ptr, size_t size, size_t count, FILE *f);
Esta funo permite escrever elementos de qualquer tipo no ficheiro.
void *ptr: ponteiro para onde queremos gravar o que lemos no ficheiro;
size_t size: o tamanho do tipo do elemento que se quer ler;
size_t count: a quantidade de elementos que para ler;
FILE *f: ponteiro para o ficheiro que para escrever.
Retorno: nmero de elementos que foram lidos com sucesso
void main ()
{
FILE *f = fopen ("array.bin", "rb");
int arr[10];
fread (arr , sizeof(int), 10, f);
fclose (f);
}
-Posicionamento:
As vezes preciso voltar atrs no ficheiro ou avanar para o fim e isso possvel atravs das
funes fseek, rewind e ftell. A ftell diz o numero do byte em que est neste momento, o
fseek d para ir para um determinado byte determinando o offset de uma origem
(fseek(FILE*f,long offset,int origem)) Para mais informaes:
http://www.cplusplus.com/reference/cstdio/fseek/
Listas e Pilhas:
Fila/listas e pilhas so uma forma de ter uma base de dados extensa no programa de uma
maneira fcil e organizada e de realizar operaes sobre elas.
So um conjunto de ns (nodos ou o que quiserem) que contm 2 ponteiros, um para o
seguinte n e outro que aponta para a informao desse n. Assim sendo tm sempre pelo
menos 2 estruturas, uma para o n e outro para a informao. (O ponteiro para a informao
no necessrio, a informao pode ficar contida no n, mas mais fcil de perceber assim).
habitual serem criadas 3 estruturas. A primeira contm o nmero de nos de uma lista/fila e
um ponteiro para o incio. As outras 2 so as que foram referidas anteriormente.
As diferenas entre Listas e Pilhas est no prprio nome. Uma pilha como se fosse uma pilha
de qualquer coisa, apenas podes tirar do cimo e por no cimo. Uma Lista podes colocar ou
retirar seja onde for. Uma fila uma mistura dos dois, inseres no incio retiras do fim. Devido a
isso apenas vou explicar as listas visto que o resto so casos particulares deste.
H 2 grandes tipos de listas, as biligadas e as simplesmente ligadas. A diferena est em que
nas biligadas os ns contm ponteiros para o prximo e para o no anterior. E a lista tem um
ponteiro para o incio e fim. til para listas com muitos elementos, mas se forem poucos
torna-se desnecessrio.
-Criao e Declarao:
As listas no so nada mais que estruturas ligadas entre si. Eu costumo usar 3 estruturas, mas
no a nica forma de fazer.
Em primeiro lugar cria-se uma estrutura para guardar a informao. De seguida preciso uma
estrutura n, que ir conter o ponteiro para a informao e outro para o n seguinte
(alternativamente pode-se ter um ponteiro para o n anterior e assim torna-la numa lista
biligada). A 3 estrutura contem um inteiro para guardar o nmero total de ns e um ponteiro
para o incio da lista.
Para declarar um varivel lista usa-se a 3 estrutura (usualmente em ponteiro). Pode-se inicila a NULL e assim dizer que a lista no existe, ou aloca-la dinamicamente, mas ao aloca-la tem
que se por o ponteiro para o inicio a NULL e o inteiro a 0.
Exemplo:
typedef struct
{
char *nome;
int numero;
}ALUNO;
typedef struct no
{
ALUNO *info;
struct no *next; //no se pode usar NO porque o NO ainda no foi
definido como a struct aqui
}NO;
typedef struct
{
NO *inicio;
int nel;
}LISTA;
void main()
{
LISTA *L = NULL;
}
-Pesquisar:
Para passar por todos os ns da lista ir ser necessrio pelo menos uma varivel auxiliar com o
tipo NO. Esta ir receber o ponteiro para o incio. Com um ciclo while verifica-se se existe e
executa o cdigo especificado, se no existir quer dizer que alcanamos o fim da lista e por isso
sai do ciclo.
-Insero de um novo n:
Para introduzir um n primeiro tem que se criar e dar valores a uma varivel ponteiro para a
estrutura com a informao a guardar. De seguida criar um novo n e inserir a informao
anteriormente criada neste.
O valor que se coloca no ponteiro para o prximo vai depender de onde se quer colocar o n
na lista. Se for no fim este ser NULL, mas se for no incio ser um ponteiro para o atual
primeiro da lista.
Mas ambos so um caso particular da insero no meio, por isso para os exemplos iremos criar
uma funo para inserir na lista os ns ordenados pelo nmero.
Exemplo:
-Remoo:
Para remover um n da lista mais simples que inserir, basicamente tem que se procurar pelo
identificador do NO a remover e depois fazer os free necessrios. NO fazer free ao next,
apenas ao info. Tambm preciso certificar que o no anterior fica a apontar para o seguinte
do que foi removido!
Exemplo:
void RemoveNO(LISTA *L, int num)
{
if(!L) //lista no existe entao adeus
return;
NO *ax = L->inicio,
*ant = NULL;
while(ax && ax->info->numero <= num) // a lista est ordenada!!
{
if(ax->info->numero == num)
{
if(ant)
ant->next = ax->next;
else L->inicio = ax->next; //se o ant for NULL entao o
inicio muda
free(ax->info->nome); //alocamos o nome
free(ax->info);
free(ax);
L->nel--;
ax = NULL; //sai do ciclo
}
}
}
Hashing:
Basicamente hashing usar arrays para separar informao, normalmente listas por uma
chave (pode por exemplo ser a primeira letra do nome, agrupa todos os que comeam por a
no ndice 0, etc).
bastante simples de usar o hashing, basta substituir o inicio da 3 estrutura de uma lista por
um array de ponteiros para o no. Ou ento criar um array de listas, nem preciso criar uma
nova struct se no quiserem.
O modo de funcionamento igual aos arrays, porque um array, s muda o tipo e o tipo passa
a ser uma lista, portanto apenas misturar a modo de funcionamento dos arrays e listas.
Arvores Binrias:
Pensem numa rvore genealgica de pernas para o ar, mais ou menos parecido.
Arvores outra forma de guardar informao. Tendes o topo e depois cada n tem um
ponteiro para a esquerda e outro para a direita.
Programao modular:
Se usarmos apenas um ficheiro para um programa iremos ter um ficheiro enorme com
demasiadas linhas de cdigo e mal organizado, para combater este problema um programa
pode conter vrios ficheiros .cpp com funes. Assim o cdigo pode ficar separado em vrios
ficheiros, melhor organizado e mais fcil de procurar o que for preciso.
Porm os ficheiros no esto diretamente ligados e por isso os tipos e variveis definidos num
ficheiro no vo estar no outro.
-extern
extern uma palavra reservada que vai buscar algo a um dos ficheiros do projeto. Por
exemplo, criamos uma funo no ficheiro funes.cpp e queremos usar essa funo no
ficheiro main.cpp, para isso no ficheiro main.cpp teremos que escrever extern headerfuno;.
Substitui-se o headerfuno pelo header da funo aquando declarada pelo outro ficheiro.
No preciso especificar em que ficheiro est, ele vai buscar automaticamente. Tambm pode
ser usado para variveis.
-Headers:
Header files so ficheiros como includes. So bastante uteis para quando se tm vrios
ficheiros que usam as mesmas estruturas e tipos. Assim possvel criar as estruturas, tipos,
defines e usar as mesmas includes num s ficheiro e usa-lo nos que forem necessrios.
Para incluir um ficheiro header criado por ns usando #include NomeHeader.h.
Tambm possvel usar um ficheiro .h para no usar extern. Para isso basta escrever os headers
das funes no .h e depois criar o corpo da funo num ficheiro que inclua este header.
Neste exemplo criamos a funo calculo que o que faz mostrar o resultado retornado por
uma funo que devolve um int e tem como parmetros de entrada 2 int.
typedef struct
{
int num;
char nome[120];
}ALUNO;
typedef struct
{
int nalunos;
char nome[120];
}DISCIPLINA;
typedef struct no
{
void *info;
struct no *prox;
}NO;
typedef struct
{
NO *inicio;
int nel;
}LISTA;
void CriarAlunos(LISTA *L)
{
if(!L)
return;
ALUNO *A = (ALUNO *)malloc(sizeof(ALUNO));
if(!A)
return;
strcpy(A->nome,"Kimossab");
A->num=14180;
NO *novo = (NO *)malloc(sizeof(NO));
novo->info = A;
novo->prox = NULL;
L->inicio = novo;
L->nel = 1;
}
void CriarDisci(LISTA *L)
{
if(!L)
return;
DISCIPLINA *A = (DISCIPLINA *)malloc(sizeof(DISCIPLINA));
if(!A)
return;
strcpy(A->nome,"IP");
A->nalunos=20;
NO *novo = (NO *)malloc(sizeof(NO));
novo->info = A;
novo->prox = NULL;
L->inicio = novo;
L->nel = 1;
}
Aqui est um exemplo de como com 4 estruturas se pode criar 2 listas diferentes e inserir l
valores. Notar como o novo->info aceita tanto DISCIPLINA como ALUNO.
Macros:
As Macros so pores de cdigo que so substitudas pelo pr-processador antes de o
compilador passar pelo cdigo.
O #define que j foi falado usado para criar macros, no cdigo C mas pode ser usado em
qualquer linha e indica ao pr-processador que a partir daquela linha uma expresso que l
colocarmos ir ser substituda por outra expresso que l colocarmos.
Normalmente os macros so conhecidos no pela definio de constantes como foi falado mas
sim de funes.
Exemplo:
#define Multi(x,y) (x*y)
A primeira parte do define funciona como uma funo, procura a palavra Multi que tenha 2
parmetros entre parenteses (independentemente do tipo) e depois vai substituir toda essa
expresso pela 2 parte do define, por exemplo:
int x = Multi(2,3); // o que o pr processador faz isto: int x=(2*3)
Neste caso esta funo no retorna um valor mas substituda pelo que est a frente.
Para poder escrever em mais do que uma linha, no fim da linha coloca-se \.
-#
Num macro o smbolo # um smbolo que diz que coloca um dos parmetros entre aspas.
Deste modo convertendo uma expresso no seu equivalente em string.
Exemplo:
#define getstring(x) #x
void main()
{
printf(getstring(Sem aspas ( "" )\n));
}
-##
## um concatenador, ou seja junta duas expresses, a da esquerda com a da direita. Lembrar
que os macros so expresses e no valores.
Exemplo:
#define getvar(x) var ## x
void main()
{
int var1=2,var2=3,var3=4,var4=5;
printf("%d", getvar(3));
}
-Pr definies
J existem macros pr definidas, entre algumas esto:
-#ifdef
possvel verificar se algum macro est j est definido. Isto bastante til para evitar que um
header file seja includo mais do que uma vez e assim prevenir erros como o de criar estruturas
j criadas. Tambm til para executar cdigos diferentes dependendo do sistema que for
(por exemplo em Linux algumas funes tm que ser diferentes por o sistema no as suportar
e as barras na direo de ficheiros so diferentes para Linux e Windows (\ e /))
Para verificar se um macro j existe usa-se o #ifdef ou #if defined e colocar o macro que se
dejesa verificar a frente. Pode-se usar tambm #elseif e #else. Para terminar um bloco #if
preciso usar o #endif.
A negao do #ifdef ou #if defined #ifndef e #if !defined respetivamente.
Exemplos:
//windows
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32)
&& !defined(__CYGWIN__)
#include <direct.h>
#define GetCurrentDir _getcwd
#define SetCurrentDir _chdir
#else //unix
#include <unistd.h>
#define GetCurrentDir getcwd
#define SetCurrentDir chdir
#endif
#ifndef MyLib_h
#define MyLib_h
//INCLUDES
//typdef
//structs
//headers de funoes
#endif
Este ultimo vai verificar se um header file j foi includo e assim prevenindo que seja includo
outra vez.
sscanf: faz o scanf mas a uma string, o primeiro parmetro o da string qual
queremos fazer o scan.
sprintf: faz o printf a uma string, assim deste modo podemos inserir dados numa string
facilmente. O primeiro parmetro o da string a qual ir ficar com o resultado.
setlocale: esta funo que vem na libraria locale.h bastante til porque ir definir o
locale do programa e assim permitir a utilizao de caracteres especiais e das normas
conforme a localizao definida. O primeiro parmetro para escolher o que parte do
sistema queremos definir o locale (tudo, tempo, valores numricos, valores
monetrios, etc.). O segundo parmetro o locale que queremos, para usar o do
sistema basta colocar . Mais informao:
http://www.cplusplus.com/reference/clocale/setlocale/ e
https://msdn.microsoft.com/en-us/library/cdax410z.aspx
fflush: o fflush fora a que bytes que ainda estejam num stream (podem ser ficheiros)
sejam colocados e limpa o stream, deste modo forando a que mensagens sejam
mostradas ou guardadas limpa o stream para receber mais informao (bastante
usado antes de um gets para limpar o stdin (standard input) com fflush(stdin))
strcmp e stricmp: compara duas strings, a primeira case sensitive, a segunda no. Se
a primeira string for menor devolve -1 se forem iguais devolve 0 se for maior devolve 1
rand(): includo no include stdlib.h uma funo para calcular um nmero pseudoaleatrio. Para poder obter um nmero aleatrio entre 0 e x basta fazer o resto da
diviso inteira (%) da funo rand() por x+1. Exemplo: numero aleatrio de 0 a 9:
rand() %10.
Cdigos teis:
Alguns cdigos que podem ser teis.
necessrio fazer um flush ao stdin porque o enter fica no buffer do teclado e depois est
sempre a l-lo.
Debug:
ESTE CAPITULO FOI FEITO BASEADO NO VISUAL STUDIO 2013. TAMBEM FUNCIONA PARA
OUTRAS VERSES DO VS, MAS PARA OUTROS COMPILADORES PODEM MUDAR ALGUMAS
COISAS, MAS A LGICA A MESMA.
Muitas vezes o cdigo no faz o que queremos ou simplesmente o programa crasha e ns no
sabemos porqu. No modo debug tudo isto pode ser facilmente solucionado.
Para entrar no debug pressionem F5 e o cdigo ser compilado e depois executado no modo
debug.
-Crash:
Quando ocorre um crash no programa no modo debug normalmente aparece uma mensagem
de erro do gnero:
A maior parte das vezes que esta message box aparece porque tentmos aceder a um
ponteiro que est a NULL, mas nem sempre o caso. Nesta situao pode-se ver que o erro diz
que tentou aceder memria na localizao 0x00000000, por isso neste caso foi mesmo por
causa de um NULL. Mas apenas isto no nos diz onde ocorreu.
Pressionem Break e no cdigo poderam ver a linha onde ocorreu o erro assinalada com uma
setinha:
Neste caso fcil de perceber o que correu mal. A varivel L est a NULL. Mas isso nem
sempre fcil de perceber no meio de muitas linhas e funes, por isso h outras duas
ferramentas importantes no debug no Visual Studio, o break points e a janela Locals.
-Locals:
A melhor ferramenta que podem ter no debug. Para a ligarem durante um debug podem ir na
barra de tarefas a Debug > Windows > Locals ou ento ALT+4.
Esta janelas mostra as variveis e os valores destas naquele momento e assim tornando-se
ainda mais fcil de perceber o que se pode passar de errado ao verificar os valores.
Como se pode ver esta janela d o nome da varivel, o seu valor e o seu tipo. Neste casp est
confirmado que o valor de L NULL e isso foi o que fez o programa crashar.
-Break Points:
Por vezes o programa no crasha mas o cdigo no faz o que pensvamos que iria fazer e
portanto existem erros lgicos no programa. Por isso s vezes d jeito saber em que partes do
programa que o cdigo passa, ou saber os valores das variveis em certas linhas do cdigo,
para isso podemos usar break points.
No modo de debug quando o programa passa por uma linha que tenha um break point este
para nessa linha at o mandarmos seguir.
Para colocar um break point apenas temos que carregar no lado esquerdo da linha que
queremos que tenha um break:
O ponto a vermelho assinala o break. A setinha a amarelo indica a linha onde o programa est
parado.
-Mensagens de debug:
Para outros IDEs onde isto ou algumas coisas no sejam possveis uma boa maneira de saber o
que se vai passando no cdigo com mensagens de debug. Fazer uns printf para mostrar os
valores de variveis ou saber se o cdigo passou por uma seco que no devia ou coisas do
gnero. Desse modo tambm fcil de saber o que se passa de errado com um cdigo e assim
corrigi-lo.