Buscar

ALGORITMOS&ESTRUTURASdeDADOS

Prévia do material em texto

� �Professora ANITA LOPES
 ��
FUNDAMENTOS DA LINGUAGEM C++
	
1 A linguagem C++
1.1	Introdução
	
A linguagem C++ foi desenvolvida nos Laboratórios da BELL. Ela é baseada na linguagem C, mas acrescenta características de uma linguagem orientada a objetos.
Nosso estudo não fará menção a orientação a objetos. 
A linguagem C++ é "Case Sensitive", isto é, maiúsculas e minúsculas fazem diferença.
	1.2	Estrutura de um programa em C++
	
	Um programa em C++ é constituído de:
cabeçalhos que contém definições de pré-processamento tais como os arquivos de cabeçalho, as definições de constantes simbólicas, uso denamesapces,declaração de variáveis globais, declaração de rotinas, etc.
um bloco da função principal e outros blocos de funções.
comentários. 
	[ <definições de pré-processamento> ]
	[ <declaração de variáveis globais> ]
	int main()
	{
	 Bloco de comandos
	}
	<tipo de retorno da função> <nome_da_função1 >( <parâmetros>) >
	{
	 Bloco de comandos da função1
	}
	...
	<tipo de retorno da função> <nome_da_funçãon >( <parâmetros>) >
	{
	 Bloco de comandos da função2
	}
Exemplo de um programa em C++
#include <iostream>
usingnamesapce std;
int main()
{ 
 cout<<"\nPRIMEIRO PROGRAMA EM C++";
}
	Explicando:
	#include <iostream> instrui o compilador a usar a biblioteca padrão de entrada e
 saída
 using namesapce std; uso do namespace padrão std 
	int main() main é o nome da função principal; 
 { inicia a função
	 cout imprime na tela a msg após alimentar linha
	} finaliza a função
1.2.1 	Conjunto de caracteres
	Um programa fonte em C++ é um texto não formatado escrito em um editor de textos usando um o conjunto padrão de caracteres ASCII.	
	
Caracteres válidos:
	As letras minúsculas e maiúsculas não acentuadas
	Os algarismos de 0 - 9 
 	+ - * / \ = | & ! ? # % ( ) { } [ ] _ ‘ “ . , : < >
	
	Observação: Qualquer outro caracter é valido para as strings. 
	1.2.2	Comentários
	Os comentários em C++ podem aparecer em qualquer lugar do programa e têm como objetivo fazer um esclarecimento sobre uma linha ou trecho do programa.
	Os comentários de bloco terão um /* antes e um */ depois, ou // quando se deseja comentar uma linha.
	Exemplo:
	/* programar em 
 C++ eh facil */	
 // so uma linha
	1.2.3 	Diretivas de Compilação
	Na linguagem C++, alguns comandos são processados durante a compilação. Estes comandos são chamados de diretivas de compilação e são eles que informam quais bibliotecas e constantes simbólicas deverão ser anexadas quando for gerado o programa executável.
A diretiva #include diz ao compilador para incluir na compilação do programa outros arquivos. Geralmente estes arquivos contem bibliotecas de funções ou rotinas do usuário. 
As bibliotecas agrupam funções de acordo com as finalidades. Se não fizéssemos uso delas, nossos programas seriam muito extensos e teríamos problemas na linkedição. 
Sintaxes: 
	#include <nome_da_biblioteca >
	#include “...nome_da_biblioteca ”
onde nome_da_biblioteca é o nome da biblioteca que se deseja incluir. Estando entre os sinais < e > significa que está no diretório padrão e ficando entre “, significa que precisamos fornecer o caminho onde se encontra a biblioteca.
	Exemplos de bibliotecas:
BIBLIOTECA ctype.h
	Converte para maiúscula ou para minúscula uma letra
	toupper(letra)
	tolower(letra)
BIBLIOTECA math.h
	Calcula o valor absoluto real d
	fabs(double d)
	Funções trigonométricas do ângulo arco, em radianos
	sin(double arco)
	cos(double arco)
	tan(double arco)
	asin(double arco)
	acos(double arco)
	atan(double arco)
	Funções de arredondamento para inteiro
	ceil(double num) Ex. ceil(3.2) => 4.0 arredonda pra cima
	floor(double num) Ex. floor(3.2) => 3.0 arredonda para baixo
	Funções logarítmicas: log() é logaritmo natural (base e), log10() é logaritmo decimal (base 10)
	log(double num)
	log10(double num)
	Funções: potência e raiz quadrada
	pow(double base, double exp); Potenciacao: pow(3.2,5.6) => 3.25.6
	sqrt(double num); Raiz quadrada: sqrt(9.0) = >3.0.
BIBLIOTECA stdlib.h
		Calcula o valor absoluto do inteiro i e do real d, respectivamente
	abs(int /float)
	rand()
BIBLIOTECA string.h
		Concatena duas strings
	strcat(str1, str2);
	Copia o conteúdo de uma variável em outra variável
	strcpy(str1, str2) /* não é permitido: str1 =str2;*/
	Fornece o número de caracteres de uma string
	strlen(str1) 
	Compara duas strings 
	 devolve número menor que 0 se str1 vier antes de str2 
strcmp(str1, str2) devolve número maior que 0 se str1 vier depois de str2
 devolve 0 se str1 for igual à str2 
2. Saída 
	O objeto cout permite que enviemos dados/mensagens para a tela.
 
	Usando: using namespace std; 
	cout<<” …”;
cout<<variavel<<endl;
	Usando: using std::cout; 
	cout<<” …”;
cout<<variavel<<endl;
	Não usando namespace
	std::cout<<” …”;
std::cout<<variavel<<endl;
		 
		Controle/Caracter
	Seqüência de escape
	nulo (null) 
campainha (bell) 
retrocesso (backspace) 
tabulacao horizontal 
nova linha (new line) 
tabulacao vertical 
alimentacao de folha (form feed) 
retorno de carro (carriage return)
aspas (") 
apostrofo (') 
interrogacao (?) 
barra invertida (\) 
	\0
\a
\b
\t
\n
\v
\f
\r
\"
\'
\?
\\
	
	#include <iostream>
using namespace std;
int main()
{ cout<<"Aprendendo a usar \"cout\"\n" ; 
 // o caracter \" imprime aspas na tela
 cout<<"O operador de insercao << separa os elementos que se desja colocar na tela\n";
 cout<<"O caracter de controle \'\\n\' equivale a endl, alimenta linha"<<endl;
 cout<<"Usando \'\\t\' \timprime-se na proxima zona\n";
 // o caracter \’ imprime apostrofo na tela e o carcater \\ imprime \ na teal
 system("pause");
}
	
3. Constantes e variáveis
	
3.1 Constantes
	O C++ possui quatro tipos básicos de constantes: inteiras, de ponto flutuante, caracteres e strings. Constantes inteiras e de ponto flutuante representam números de um modo geral.
	3.1.1	Constantes inteiras
	As constantes inteiras na linguagem C++ podem ser escritas no formato decimal (base 10), hexadecimal (base 16) ou octal (base 8). 
	Exemplos:
 	Decimal: 12 
	Octal : 033 ( em decimal vale 27. O zero antes do número caracteriza a constante octal)
	Hexadecimal: 0xff ( em decimal vale 255. O zero e o x antes do número caracterizam a constante hexadecimal)
	
	3.1.2	Constantes de ponto flutuante
	
	São números reais com um ponto decimal e (opcionalmente) um expoente.	
	Exemplos: 
	1.876 476.65 1.23e-9 -1.e2 10.6e18 -.853E+67
	3.1.3	Constantes caracteres
	Uma constante caracter é uma letra ou símbolo colocado entre plicas.
	Exemplo:
	’A’	’N’	’I’	’T’ ’A’	
	As constantes caracter são armazenadas como números inteiros. Estes números correspondem aos valores de cada caracter dentro do código ASCII.
	
	3.1.4	Constantes strings
	Uma constante string consiste de um conjunto de caracteres do código ASCII padrão ou estendido, colocados entre aspas duplas.
	Exemplo: 
	”UAL!”
	”Matemática”
	”APRENDENDO A PROGRAMAR EM C++ ”
Na linguagem, C++ uma string é um vetorde caracteres terminado com um caracter nulo. O caracter nulo é um caracter com valor inteiro igual a zero (código ASCII igual a 0). O terminador nulo também pode ser escrito usando a convenção de barra invertida do C como sendo '\0'.
	char nome_da_string[tamanho];
Como precisamos reservar uma posição para o terminador, sempre iremos declarar o tamanho necessário mais um.
Vamos supor que declaremos uma variável de nome palavra de 11 posições(char palavra[11]; ) e armazenemos a palavra PROGRAMAS nela. 
É bom ressaltar que a linguagem C++ não inicializa as variáveis e toda célula não usada têm valor indeterminado. 
Não se esqueça de inicializar as variáveis de seus programas, pois coisas incríveis podem acontecer!
As strings são consideradas vetores de caracteres( matriz linha). Como na Matemática, para se acessar um determinado caracter de uma string, basta "indexarmos". 
	
	str[1] = 'o'
str[2] = 'a'
	No exemplo acima, percebemos que o primeiro caracter se encontra na posição 0( em algumas linguagens, seria a posição 1). Desta forma, se indexarmos com 1, na verdade estaremos nos referindo ao segundo caracter da string; se indexarmos com 2, na verdade estaremos nos referindo ao terceiro caracter da string e assim sucessivamente. 
3.1.5 Constantes Simbólicas
	A Matemática define pi como tendo o valor 3,14159265. Muitas vezes precisaremos definir algumas constantes em nossos programas.
3.1.5.1 Constantes definidas pelo programador 
	
	O programador pode definir constantes simbólicas em qualquer programa.
	Sintaxe: 
	#define <nome> < valor >
	Onde #define é uma diretiva de compilação que diz ao compilador para trocar as ocorrências do texto nome por valor. Observe que não há ; no final da instrução pois trata-se de um comando para o compilador e não para o processador. A instrução #define deve ser escrita antes da instrução de declaração da rotina principal. 
	
	O uso da diretiva #define não se restringe apenas para declarar constante(#define pi 3.14159265 ) mas também podemos usá-la para definir macro instruções(#define conv(x) (x*pi/180) ou #define quadrado(x) (x*x) ). 
3.2 Variáveis
A variável é um lugar(endereço) na memória principal que armazena um dado e tem um nome associado para facilitar a programação .
	Em C++, as variáveis podem ser declaradas no inicio do programa, mas poderemos também declarar dentro de algumas estruturas, diferentemente de outras linguagens. Estas variáveis podem ser de vários tipos: int (inteiro), float (real de simples precisão) , char (caracter único), double (real de dupla precisão).
	A classe String será vista em outro momneto.
	Tipo
	Tamanho
	Intervalo
	Uso
	char
int 
float 
double
	1 byte 
4 bytes 
4 bytes 
8 bytes 
	-128 a 127
-2147483648 a 2147483647
3.4e-38 a 3.4e38 
1.7e-308 a 1.7e308 
	número muito pequeno e caracter ASCII
contador, controle de laço
real (precisão de 6dígitos)
científico (precisão de 10 dígitos)
	Quando se define um tipo de variável, informamos ao computador quanto de memória será necessária para armazenar este dado e que tipos de operações poderão ser realizadas com este dado.
	Para se declarar uma variável, usamos a seguinte sintaxe:
	< tipo> nome_da_variável ;
	
	O nome de uma variável deve obedecer algumas regras:
O primeiro caracter pode ser uma letra ( maiúscula ou minúscula) ou o caracter sublinha. Aconselha-se a não usar o caracter sublinha no inicio para não confundir com algumas funções. 
Os demais caracteres, letras algarismos ou o caracter sublinha.
Exemplos:
	int a; float peso; char sexo; int idade1, idade2;
3.2.1	Palavras reservadas
	Existem certos nomes que não poderão ser usados como identificadores. São chamadas as palavras reservadas e são de uso restrito da linguagem C++. 
 
3.2.2	Tipos modificados
	Além dos tipos de dados mencionados, existem os modificadores: long, short, signed e unsigned. Tipicamente o modificador long aumenta o número de bytes usados para o registro do número. O modificador unsigned, usado somente em inteiros, permite que um bit usado para guardar o sinal do número seja usado para guardar o valor do número. 
	Tipo
	Tamanho (bytes)
	Intervalo
	unsigned char 
	1
	0 a 255 
	unsigned int 
	2
	0 a 65 535
	unsigned long int 
	4
	0 a 4 294 967 295
	long int (int) 
	4
	-2 147 483 648 a 2 147 483 647
	short int
	2
	-32768 a 32767
	long double 
	10
	3.4e-4932 a 1.1e4932
 Observação: Alguns outros tipos são possíveis em ISO C90
3.2.3 Conversão de tipo (Casting)
	Algumas vezes queremos, momentaneamente, modificar o tipo de dado representado por uma variável, isto é, queremos que o dado seja apresentado em um tipo diferente do qual a variável foi inicialmente declarada. Por exemplo: ao fazermos uma divisão entre dois inteiros, a linguagem C++ trunca a parte fracionária e podemos desejar que isto não aconteça. Este procedimento é chamado de conversão de tipo ou casting . 
Sintaxe: 
	(tipo) variável
onde tipo é o nome do tipo ao qual queremos converter o dado armazenado em variável. 
Exemplo: 
	#include <iostream>
using namespace std;
int main()
{ cout<<"\nNumero 7 DIVIDIDO por 3" ; 
 cout<<"\n\nsem conversao: "<<7/3<<"\tcom conversao: "<< float)7/3<<"\n\n";
 system("pause");
}
	
3.2.4 Variável ponteiro
Nós já sabemos que uma variável é um endereço na MP que armazena um dado. É bom deixar claro que não é um único endereço, pois, dependendo do tipo, poderemos estar alocando 1, 2, 4, 8 ou mais posições para cada variável como vimos na última tabela. 
Uma variável ponteiro armazena o endereço de outra variável. Mais adiante estudaremos este tipo de variável uma vez que se não trabalharmos bem com este tipo de variável, não conseguiremos programar bem na linguagem C++.
4. Atribuição
Consiste em atribuir um valor a uma variável. Em C++, o comando de atribuição tem a seguinte sintaxe:
	< nome_da_variável > = <conteúdo> ;
	
Exemplos:
a = 12 ; peso = 65.2; sexo ='f'; idade1 = 21; idade2 = 34;
Observação 1: Em C++, é possível declarar e inicializar uma variável: int a = 12; 
Observação 2: Em C++, é possível inicializar várias variáveis: x =t =s = 0;
Na atribuição múltipla as operações ocorrem da direita para a esquerda, isto é, inicialmente o valor 0 é atribuído a s, depois o valor de s é atribuído a t e, por último, o valor de t é atribuído a x.
4.1 Atribuição múltipla.
 A linguagem C++ permite que se atribua um valor a muitas variáveis. em uma única instrução. 
Sintaxe: 
	var_1 = [var_2 = ... ] valor;
Exemplo:
a = b = 0;
5. Entrada de dados 
	scanf
5.1 cin
	cin>>nomedavariável;
	cin>>nomedavariável1>> nomedavariável2;
  	 O objeto cin permite que o usuário digite dados através do dispositivo padrão de entrada: teclado. O operador >> é chamado de extração.
	#include <iostream>
using namespace std;
int main()
{ int idade; float altura; 
 cout<<"\nDigite idade: " ; cin>>idade;
 cout<<"\nDigite altura: " ; cin>>altura; 
 cout<<"\n\n\nIdade: "<<idade;
 cout<<"\nAltura: "<<altura<<endl; 
 system("pause");
}
	
	#include <iostream>
using namespace std;
int main()
{ char sexo; char nome[30];
 cout<<"\nDigite nome: " ; cin>>nome;
 cout<<"\nDigite sexo(m/f): " ; cin>>sexo; 
 system("pause"); 
 system("cls");
 cout<<"\nNome; "<<nome;
 cout<<"\nSexo; "<<sexo<<endl;;
 system("pause");
}
	
	
	O objeto cin quando lê um vetor de char(string) termina a leitura no primeiro espaço, deixando RENATO no buffer.
Quando um outro cin para ler o sexoé executado, o teclado não é liberado e a letra R é “apanhada” e armazenada na variável sexo.
Por estas razões, precisamos conhecer outros métodos.
5.2 cin.getline
	Este método permite a leitura de um vetor de char inclusive com espaços e não deixando nada no buffer.
Sintaxe:
	cin.getline( <nome do vetor de caracteres>, <tamanho-1> );
 
	#include <iostream>
using namespace std;
int main()
{ char sexo; char nome[30];
 cout<<"\nDigite nome: " ; cin.getline(nome,29);
 cout<<"\nDigite sexo(m/f): " ; cin>>sexo; 
 cout<<"\n\n\nNome: "<<nome;
 cout<<"\nSexo: "<<sexo<<endl;;
 system("pause");
}
	
5.3 cin.get
	Este método permite a leitura de um char.
Sintaxes:
	cin.get(<nome da variável char);
	cin.get();
	A primeira sintaxe serve para ler uma variável do tipo char, mas deixa enter no buffer enquqnto que o objeto cin sempre libera o teclado para o usuário digitar.
	#include <iostream>
using namespace std;
int main()
{ char sexo1,sexo2; 
 cout<<"\nDigite sexo(m/f) " ; 
 cin.get(sexo1);
 cout<<"\nDigite sexo(m/f): " ;
 cin.get(sexo2);
 cout<<"\n\n\nSexo: "<<sexo1;
 cout<<"\nSexo: "<<sexo2<<endl;;
 system("pause");
}
	#include <iostream>
using namespace std;
int main()
{ char sexo1,sexo2; 
 cout<<"\nDigite sexo(m/f) " ;
 cin>>sexo1;
 cout<<"\nDigite sexo(m/f): " ;
 cin>>sexo2;
 cout<<"\n\n\nSexo: "<<sexo1;
 cout<<"\nSexo: "<<sexo2<<endl;;
 system("pause");
}
	
	
	
	Não se surpreenda se econtrar alguns bugs quando usar cin, cin.get() ou cin.getline() em alguns compiladores. 
	Não gosta de usar system(“pause”); ? Veja o exemplo abaixo: 
	#include <iostream>
using namespace std;
int main()
{ char sexo1,sexo2; 
 cout<<"\nDigite sexo(m/f) " ; cin>>sexo1;
 cout<<"\nDigite sexo(m/f): " ; cin>>sexo2;
 cout<<"\n\n\nSexo: "<<sexo1;
 cout<<"\nSexo: "<<sexo2<<endl;;
 cin.get();cin.get(); 
 // o primeiro limpa o buffer e o segundo aguarda o pressionamento de uma tecla
}
	
6. Operadores Aritméticos
	
Existem cinco operadores aritméticos em C++. Cada operador aritmético está relacionado a uma operação aritmética elementar: adição, subtração, multiplicação e divisão. Existe ainda um operador (%) chamado operador de módulo cujo significado é o resto da divisão inteira. 
	
	Operador
	Operação
	+
-
*
/
%
	adição
subtração
multiplicação
divisão
módulo (resto da divisão inteira)
	
	Sintaxe: 
	operando1 operador operando2
	onde operador é um dos símbolos mostrados acima e operando é uma constante ou um identificador de variável. 
	Exemplos:
	12 + 5 -> 17
	12 * 5 -> 60
	12 / 5 -> 2 quando se divide dois inteiros, o resultado é um inteiro
	12 % 5 -> 2 resto da divisão inteira	
	Observação: Se você precisar dividir dois números inteiros e quiser a resposta em real, existe duas saídas:
Coloque um ponto em um dos operandos caso, pelo menos um, seja uma constante: 12 / 5. .
Caso os dois operandos sejam variáveis, faça: (float) a/b . 
		Não existe em C++, como existe em outras linguagens, um operador específico para a operação de potenciação (ab). Existe, porém, uma função de biblioteca (pow(...,...)) que realiza esta operação, ou você poderá criar quando aprender a usar as funções log e exp.. 
	6.1	Hierarquia das operações
	Categoria
	Operadores
	Prioridade
	parênteses
	( ) 
	interno ( externo
	função
	nome() 
	E ( D
	incremental, lógico
	++ -- ! 
	E ( D
	aritmético
	* / %
	E ( D
	aritmético
	+ -
	E ( D
	relacional
	< > <= >=
	 E ( D
	relacional
	== !=
	E ( D
	lógico
	&&
	E ( D
	lógico
	||
	E ( D
	condicional
	?:
	E ( D
	atribuição
	= += -= *= /= %= 
	E ( D
6.2 	Operadores de Atribuição Aritmética
	Muitas vezes queremos alterar o valor de uma variável realizando alguma operação aritmética com ela.
A linguagem C++ apresenta instruções otimizadas com o uso de operadores ditos operadores de atribuição aritmética. Os símbolos usado são (+=, -=, *=, /= , %=). 
Sintaxes: 
	var += exp;
var -= exp; 
var *= exp; 
var /= exp; 
var %= exp;
	var = var + exp;
var = var - exp; 
var = var * exp; 
var = var / exp; 
var = var % exp;
onde var é o identificador da variável e exp é uma expressão válida. Estas instruções são equivalentes as seguintes:
�
Exemplos: 
	Atribuição Aritmética
	Instrução Equivalente
	cont += 1; 
j -= i ; 
num *= 1 + k;
divide /= 5; 
resto %= 2; 
	cont = cont + 1;
j = j – i ;
num = num * (1 + k);
divide = divide / 5;
resto = resto % 2;
O operador de atribuição aritmética tem precedência menor que os outros operadores até aqui discutidos.
6.3 	Operadores Incrementais
	Em programação existem instruções muito comuns chamadas de incremento e decremento. Uma instrução de incremento adiciona uma unidade ao conteúdo de uma variável. Uma instrução de decremento subtrai uma unidade do conteúdo de uma variável. 
Existem, em C++, operadores específicos para realizar as operações de incremento (++) e decremento (--). Eles são genericamente chamados de operadores incrementais.
Sintaxe: 
	
	Instrução Equivalente
	++ var;
var ++ ; 
-- var ; 
var -- ; 
	var = var + 1;	
var = var + 1;
var = var – 1;
var = var – 1;
onde var é o nome da variável da qual se quer incrementar ou decrementar um unidade. 
Observe que existe duas sintaxes possíveis para os operadores: pode-se colocar o operador como prefixo ou como sufixo. Nos dois casos o valor da variável será incrementado (ou decrementado) de uma unidade. Porém se o operador for colocado como sufixo, o valor da variável será incrementado (ou decrementado) antes que a variável seja usada em alguma outra operação. Caso o operador seja colocado como sufixo, o valor da variável será incrementado (ou decrementado) depois que a variável for usada em alguma outra operação. 
	#include <iostream>
using namespace std;
int main()
{ int n,n1,n2,pre,suf; 
 cout<<"\nnumero:";
 cin>>n;
 n1=n; //para nao perder o valor de n
 n2=n; //para nao perder o valor de n
 pre=++n1;
 cout<<"\n\nprefixo= "<<pre<<"\t n= "<<n1<<endl;
 suf=n2++;
 cout<<"\n\nsufixo= "<<suf<<"\t n= "<<n2<<endl;
 cin.get();cin.get();
}
	
 
6.4 	Operadores Relacionais e Lógicos
	
	As expressões lógicas usadas nas estruturas de teste são formadas pelos operadores relacionais e lógicos. 
6.4.1	Operadores relacionais
Operadores relacionais verificam a relação de magnitude e igualdade entre dois valores. São seis os operadores relacionais em C:
	Operador
	Significado
	>
<
>=
<=
==
!=
	maior que
 menor que
maior ou igual a 
menor ou igual a 
igual a
diferente de
 Sintaxe: 
	expressão_1 operador expressão_2
onde expressão_1 e expressão_2 são duas expressões numéricas quaisquer, e operador é um dos operadores relacionais.
	Ao contrário de outras linguagens, em C++ não existem tipos lógicos, portanto o resultado de uma expressão lógica é um valor numérico: uma expressão avaliada verdadeira recebe o valor 1, uma expressão lógica avaliada falsa recebe o valor 0.
Os operadores relacionais de igualdade (== e !=) tem precedência menor que os de magnitude (>, <, >= e <=). Estes, por sua vez, tem precedência menor que os operadores aritméticos. 
�
6.4.2	Operadores lógicos
São três os operadores lógicos de C: &&, || e !. Estes operadores têm os mesmos significados dos operadores lógicos Booleanos AND, OR e NOT. 
Sintaxes: 
	expr_1 && expr_2
expr_1 || expr_2
!expr
 onde expr_1 , expr_2 e expr são expressões quaisquer. 
Observeque os operadores lógicos atuam sobre expressões de quaisquer valores. Para estes operadores todo valor numérico diferente de 0 é considerado 1.
	Operador
	Matemática
	C
	conjunção
disjunção
negação
	 e ^
 ou v 
 não |
	&& 
|| 
!
TABELA VERDADE DO OPERADOR &&
Suponha duas perguntas feitas a quatro pessoas. Se a resposta do candidato for negativa, deverá falar 0, caso contrário, falará 1.
Suponha também que só será chamado para entrevista o candidato que dominar as duas linguagens.
	 Você conhece C++?
	Você conhece PASCAL?
	SAÍDA
	0
	0
	0
	0
	1
	0
	1
	0
	0
	1
	1
	1
Neste exemplo, somente o quarto candidato seria chamado para a entrevista, pois o operador && (e), só considera a expressão como verdadeira se todas as expressões testadas forem verdadeiras.
 
TABELA VERDADE DO OPERADOR ||
Suponha duas perguntas feitas a quatro pessoas. Se a resposta do candidato for negativa, deverá falar 0, caso contrário, falará 1.
Suponha também que será chamado para entrevista o candidato que dominar pelo menos uma linguagem.
	 Você conhece C++?
	Você conhece JAVA?
	SAÍDA
	0
	0
	0
	0
	1
	1
	1
	0
	1
	1
	1
	1
Neste exemplo, somente o primeiro candidato não seria chamado para a entrevista , pois o operador || (ou), considera a expressão como verdadeira se, pelo menos uma expressão testada for verdadeira.
 Observação:O Operador && tem precedência sobre o operador ||. Estes dois têm precedência menor que os operadores relacionais. 
TABELA VERDADE DO OPERADOR !
Suponha uma pergunta feita a duas pessoas. Se a resposta do candidato for negativa, deverá falar 0, caso contrário, falará 1.
	Você Não conhece C++?
	SAÍDA
	1
	0
	0
	1
Observação:
O operador ! tem a mesma precedência que os operadores incrementais. 
7. Estruturas de seleção - if / switch
Nossos programas até agora seguiram um mesmo padrão: entrava-se com dados, estes eram processados e alguma informação era mostrada na tela.
Agindo desta forma, o computador mais parecia uma máquina de calcular. O aprendizado de novos conceitos como a da estrutura de seleção nos dará uma visão maior da complexidade de tarefas que ele poderá executar. 
7.1	Estrutura de decisão - if...else
	
A estrutura if...else é uma estrutura de controle do C++ muito fácil de ser usada Após o teste, o fluxo poderá seguir dois caminhos, isto é, se o teste resultar em uma verdade, será executado o comando ou bloco de comandos que se encontra após o fecha parênteses do teste, caso contrário, se existir, será executado o comando ou bloco de comandos que se encontra após o comando else. 
�
7.1.1 	Estrutura de decisão com um bloco
Sintaxe: 
	 if(condição)
 {
 bloco
 }
onde:	condição é uma expressão lógica ou relacional.
	bloco é um conjunto de instruções, separadas por ponto-e-vírgula. 
 { e } só serão obrigatórias se tiver mais de uma ação para ser executada.
Se a condição for verdadeira, o bloco é executado. Caso contrário, o bloco não é executado.
7.1.2 	Estrutura de decisão com dois blocos
Sintaxe:
	 if(condição)
 {
 bloco
 }
 else
 {
 bloco
 }
 onde:	condição é uma expressão lógica ou relacional.
 bloco 1 e bloco 2 são conjuntos de instruções.
Se a condição for verdadeira o bloco 1 é executado. Caso contrário, o bloco 2 é executado.
7.1.3	Decisão de múltiplos blocos (if...else if...)
Muitas vezes, nossos programas poderão envolver várias condições excludentes. Programas que envolvem faixas salariais ou faixas de idades são exemplos clássicos do uso da instrução if ... else if ... .
Sintaxe: Decisão de múltiplos blocos:
	if(condição 1)
{
 bloco 1
}
...
else if(condição N)
{
 bloco N
}
else
{
 bloco P
 }
 onde:condição 1, condição 2, ... são expressões lógicas ou relacionais.
 bloco 1 , bloco 2,... são conjuntos de instruções.
Se a condição 1 for verdadeira o bloco 1 é executado. Caso contrario, as condições serão avaliadas, sucessivamente até que seja verdadeira ou chegue ao último else, onde o bloco P seria executado. Observe que apenas um dos blocos é executado.
7.2 	Estrutura switch...case
A estrutura switch...case, também conhecida como alternativa de múltiplas escolhas, é uma estrutura que simplifica nossos programas no uso de decisão de múltiplos blocos quando a expressão de controle( a condição) envolver tipos int ou char(de um caracter que também é considerada inteira). O resultado desta expressão é comparado ao valor de cada um dos rótulos, e os comandos são executadas a partir desde rótulo. 
Sintaxe:
	switch(expressão)
{
 case rótulo_1:
 bloco1;
 break;
 case rótulo_2:
 bloco2 
 break;
 ...
 case rótulo_n:
 bloco n
 break;
<default:
 bloco d>
 }
 onde: expressão é uma expressão inteira ou char de um caracter.
 rótulo_1,rótulo_2,...rótulo_n e rótulo_d são constantes inteiras ou char
 de um caracter.
	 bloco 1, bloco 2, ..., bloco n e bloco d são conjuntos de instruções.
Execução:
 A expressão é avaliada e o fluxo desviado para o conjunto cujo rótulo é igual ao resultado da expressão. O bloco abaixo do rótulo é executado. Se o valor da expressão não for igual a nenhum rótulo, o bloco do defualt é executado. Você não é obrigado a colocar o rótulo do default e por esta razão ele se encontra entre os sinais de menor e maior. 
Por que usar break?
 Normalmente, em outras linguagens de programação, após a avaliação da expressão e a execução do bloco correspondente, o fluxo do programa passa para a pro'xima instrução, ignorando todos os outros rótulos. Na linguagem C++ isto não acontece e poderá trazer sérias conseqüências em seus programas. O uso do break forçará a saída do comando switch e a execução do próximo comando. 
Existirá alguma situação que não será necessário usar break?
Sim. Lembre-se do exercício dos triênios. 
8. Estruturas de repetição 
Três são as estruturas de repetição disponíveis na linguagem C++: for, while e do ... while. Em todas as estruturas estará presente pelo menos uma expressão para controlar a repetição.
8.1 Estrutura de repetição: for
A estrutura do for é a mais simples estrutura de repetição e é usada para repetir um ou vários comandos tantas vezes quanto desejarmos. É a estrutura mais indicada quando o número de repetições for conhecido embora, as outras duas estruturas também possam ser usadas. O controle do número de repetições, na maioria das vezes, é feito por uma variável chamada de variável contadora.
A estrutura do for na linguagem C++ é um pouco diferente das demais linguagens, pois a condição pode não se prender somente a uma variável contadora.
	
�
 Sintaxes:
	for (inicialização;condição;incremento) declaração;
	for (inicialização ;condição ;incremento)
{
 bloco de comandos
}
onde:	inicialização é uma expressão de inicialização da variável contadora e só é 
 executada uma vez..
condição é uma expressão lógica de controle de repetição.
	incremento é uma expressão de incremento da variável contadora.
bloco de comandos é um conjunto de instruções a ser executado.
 
8.2 Estrutura de repetição: while
A estrutura while é uma estrutura "poderosa" da programação. Muitos programadores fazem uso somente desta estrutura. Ela testa primeiro a condição e poderá nem executar o bloco caso a condição seja falsa. Logo, a estrutura do while repete enquanto a condição for verdadeira.
Ë importante que a variável presente na condição tenha seu valor alterado dentro da repetição, pois, caso contrário, entraráem loop.
Normalmente, todos os autores mostram simplesmente a sintaxe da estrutura, mas esquecem de informar como na prática ela deverá ser escrita.
Abaixo, apresentarei a sintaxe geral e a sintaxe usada na prática:
	Sintaxe 
	
	Sintaxe na prática
	while(condição)
{
 bloco de comandos
}
	
	atribuição ou leitura da variável presente na condição
while(condição)
{
 bloco de comandos
 atribuição ou leitura da variável presente na condição
}
onde:	condição é uma expressão lógica ou numérica.
bloco de comandos é um conjunto de instruções.
�
8.3	Estrutura de repetição: do...while
Esta estrutura é parecida com while. Sua diferença é que o bloco é executado pelo menos uma vez, pois testa ao final. Esta estrutura repete enquanto a condição for verdadeira.
Sintaxe:
	do
{
 bloco de comandos
}
while(condição);
onde:	condição é uma expressão lógica ou numérica.
bloco de comandos é um conjunto de instruções.
8.4 Comandos associados
As estruturas de repetição podem, mas não devem, sofrer desvios e interrupções em sua seqüência normal.
8.4.1 break
Assim como o foi usado para interromper o comando switch, poderá ser usado com qualquer um dos três comandos de repetição.
9 Estruturas
As estruturas em C++ podem ser homogêneas e heterogêneas. Inicialmente, vamos abordar as homogêneas, pois são mais familiares uma vez que conhecemos seu conceito da matemática quando estudamos matrizes.
9.1 Estruturas homogêneas
Em C++, o uso de matrizes é de fundamental importância e existe uma relacionamento estreito entre matrizes e ponteiros que estudaremos mais adiante.
A grande novidade que estudaremos será o uso de matrizes com estruturas heterogêneas.
As matrizes são tabelas na MP e podem ter uma ou mais dimensão. Quando tem somente uma dimensão, também chamamos de vetor.
Na linguagem C++, como já vimos, uma variável char ,que precisa armazenar mais de um caracter, faz uso de matriz, pois podemos acessar cada um de seus caracteres em separado, usando o nome da variável e sua posição entre colchetes.
	
Por que será que na linguagem C++ a posição do primeiro caracter é 0 ?
O endereço guardado é o do primeiro caracter que chamamos de base, logo qualquer outro caracter será acessado pelo endereço base mais sua posição. Se o endereço é o da primeira posição, somente o 0 poderia ser acrescido para permanecer na mesma posição.
Se declararmos pal com tamanho 5, lembre-se de que só podemos usar 4 posições, pois uma reservada para o finalizador \0 que indica o fim do vetor.
É bom você já ir se acostumando com este conceito de apontamento, pois para se programar bem em C, precisaremos dominar o conceito de ponteiros.
9.1.1 Declarando uma matriz:
 tipo nome do conjunto [ ... ] [ ...] ... ; 
Exemplos:
/* declara uma matriz unidimensional de 5 elementos inteiros */
 int num[ 5 ]; 
/* declara uma matriz bidimensional com 100 linhas e 4 colunas do tipo float */
 float notas [ 100 ][ 4 ]; 
/* declara uma matriz bidimensional com 100 linhas e 30 colunas do tipo char */
 char nomes [ 100 ][ 30 ]; 
 Toda matriz para guardar nomes, na linguagem C++, é bidimensional, pois o primeiro índice indica a quantidade de nomes e o segundo o número de caracteres –1 que serão armazenados em cada nome.
9.1.2 Armazenamento
O armazenamento na matriz poderá ser feito através de um comando de leitura ou de atribuição.
�
9.1.2.1 Leitura
	/*um dimensao */
 ...
 for(a=0;a<tamanho;a++)
 { 
 cout<<"\n…: "<<a+1; 
 cin>>nomeVetor[a];
 }
 ...
	/*duas dimensoes */
 ...
 for(L=0;L<tamanhoLinha;L++)
 for(c=0;c<tamanhoColuna;c++)
 { 
 cout<<”\nNumero da linha “<<L+1<<” coluna "<<c+1<<”: “;
 cin>>nomeMatriz[L][c];
 }
 ...
 
9.1.2.2 Atribuição
Podemos também inicializar as matrizes através de atribuições:
Exemplos:
int vet[4]={6,7,8,9};
float nota[3]={8.5,6.2,9.8};
char nome[12]="João Renato";
char nomes[4][30]={"JOÃO", "MARIA", "PEDRO","FILIPE"};
int mat[][3]={1,2,3,4,5,6,7,8,9};
/* na declaração/atribuição acima, é assumido 3 como número de linhas */
	#include <iostream>
using namespace std;
int main()
{int L,c; 
 int ias_meses[][12]={31,28,31,30,31,30,31,31,30,31,30,31,31,29,31,30,
 31,30,31,31,30,31,30,31};
 cout<<"\n\nPara anos nao bissextos, primeira linha e para bissextos, segunda linha\n\n"; 
 for(L=0;L<2;L++)
 { for(c=0;c<12;c++)
 cout<<dias_meses[L][c]<<" ";
 cout<<"\n\n"; 
 }
 system("pause"); 
}
	
9.1.3 Saída 
	/*um dimensao – MATRIZ COLUNA*/
 ...
 system(“cls”);
 cout<<”\nTitulo\n”;
 for(a=0;a<tamanho;a++)
 cout<<"\n…: "<<nomeVetor; 
 ...
	/*um dimensao – MATRIZ LINHA*/
 ...
 system(“cls”);
 cout<<”\nTitulo\n”;
 for(a=0;a<tamanho;a++)
 cout<<nomeVetor <<"\t"; 
 ...
	/*duas dimensoes TODOS OS ELEMENTOS*/
 ...
 system(“cls”);
 cout<<”\nTitulo\n”;
 for(L=0;L<tamanhoLinha;L++)
 { for(c=0;c<tamanhoColuna;c++)
 cout<<nomeMatriz[L][c]<<"\t";
 cout<<”\n“;
 }
 ...
	/*duas dimensoes ALGUNS ELEMENTOS*/
 ...
 system(“cls”);
 cout<<”\nTitulo\n”;
 for(L=0;L<tamanhoLinha;L++)
 { for(c=0;c<tamanhoColuna;c++)
 if( condição ) 
 cout<<nomeMatriz[L][c]<<"\t";
 else
 cout<<"\t"; 
 cout<<”\n“;
 }
 ...
	Condição
(L==c)
só diagonal Principal
(L!=c)
todos menos a diagonal Principal
(L<c) elementos acima da diagonal principal
(L>c) elementos abaixo da diagonal principal
9.1.4 Matrizes somaLinha e somaColuna
 9.1.4.1 Matriz somaLinha
 
 É uma matriz unidimensional(vetor ou matriz coluna) que terá tantas linhas quantas forem as linhas da matriz original e cada elemento será a soma de todos os elementos da linha correspondente na matriz original. Em outras palavras, cada elemento soma de todos os elementos das colunas de uma linha.
9.1.4.1.1 Inicializando a matriz somaLinha
 
 Como é uma matriz de acumuladores precisa ser inicializada.
	for(L=0; L<tamanhoLinha; L++) 
 somaLinha[L]=0;
9.1.4.1.2 Gerando a matriz somaLinha
 
	for(L=0;L< tamanhoLinha;L++)
 for(C=0;C< tamanhoColuna;C++)
 somaLinha[L]+=mat[L][C];
9.1.4.1.3 Imprimindo a matriz somaLinha sozinha
 
	for(L=0;L< tamanhoLinha;L++)
 cout<<somaLinha[L]<<”\n”;
cout<<endl;
9.1.4.1.4 Imprimindo a matriz somaLinha com a matriz original
 
	system("cls");
cout<<"\nMatriz Original com matriz SomaLinha\n\n";
for(L=0;L< tamanhoLinha;L++)
{ for(C=0;C< tamanhoColuna;C++)
 cout<<matOriginal[L][c]<<"\t";
 cout<<somaLinha[x]<<"\n";
} 
9.1.4.2 Matriz somaColuna
 
 É uma matriz unidimensional(vetor ou matriz linha) que terá tantas colunas quantas forem as colunas da matriz original e cada elemento será a soma de todos os elementos da coluna correspondente na matriz original. Em outras palavras, cada elemento é a soma de todos os elementos das linhas de uma coluna.
9.1.4.2.1 Inicializando a matriz somaColuna
 
 Como é uma matriz de acumuladores precisa ser inicializada.
	for(c=0; c<tamanhoColuna; c++) 
 somaLinha[c]=0;
9.1.4.2.2 Gerando a matriz somaColuna
 
	for(L=0;L< tamanhoLinha;L++)
 for(c=0;c< tamanhoColuna;c++)
 somaColuna[c]+=mat[L][c];
9.1.4.2.3 Imprimindo a matriz somaColuna sozinha
 
	for(c=0;L< tamanhoColuna;c++)
 cout<<somaColuna[c]<<”\t”;
cout<<endl;
9.1.4.2.4 Imprimindo a matriz somaColuna com a matriz original
 
	system("cls");
cout<<"\nMatriz Original com matriz SomaColuna\n\n";
for(L=0;L< tamanhoLinha;L++)
{ for(c=0;c< tamanhoColuna;c++)cout<<matOriginal[L][c]<<"\t";
 cout<<"\n";
}
for(c=0;c< tamanhoColuna;c++)
 cout<<somaColuna[c]<<"\t"; 
cout<<"\n"; 
9.1.5 Operações
Em relação às matrizes numéricas, podemos realizar todas as operações que já conhecemos com matrizes: produto escalar, soma, subtração, multiplicação por escalar, multiplicação de matrizes, cálculo do determinante, etc.
 9.1.6 Ordenação 
Vários são os métodos de ordenação. Alguns são mais eficientes e mais complicados e outros menos eficientes para um grande conjunto de dados, porém mais simples.
Para que possamos ordenar nomes, precisaremos conhecer duas funções que fazem parte da biblioteca string.h:
Função strcmp
Esta função tem dois argumentos do tipo vetor de char(ou cadeia de caracteres).
Os argumentos são comparados e é devolvido um dos resultados:
… strcmp(arg1,arg2)…
0 – se os dois argumentos forem iguais.
número > 0 - se o primeiro argumento vier na ordem alfabética depois do segundo.
número < 0 - se o primeiro argumento vier na ordem alfabética antes do segundo.
Observação: Você deve estar estranhando a necessidade desta função, mas na linguagem C++, como já falamos a variável vetor de char é um endereço, e não tem sentido comparamos endereços. É, portanto, expressamente proibido usar operadores relacionais para comparar este tipo de variável.
Função strcpy
Esta função tem dois argumentos: o primeiro é o destino e o segundo, a origem. Copia a origem no destino.
strcpy(arg1,arg2);
Observação: É, portanto, expressamente proibido usar comando de atribuição este tipo de variável.
1: Ordenação por Inserção
Ordena a matriz somente quando realmente for necessário.
	
for( L = 1 ; L < tamanho; L++)
{ tmp= nomeVetor[L];
 for (c = L; c >0 && tmp < nomeVetor[c-1]; c--)
 nomeVetor[c] = nomeVetor[c-1] ;
 nomeVetor[c] = tmp ;
}
2: Ordenação por Seleção 
Localiza qual elemento deve ficar na posição 0, na posição 1, etc.
	 
for(L=0;L<tamanho -1;L++)
{ tmp=L;
 for(c=L+1;c<tamanho;c++)	
 if(vet[tmp]> vet[c])	 
tmp=c; 
 aux= vet[tmp]; vet[tmp]= vet[L]; vet[L]=aux;
}
3: Ordenação Bubble Sort
 Começando da base para o topo. Começando do topo para base. 
	for( L = 0 ; L < tamanho -1; L++)
for (c = tamanho -1; c > L; c--)
 if(nomeVetor[c-1]> nomeVetor[c])
 {aux = nomeVetor[c];
 nomeVetor[c] = nomeVetor[c-1];
 nomeVetor[c-1] = aux; 
 } 
	for( L = 0 ; L < tamanho -1; L++)
 for (c = L+1; c < tamanho; c++)
 if(nomeVetor [L]> nomeVetor [c])
 {aux = nomeVetor[L];
 nomeVetor[L] = nomeVetor[c];
 nomeVetor[c] = aux; 
 }
	Comparando os três métodos
	
	Inserção
	Seleção
	Bubble Sort
	Duas vezes mais comparações e o mesmo número de movimentos.
	Mesmo núnero de comparações e tamanho vezes mais movimentos.
Métodos de ordenação mais eficientes
4: Ordenação Merge Sort
 Une metades de vetores em um vetor ordenado. 
	tam = 1; //intercala subvetores de tamanho 1
while (tam < tamanho )
{
 a1 = k = 0;
 while ((a1 + tam) < tamanho )
 {
a2 = a1 + tam;
u1 = a2 - 1;
u2 = (a2+tam-1 < tamanho) ? a2+tam-1 : tamanho-1;
for(i = a1, j = a2; i <= u1 && j <= u2; k++)
 if (nomeVetor[i] <= nomeVetor[j]) aux[k] = nomeVetor[i++];
 else aux[k] = nomeVetor[j++];
for( ; i <= u1; k++) aux[k] = nomeVetor[i++];
 for( ; j <= u2; k++) aux[k] = nomeVetor[j++];
 a1 = u2+1;
 }
 //copia o restante de x em aux
for(i = a1; k < tamanho; i++) aux[k++] = nomeVetor[i];
 //copia aux em x
for(i = 0; i < tamanho; i++) nomeVetor[i] = aux[i];
 tam *= 2;
}
5: Ordenação Quick Sort
 Divide o vetor em duas partes: uma contem valores menores ou iguais a uma chave e a outra, valores maiores.
	void particiona(int x[], int inicio, int fim, int *pj)
{
 int a, temp, i, f;
 a = x[inicio];
 f = fim;
 i = inicio;
 while ( i < f )
 { 
 while ( x[i] <= a && i < fim ) i++;
 while ( x[f] > a ) f--;
 if ( i < f )
 { temp = x[i];
 x[i] = x[f];
 x[f] = temp;
 }
 }
 x[inicio] = x[f];
 x[f] = a;
 *pj = f;
}
void quicksort(int x[], int inicio, int fim)
{
 int j;
 if (inicio >= fim ) return;
 particiona(x, inicio,fim,&j);
 quicksort(x, inicio,j-1);
 quicksort(x,j+1, fim);
}
9.1.4 Pesquisa
9.1.4.1 Seqüencial
Este método é o mais simples, pois começa no primeiro elemento só para quando encontra ou chega ao final.
	cout<<"\nQual ... a ser procurado(a)? ";
cin>>nomeProcura;
achou=0;
for(L=0;L<5 && achou==0;L++)
{ if(n_mat==mat[L])
 {
 achou=1; 
 pos=L;
 } 
}
if(achou==1)
 cout<<"\n... achado(a) na posicao: "<<pos+1<<endl;
else
 cout<<"\n... nao achado(a)\n";
 
9.1.4.2 Binária
Este método será mais eficiente se o conjunto estiver ordenado.
Baseia-se em reduzir o espaço a ser pesquisado.
1. Inicialmente, aponta-se para o centro da tabela. Como se faz isto?
 Suponha um vetor de 8 elementos:
 centro = (0 + 7) /2; /* valor 3 */ 
2. Depois, perguntamos se o elemento pesquisado é igual ao que está sendo apontado. Se não for, continua-se com a pesquisa.
3. Se continuarmos com a pesquisa, verificamos se o elemento pesquisado é maior(menor) do o que está sendo apontado.
4. Se for, calculamos o novo centro:
 
 centro = (posição do apontador +1 +7) /2; 
 Se não for:
 centro = (0 + posição do apontador -1) /2; 
5. E assim, sucessivamente até acharmos, ou não.
	#include <iostream>
#define N 5
using namespace std;
int main()
{ int L,c,inicio,fim,meio,vet[N],aux,procura;
 for(L=0;L<N;L++)
 { cout<<"\nDigite "<<L+1<<"o elemento: ";
 cin>>vet[L];
 }
 /*ORDENA*/
 for(L=0;L<N-1;L++)
 for(c=L;c<N ;c++)
 if(vet[L]>vet[c])
 {aux=vet[L];
 vet[L]=vet[c];
 vet[c]=aux;
 } 
 cout<<"\n\n\nVETOR ORDENADO\n\n";
 for(L=0;L<N;L++)
 cout<<"\n"<<vet[L];
 /*PESQUISA BINARIA*/
 cout<<"\nDigite ... a ser procurado(a) ou 0 para terminar: ";
 cin>>procura;
 while(procura!=0) 
 { inicio=0;fim=N-1;
 do 
 { meio=(inicio+fim)/2; 
 if(vet[meio]<procura)
 inicio=meio+1;
 else 
 fim=meio-1; 
 }
 while((inicio<=fim) && (vet[meio]!=procura));
 if(vet[meio]==procura)
 cout<<"\n... encontrado(a) na posicao: "<<meio+1<<endl;
 else 
 cout<<"\n... nao encontrado\n";
 cout<<"\nDigite ... a ser procurado(a) ou 0 para terminar: ";
 cin>>procura; 
 }
 
 system("pause");
} 
 
 
9.2 Estrutura heterogênea (struct)
Uma estrutura(struct) é, na verdade, um conjunto de variáveis que podem ter tipos diferentes.
Suponha que você deseje armazenar nome, e duas notas de um aluno. Se você usar variáveis simples, precisará declarar três variáveis simples e, para que fiquem claras que existe uma relação entre elas, precisamos nomeá-las de uma forma que nos faça entender que elas se relacionam. Usando struct fica mais claro o relacionamento entre elas.
Suponha também que você deseje armazenar nome, e duas notas de três alunos. Se você usar matrizes, precisará declarar uma matriz para guardar os nomes e uma matriz bidimensional para guardar as notas(pode ser também duas matrizes unidmensionais). Se você usar uma matriz de struct, será necessária somente uma matriz.
As variáveis de um struct são chamadas de campos ou membros.
Normalmente, costumamos associar um nome à estrutura para que possamos definir novos tipos.
 9.2.1 Declarando um struct 
 sintaxe 1
	struct{ tipo da variável 1 nome da variável 1;
 tipo da variável 2 nome da variável 2;
 tipo da variável n nome da variável n;
}nome do struct1, nome do struct2;
 
 sintaxe 2
	struct nome da estrutura
{ tipo da variável 1 nome da variável 1;
 tipo da variável 2 nome da variável 2;
 tipo da variável n nome da variável n;
};
struct nome da estrutura nome do struct1, nome do struct2;
/* ao fazermos esta declaração, dizemos que os dois structs são do tipo nome da estrutura*/
9.2.2 fazendo referência a um membro um struct
	nome do struct. nome do membro -> struct simples
Exemplos:
cin>>dados.idade;
cout<<”\n”<<dados.idade;
	nome do struct[posição]. nome do membro -> matriz de struct
Exemplos:
cin>>cad[3].idade;
cout<<”\n”<<cad[3].idade;
Exemplo 1:
Guardar nome e duas notas de um aluno e imprimir a média e o nome.
	#include <iostream>
using namespace std;
int main()
{
 struct 
 { char nome[30];
 float nota1,nota2;
 }aluno;
 cout<<"\nNome : "; cin.getline(aluno.nome,29);
 cout<<"\nNota 1: "; cin>>aluno.nota1;
 cout<<"\nNota 2: "; cin>>aluno.nota2;
 cout<<"\nMedia: "<<(aluno.nota1+aluno.nota2)/2;
 cout<<"\t"<<aluno.nome<<"\n";
 system("pause");
}
	
Exemplo 2:
Guardar nome e duas notas de três alunos e imprimir a média e o nome.
	#include <iostream>
using namespace std;
int main()
{ int a;
 struct Cadastro
 { char nome[30];
 float nota1,nota2;
 }aluno[3];
 for(a=0;a<3;a++)
 { cout<<"\nNome : ";cin.getline(aluno[a].nome,29);
 cout<<"\nNota 1: "; cin>>aluno[a].nota1;
 cout<<"\nNota 2: "; cin>>aluno[a].nota2;
 cin.get();
 }
 system("cls");
 cout<<"\n\nMedia\tNome\n\n";
 for(a=0;a<3;a++)
 { cout<<"\n"<<(aluno[a].nota1+aluno[a].nota2)/2<<"\t";
 cout<<aluno[a].nome<<"\n";
 }
 system("pause");
 }
	
Observação: Nos exemplos abaixo, você verá uma das maiores vantagens de se usar uma matriz de struct, pois quando precisarmos ordenar, não teremos que fazer muitos trechos de troca. A grande vantagem é que podemos trocar de lugar todo o struct. Observe que foi criada uma estrutura de nome aux para poder fazer a troca.
Exemplo 3: Faça um programa usando matriz de estruturas para armazenar matricula, três nota e a média de 5 alunos. Calcule a média(as duas maiores notas). Ordene pela matrícula e liste.
	#include <iostream>
using namespace std;
int main()
{int op,L,c,x;
 struct reg
 {int mat;
 float av1,av2,av3,m;
 }aluno[5],aux;
 for(x=0;x<5;x++) 
 {cout<<"\nMatricula: "; cin>>aluno[x].mat; 
 cout<<"\nAV1: "; cin>>aluno[x].av1;
 cout<<"\nAV2: "; cin>>aluno[x].av2;
 cout<<"\nAV3: "; cin>>aluno[x].av3;
 }
 //Calcula media
 for(x=0;x<5;x++) 
 { if(aluno[x].av1< aluno[x].av2 && aluno[x].av1< aluno[x].av3)
 aluno[x].m=(aluno[x].av2+ aluno[x].av3)/2; 
 else if(aluno[x].av2< aluno[x].av3)
 aluno[x].m=(aluno[x].av1+ aluno[x].av3)/2; 
 else
 aluno[x].m=(aluno[x].av1+ aluno[x].av2)/2;
 } 
 // Ordena pela matricula
 for(L=0;L<4;L++)
 for(c=L+1;c<5;c++)
 if(aluno[L].mat>aluno[c].mat)
 {aux=aluno[L];aluno[L]= aluno[c]; aluno[c]=aux;}
 
 system("cls");
 cout<<"\nMat\tAV1\tAV2\tAV3\tMedia\n";
 for(x=0;x<5;x++)
 cout<<"\n"<<aluno[x].mat<<"\t"<< aluno[x].av1<<"\t"<< aluno[x].av2<<"\t"<< aluno[x].av3<<"\t"<< aluno[x].m;
 cout<<"\n\n";
 system("pause");
} 
	
9.2.3 Declarando ou definindo
A principal diferença é que quando se declara, não se aloca espaço na MP e quando se define, sim. 
9.2.4 Embutindo a definição na declaração
Veja exemplo abaixo:
	struct Notas
{float n1,n2,media;}
struct 
{ char nome[3];
 struct notas notasAluno;
}Auno;
Observação: No primeiro, estamos associando uma etiqueta(nome) ao struct: Notas. Estamos definindo um novo tipo de dado.
No segundo, estamos declarando um struct de nome Aluno que tem embutindo uma definição na declaração.
Quando precisarmos nos referenciar à variável n1, por exemplo:
	 .... Aluno.notasAluno.n1
10 Funções
 
 10.1 Conceito
Função é um trecho de programa com atribuições específicas, simplificando o entendimento do programa, proporcionando ao programa menores chances de erro e de complexidade. 
A linguagem C++ é formada de várias funções.
10.2 Vantagens
As funções através da passagem de parâmetros e através do seu nome permitem que sejam retornados valores à rotina chamadora e desta forma, esses valores poderão ser impressos, atribuídos a uma variável ou podem servir em operações aritméticas entre outras. 
 Os principais objetivos de uma função são:	
Dividir e estruturar um algoritmo em partes logicamente coerentes;
Facilidade em testar os trechos em separados;
O programador poderá criar sua própria biblioteca de funções, tornando sua programação mais eficiente uma vez que poderá fazer uso de funções por ele escritas em vários outros programas com a vantagem de já terem sido testadas;
Maior aumentar a legibilidade de um programa;
Evitar que uma certa seqüência de comandos necessária em vários locais de um programa tenha que ser escrita repetidamente nestes locais, diminuindo também, o código fonte, ;
Tudo isto justifica o uso de funções em nossos programas
10.3. Funções Pré-definidas
O conjunto de funções pré-definidas é muito extenso e aqui vamos estudar algumas funções das bibliotecas: cmath, cstring.
Quando estudamos uma função, temos vários parâmetros a observar. Veja, por exemplo a seguinte função pré-definida da biblioteca cmath:
double sqrt(double x)
Este é o protótipo da função, isto é, informações sobre o tipo de retorno da função e tipos dos parâmetros.
Esta função retorna um valor double, seu nome é sqrt e o tipo da variável que recebe o valor passado é double.
Quando você criar suas funções, elas precisarão ter uma declaração semelhante a esta.
As funções poderão ser localizadas antes da função principal(main) ou depois. Se uma função for declarada antes, o protótipo da função não precisará ser declarado na função main, mas se declarada depois, o protótipo precisará ser declarado na função main. 
Declaração de uma função:
	tipo
	identificador
	(lista de parâmetros)
	int, float, char, void
	Nome da função 
	( tipo1 nome1, tipo2 nome2 )
Exemplos:
int quadrado(int l)
char maiuscula(char n[] )
10.3.1 Funções Numéricas 
Biblioteca: cmath
	#include <iostream>
#include <cmath>
#define PI 3.14159265
using namespace std;
int main()
{ float f;
 cout<<"\nFUNCOES NUMERICAS\n";
 cout<<"\nDigite numero real: ";
 cin>>f;
 cout<<"\nNumero: "<<f;
 cout<<"\nABSOLUTO: "<<fabs(f);
 cout<<"\nCEIL: "<<ceil(f);
 cout<<"\nFLOOR: "<<floor(f);
 cout<<"\nTRUNC: "<<trunc(f);
 cout<<"\nROUND: "<<lround(f);
 cout<<"\nFMOD: "<<fmod(f,3);
 cout<<"\nSQRT: "<<sqrt(f+0.5);
 cout<<"\nSeno de 30: "<<sin(30*PI/180);
 cout<<"\nCo-seno de 30: "<<cos(30*PI/180);
 cout<<"\nTangente de 30: "<<tan(30*PI/180);
 cout<<"\nPotencia de 2 elevado a 3: "<<pow(2.0,3);
 cout<<"\nLogaritmo de 8 na base neperiana: "<<log(8.0);
 cout<<"\nLogaritmo de 8 na base 10: "<<log10(8.0);
 cout<<"\nLogaritmo 8 na base 2: "<<log(8.0)/log(2.0);
 cout<<"\nRaiz cubica de 8: "<< pow(8,1.0/3);
 cout<<"\n\n";
 system("pause");
}
	
10.3.2 Funções Strings 
Biblioteca: cstring/cctype
	#include <iostream>
#include <cstring>
#include <cctype>
using namespace std;
int main()
{char c,s1[40],s2[30];
 cout<<"\nBIBLIOTECA cctype\n";
 cout<<"\nLetra: ";
 cin>>c;cin.get();
 c=toupper(c);
 cout<<"Convertida para maiuscula: "<<c;
 c=tolower(c);
 cout<<"\nConvertidapara minuscula: "<<c;
 cout<<"\n\nBIBLIOTECA cstring\n";
 cout<<"\nDigite palavra: "; cin.getline(s1,29); 
 strcat(s1,"FIM");
 cout<<"\nConcatenacao com FIM: "<<s1;
 cout<<"\nDigite palavra: "; cin.getline(s2,29); 
 strcpy(s1,s2);
 cout<<"\nApos copia de toda palavra2: "<<s1;
 cout<<"\nTamanho de s2: "<<strlen(s2);
 cout<<"\n\nComparando strings\n";
 cout<<"Digite PAZ: "; cin.getline(s1,29);
 cout<<"Digite PAZ: "; cin.getline(s2,29);
 if(strcmp(s1,s2)==0)
 cout<<"\nIGUAIS";
 else
 cout<<"\nDiferentes";
 cout<<"\nDigite PAZ: "; cin.getline(s1,29);
 cout<<"Digite AMOR: "; cin.getline(s2,29);
 if(strcmp(s1,s2)!=0)
 cout<<"\nDIFERENTES";
 else
 cout<<"\nIguais";
 cout<<"\n";system("pause");
}
	
10.4. Diretiva #define
Define um identificador e um conteúdo que irá ser substituído toda vez que o identificador aparecer em um programa.
Esta diretiva pode ser associada a uma string ou a uma macro semelhante a uma função.
Se o tamanho da macro for pequena, substitui com vantagens o uso de funções.
Exemplo 1:
	#include <iostream>
#define quadrado(x) ((x)*(x))
#define pi (3.14159265)
#define NP (2.71828182846)
#define conv(x) ((x)*(pi)/(180))
...
Exemplo 2:
	#include <iostream>
#define AREA(b,h) (b*h)
…
Exemplo 3:
	#include <iostream>
#define HIPO(c1,c2) (sqrt(c1*c1+c2*c2))
…
10.5 Chamada da função
	
Não devemos ficar preocupados como isso irá acontecer, pois já fizemos uso de vários funções internas(funções do tradutor) e, da mesma forma, chamaremos as funções feitas por nós.
Quando uma função é chamada, o fluxo de controle é desviado para a função, no momento em que ela é ativada no algoritmo principal. Ao terminar a execução dos comandos da função, o fluxo de controle retorna ao comando seguinte àquele onde ela foi ativada, exatamente como na figura abaixo:
	main()
	
	funcao1( ...)
{ ...
 retorna(...);
}
	{...
	
	
	...
	
	
	< chamada da função 1 >
	
	...
	...
	}
	main()
	
	funcao1( ...)
{ ...
 retorna(...);
}
	{...
	
	
	...
	
	
	< chamada da função 1 >
	
	...
	...
	}
10.6 Estrutura de uma função
Uma função é um bloco contendo início e fim, sendo identificada por um nome , pelo qual será referenciada em qualquer parte e em qualquer momento do programa. A função serve para executar tarefas menores como ler, calcular, determinar o maior/menor valor entre uma lista de valores, ordenar, converter para maiúsculas, entre outras.
Após executar estas tarefas menores, a função retorna, ou não, um determinado valor para a função chamadora.
Quando a função não retornar nada(nulo) usaremos o tipo void, pois é sugerido pelo comitê de padronização ANSI. 
Dentro da função, podem ser declaradas variáveis que chamamos de variáveis locais, pois só são visíveis dentro da função.
 Sintaxe da função:
	<tipo de função> nome_da_função (declarações dos parâmetros) 
	{
	 ( declaração das variáveis locais(
	
	comandos que formam o corpo da funcao 
	
	 return(( valor () ; /* ou return; ou nada */
	}
	tipo de função 
	: 
	tipo de dado que a função dará retorno. Pode ser int, float, char ou void
	nome da função 
	:
	segue as mesmas regras de declaração de variáveis 
	parâmetros 
	: 
	nomes das variáveis, seguem as mesmas regras de declaração de variáveis
	declarações dos parâmetros
	:
	declarações de variáveis da função(tipo e nome)
	{
	:
	início da função 
	variáveis locais 
	:
	declarações de variáveis que serão utilizadas dentro da função( tipo e nome)
	corpo da função 
	:
	seqüência de comandos 
	return( .. ) 
	:
	o que vai ser retornado para o algoritmo ou não existe
	} 
	:
	fim da função
10.7. Localização das funções
Podem ser colocadas antes ou depois da main. Se for depois da main, os protótipos precisam ser colocados na função principal(main).
	main()
{ protótipo da funcao1; protótipo da funcao2; protótipo da funcao3;
...
}
	funcao1(...)
{...
}
	funcao2(...)
{...
}
	funcao3(...)
{...
}
10.8. Dividindo o programa em funções
Nós podemos modularizar nossos programas para que possamos deixá-lo mais claro. Se as funções manipulam as mesmas variáveis, deveremos declará-las com variáveis globais, isto é, fora de todas as funções.
10.9 Tipos de Funções
10.9.1 Funções void ( não retornam nada)
Este tipo de função não tem nenhum dado de retorno para a função principal. Ela executa o trecho e retorna para a função seguinte da sua chamada. A função pode não ter parâmetros e ser do tipo void, também.
Exemplo:
	#include <iostream>
using namespace std;
int main()
{void linha();/*prototipo da função(tipo de retorno, nome e (argumentos) */
 cout<<"\nUNESA\n";
 linha();
 cout<<"\nAlgoritmos e Estruturas de Dados\n";
 linha();
 cout<<"\nPolitecnico e SI\n";
 linha();
 cout<<"\nPROF. ANITA LOPES\n";
 linha();
 cout<<"\n";
 system("pause");
}
void linha()
{int a;
 for(a=1;a<=50;a++)
 cout<<"*";
}
10.9.2 Funções com passagem de valor 
A linguagem C++ passa os valores para funções através de argumentos das chamadas das funções para os parâmetros das funções, na verdade variáveis que receberão cópias dos dados. Desta maneira, os dados de origem não são alterados.
Uma boa dica: Suponha que você comprou um livro e descobriu alguns erros. Você corrige no seu livro, mas não altera o original que, enquanto o autor não corrigir, os erros permanecerão.
Exemplo 1: Função linha com número variado de asteriscos
	#include <iostream>
using namespace std;
int main()
{void linha(int x);
 cout<<"\nUNESA\n";
 linha(5);
 cout<<"\nAlgoritmos e Estruturas de Dados\n";
 linha(32);
 cout<<"\nPolitecnico e SI\n";
 linha(16);
 cout<<"\nPROF. ANITA LOPES\n";
 linha(17);
 cout<<"\n";
 system("pause");
}
void linha(int x)
{int a;
 for(a=1;a<=x;a++)
 cout<<"*";
}
Exemplo 2: Função linha com número variado de qualquer caracter
	#include <iostream>
using namespace std;
void linha(int x,char c)
{int a;
 for(a=1;a<=x;a++)
 cout<<c;
}
int main()
{
 cout<<"\nUNESA\n";
 linha(5,'#');
 cout<<"\nAlgoritmos e Estruturas de Dados\n";
 linha(32,'*');
 cout<<"\nPolitecnico e SI\n";
 linha(16,'@');
 cout<<"\nPROF. ANITA LOPES\n";
 linha(17,'=');
 cout<<"\n";
 system("pause");
}
Exemplo 3: função PA.
	void PA(int x,int y,int z)
{int c;
 for(c=1;c<=z;c++)
 {cout<< x<<”\t”;
 x+=y;
 } 
}
Exemplo 4: Função RAIZ.
	float RAIZ(float rad,int ind)
{ return pow(rad,1.0/ind);}
10.9.2.1 Funções recursivas
As funções recursivas, embora mais elegantes que as funções normais, são muito mais lentas e, muitas vezes de difícil compreensão.
"Quando uma função chama a si própria, as novas variáveis locais e os argumentos são alocados na pilha, e o código da função é executado com esses novos valores a partir do início. Uma chamada recursiva não faz uma nova cópia da função. Somente os argumentos e as variáveis são novos. Quando cada chamada recursiva retorna, as antigas variáveis locais e os parâmetros são removidos da pilha e a execução recomeça no ponto de chamada da função dentro da função dentro da função. Tendo em vista que o local para os argumentos de funções e para as variáveis locais é a pilha e que a cada nova chamada é criado uma cópia destas variáveis na pilha, é possível ocorrer overflow da pilha (stack overflow) e o programa trancar."( FERNANDO CÉSAR COMPARSI DE CASTRO)
Exemplo 1: Conta algarismos de um número.
	int contaAlgarismos(int a)
{if(a==0)
 return a;
 else
 return 1+ contaAlgarismos(a/10);
} 
Exemplo 2:. Soma algarismos de um número.
	int somaAlgarismos(int a)
{
 if(a==0)
 return(a);
 if(a>0)
 return(a%10+somaAlgarismos(a/10));
} 
 Exemplo 3:. Multiplica dois números.
	int mult(int m1,int m2)
{int m;
 if(m1==0)
 return m1;
 else
 return m2+mult(m1-1,m2);
}
Exemplo 4: Soma os pares em um intervalo de 1 até n-1.
	int somaPares(int n)
{
 if(n==0)
 return(n);
 else 
 if(n%2==0)
 return n+somaPares(n-1);
 else
 return somaPares(n-1); 
} 
 
 Exemplo 5: Potência de 10.
	int pot10(int pot)
{
 if(pot==0)
 return(1);
 if(pot>0)
 return(10*pot10(pot-1));
}
Exemplo 6: Fatorial de um número.
	int fat(long int m1)
{ if(m1==0)
 return 1;
 else
 return m1*fat(m1-1);
} 
10.9.3 Funções com passagem por referência
Para melhor compreensão deste item, precisaremos estudar PONTEIROS.
Nós já trabalhamos com ponteiros embora, claramente não tenhamos usado esta nomenclatura.
Continuando o estudo de matrizes, tomamos conhecimento que ao declaramos uma matriz, era feita uma alocação na MP para todos os elementos da matriz de forma contígua, porém só era guardado o primeiro endereço do primeiro elemento da matriz.
Suponha a declaração: int vet[5]; e a tabela criada durante a execução do programa:
	Nome da matriz
	Tipo da matriz
	Endereço
	vet
	int
	60000
 	
Não se lembrou ainda?
Então mais uma recordada: quando fazemos referência a um elemento da matriz, usamos o nome da matriz e, entre pares de colchetes, a posição do elemento dentro da matriz.
Tomemos como exemplo a declaração int vet[5]; :
	vet[0]
	vet[1]
	vet[2]
	vet[3]
	vet[4]
	lixo
	lixo
	lixo
	lixo
	lixo
	60000
	60001
	60002
	60003
	60004
	60005
	60006
	60007
	60008
	60009
	60010
	60011
	60012
	60013
	60014
	60015
	60016
	60017
	60018
	60019
Então podemos concluir que o índice é um deslocamento do endereço básico (no exemplo, 60000) para chegarmos a outro elemento da matriz.
Sendo int uma variável de tamanho de 4 bytes, chegamos a seguinte fórmula para o deslocamento:
	índice * 4 + endereço básico
 
Exemplo: deslocando para o terceiro elemento: 2*4+60000=60008 
Exemplo 1: Função maiuscula
	char maiuscula(char n[])
{int c;
 for(c=0;c<strlen(n);c++)
 n[c]=toupper(n[c]);
}
Exemplo 2: Função Troca
	char troca1(char x[], char y[])
{ char aux[30];
 strcpy(aux,x);
 strcpy(x,y);
 strcpy(y,aux);
}
	
Exemplo 3: Função ordena vetor
	void ordena(int v[],int t)
{ int c,l,aux;
 for(c=0;c<t-1;c++)
 for(l=c+1;l<t;l++)
 if(v[c]<v[l])
 {aux=v[c];v[c]=v[l];v[l]=aux;}
}
11 PONTEIROS
11.1 Considerações
	
A MP consiste de milhões de posições para armazenamento de dados, SO, programas, etc.
O tamanho da MP depende da capacidade instalada em seu computador.
Nós já vimos que, ao declaramos uma variável, o "nome" dado é associado a uma posição de memória (endereço) e quanto cada tipo de variável ocupa na MP. A variável do tipo struct ocupa o somatório das variáveis que a compõe.
O ponteiro é uma variável que contem o endereço de outra variável.
O uso de ponteiros nos dá uma grande flexibilidade em programação, pois determinadas rotinas em outras linguagens só podem ser feitas em assembly. 
Uma boa dica para entender como funciona a variável ponteiro: você viu no jornal um anúncio de uma loja que vende notebook muito facilitado para alunos que estão cursando Engenharia ou Informática. Ao ligar para a loja, você pede o endereço e anota na sua agenda. Você vai até à loja(na linguagem C, &loja) para verificar as condições de pagamento e até dar uma "pechinchada"(na linguagem C, *loja) porque quem sabe você, com muita choradeira consegue um bom desconto.
	A variável ponteiro precisa ser declarada como qualquer outra variável.
	Como se declara?
 
	tipo *nome da vriável ponteiro ;
	
O que significa tipo para uma variável ponteiro?
Quando declaramos uma variável ponteiro, precisamos informar o tipo de variável que será apontada pelo ponteiro.
	Quando usamos o operador & antes de uma variável?
	Quando precisarmos informar à variável ponteiro que ela armazenará o endereço de outra variável. Neste momento, estaremos incializando a variável ponteiro.
	Lembre-se de que sempre precisamos inicializar uma variável ponteiro.
11.2 Atribuição de ponteiros
Exemplo:
	.
int x,*px;
px=&x;
.
	
Quando usamos o operador * antes da variável ponteiro?
Quando desejarmos o conteúdo do endereço apontado pela variável ponteiro.
	#include <iostream>
using namespace std;
int main()
{int a,b;
 int *pa,*pb;
 struct reg
 {int mat;
 float av1,av2,av3;
 }aluno;
 int n[4];
 aluno.mat=11;
 aluno.av1=8;aluno.av2=9;aluno.av3=10;
 cout <<"\nEndereco do vetor n: "<<&n<<endl;
 cout <<"\nEndereco de n0: "<<&n[0]<<"\tEndereco de n1: "<<&n[1]<<"\n\n";
 cout <<"\nEndereco de n2: "<<&n[2]<<"\tEndereco de n3: "<<&n[3]<<"\n\n"; 
 cout <<"\nEndereco de mat: "<<&aluno.mat<<"\tEndereco de av1: "<<&aluno.av1<<"\n\n"; 
 cout <<"\nEndereco de av2: "<<&aluno.av2<<"\tEndereco de av3: "<<&aluno.av3<<"\n\n"; 
 cout <<"\nEndereco de pb: "<<&pb<<"\tEndereco de pa: "<<&pa<<endl; 
 cout <<"\nEndereco de b: "<<&b<<"\tEndereco de a: "<<&a<<"\n\n";
 a=23; b=52;
 pa=&a; pb=&b;
 cout <<"\nConteudo de a: "<< a<<"\t\tConteudo de b: "<<b<<endl;
 cout <<"\nConteudo de pa: "<<pa<<"\tConteudo de pb: "<<pb<<endl;
 cout<<*pa<<"\t\t"<<*pb<<endl; 
 system("pause");
}
11.4 Ponteiros e Matrizes
A relação entre ponteiros e matrizes é muita intensa como já falamos anteriormente e, por esta razão, vamos reescrever um programa já visto:
LEIA COM ATENÇÃO AS CONSIDERAÇÕES ABAIXO E ANALISE O PROGRAMA
Considerações:
1. ps=s; ps foi associado ao endereço do primeiro elemento do vetor s(Relembrando que ao usarmos o nome do vetor sem índice estamos na verdade fornecendo o endereço do começo do vetor).
2. ps+l como já foi dito, você pode somar ou subtrair inteiros. Neste caso, o conteúdo da variável l, será o incremento do ponteiro.
*( ps + l) o conteúdo da variável l será somado ao endereço básico apontado por ps. A expressão *( ps + l) representa o conteúdo do endereço. Como ps é um apontador para int, o ponteiro é incrementado de 4 bytes, isto é, embora ps seja incrementado de 1, em verdade, cada 1, equivale a 4.
	#include <iostream>
using namespace std;
int main()
{int s[5],l,*ps;
 ps=s;
 for(l=0;l<5;l++)
 {cout<<"\ndigite "<<l+1<<"o numero: "; 
 cin>>*(ps+l);
 }
 system("cls");
 cout<<"\n\n\nVETOR\n\n";
 for(l=0;l<5;l++)
 cout<<*(ps+l)<<endl;;
 system("pause");
}
 
LEIA COM ATENÇÃO AS CONSIDERAÇÕES ABAIXO 
Considerações:
1. p=&mat[0][0]; p foi associado ao endereço do primeiro elemento da primeira linha da matriz mat.
2. (p+2*l+c)); como cada vez que o ponteiro é incrementado ele desloca tantas posições quanto for o tamanho da variável que ele aponta, para se chegar ao endereço de um elemento da matriz, usamos a seguinte fórmula:
número de colunas da matriz * número da linha desejada + número da coluna na linha
3. *(p+2*l+c) o conteúdo da variável l multiplicado por 2(número de colunas da matriz), somado com c(número da coluna desejada na linha) e somado ao endereço básico apontado por p A expressão *(p+2*l+c) representa o conteúdo do endereço. 
	#include <iostream>
using namespace std;
int main()
{int mat[3][2],L,c,*p;
 p=&mat[0][0];
 for(L=0;L<3;L++)
 for(c=0;c<2;c++)
 { cout<<"\ndigite elemento "<<L+1<<","<<c+1<<": ";
 cin>>*(p+2*L+c);
 }
 system("cls"); 
 cout<<"\n\n\nMATRIZ\n\n";
 for(L=0;L<3;L++)
 { for(c=0;c<2;c++)
 cout<<*(p+2*L+c)<<"\t";cout<<"\n"; 
 }
 system("pause");
}
Exemplo: Observe a solução abaixo para matrizes bidimensionais:
	#include <stdio.h>
main()
{int mat[3][2],l,c;
for(l=0;l<3;l++)
 for(c=0;c<2;c++)
 { printf("\ndigite elemento %d-%d: ", l+1,c+1);
 scanf("%d",*(mat+l)+c);
 } 
 printf("\n\n\nMATRIZ\n\n");
 for(l=0;l<3;l++)
 { for(c=0;c<2;c++)
 printf("%d\t",*(*(mat+l)+c));
 printf("\n"); 
 }
 printf("\n\n");
}
Vamos explicar melhor a expressão em negrito: *(*(mat+l)+c), supondo L=1 e c=1:
*(mat+1 ) +1) – 
	mat[0][0]
	mat[0][1]
	mat[1][0]
	mat[1][1]
	mat[2][0]
	mat[2][1]
	lixo
	lixo
	lixo
	lixo
	lixo
	lixo
	60000
	...
	6003
	60004
	...
	6007
	60008
	...
	60011
	60012
	...
	60015
	60016
	...
	60019
	60020
	...
	60023
	1a linha
	2a linha
	3a linha
 Deslocamento entre linhas:
mat – é um array de 3 por 2 e é convertida para um endereço para a 1a linha- 60000.
mat + 1 – é um endereço para a 2a linha, iniciando em 60008- (equivale: 60000 + 2(colunas) * 1(deslocamento) * 4(bytes)).
 Deslocamento entre colunas de uma linha:
*(mat +1) – é convertida para um endereço para o primeiro inteiro da 2a linha (começa em 60008 e termina em 60011).
*(mat +1) + 1 – é um endereço para o segundo inteiro da 2a linha (começa em 60012 e termina em 60015, pois 60008 + 4(bytes) é igual à 60012).
*( *(mat +1) + 1 ) - é o segundo inteiro da 2a linha.
Observação: A aritmética de ponteiros(uso do * ), na maioria da vezes, é mais rápida e eficiente em se tratando de um acesso seqüencial do que a indexação de matrizes, porém não devemos achar que nunca mais usaremos a indexação porque a aritmética de ponteiros pode ser tão complexa e confusa que,às vezes, é mais fácil codificar usando a indexação, principalmente se for usada randomicamente.
VIU COMO A MATRIZ É TRATADA COMO PONTEIRO NA LINGUAGEM C++ ?
11.5 Ponteiros para Estruturas
Quando se passa uma estrutura para uma função, gera-se uma sobrecarga da pilha implicando em perda de tempo na transferência de dados entre uma função chamadora e função chamada. Tendo em vista isto, aconselha-se a passar para a função somente um ponteiro como argumento, pois estaremos passando o endereço da estrutura, tornando a chamada extremamente rápida .
Existe duas formas de se acessar o elemento através do ponteiro:
...(*ptr).elemento
...ptr ->elemento /* mais recomendável */
Para se atribuir o endereço de uma estrutura a um ponteiro, usamos:
ptr= &nome;
Veja o exemplo 1 onde passamos para uma função um ponteiro de estrtura:
	#include <iostream>
#include <cctype >
#include <cstring>
using namespace std;
 struct CADASTRO
 { char nome[30];
 float nota;
 };
void imp(struct CADASTRO *m) 
{ int c;
 for(c=0;c<strlen(m->nome);c++)
 m->nome[c]=toupper(m->nome[c]); 
}
int main()
{ 
 struct CADASTRO aluno,*p;
 char c;
 cout<<"\nNome : ";
 cin.getline(aluno.nome,29);
 cout<<"\nNota: ";
 cin>>aluno.nota;
 p=&aluno;
 imp(p);
 system("cls");
 cout<<"\nNOME: "<<p->nome;
 cout<<"\nNOTA: "<<p->nota<<endl;;
 system("pause");
}
 
Considerações sobre FUNÇÕES 
Quando usamos funções, nossos programas ficam menores, pois não temos que repetir o código várias vezes.
Os protótipos de função servem para declarar as funções, isto é, indicar para o compilador qual o seu nome, tipo de retorno e o número e tipos dos parâmetros 
As variáveis declaradas em uma função só são acessíveis na função
Funções podem ser chamadas por outras funções, mas não podem ser definidas dentro de outras funções 
Uma função que não retorna nada deve ser declarada como void
Os parâmetros recebidos por uma função com passagem por valor armazenam cópias das variáveis usadas na chamada da função 
Quando desejarmos alterar os conteúdos das variáveis que são passadas como parâmetros para uma função, devemos declará-las como ponteiros na função
Quando utilizamos um vetor como parâmetro para uma função, estamos fornecendo o enderço do primeiro elemento do vetor
Em um programa C, as funções de um programa podem estar em vários arquivo.c
Variáveis globais são conhecidas e podem ser alteradas por todas as funções do programa
A função scanf necessita receber como parâmetro o endereço da variável de entrada, porque ela precisa alterar esta variável. (Lembre-se de usar o operador & para variáveis numéricas e char de um caracter. A variável vetor de char não precisa, pois já é um endereço) 
As bibliotecas contêm o protótipo de algumas funções da biblioteca do C 
Funções não rodam mais rápido 
Funções modularizam o programa e podem ser testadas em separado
Retorno da função
Uma função pode ter vários comando return 
Você só pode retornar o conteúdo de uma variável através do comando return 
Uma função pode retornar um ponteiro 
O retorno da função main é feito para o sistema operacional 
 
Considerações sobre PONTEIROS
Após a atribuição  pa=&a[0];  pa e a possuem valores idênticos, isto é, apontam para o mesmo endereço
A atribuição  pa=&a[0];  pode ser escrita como pa=a;
a[i] pode ser escrito como *(a+i) 
	
�
Estruturas de Dados
“Estruturas de dados são construções de uma linguagem de programação que agregam um ou mais elementos de dados para formar um tipo de dado que armazena uma quantidade maior de informações”(Oliveira,R,taveira,G, Botini,J,2003)
Várias são as formas de se organizar dados: pilhas, filas, listas, árvores, etc.
O objetivo das estruturas de dados é tornar o algoritmo mais eficiente.
Pilhas
1. Conceitos
É a ED mais simples e por esta razão é muito utilizada.
Estruturas de dados dinâmicas onde os elementos podem ser estruturas estáticas ou dinâmicas.
Não existe “buracos”.
São conhecidas como estruturas FILO – first in, last out (o primeiro elemento que entra é o último a sair. A sigla LIFO – last in, first out tem o mesmo significado: último a entrar, primeiro a sair).
A inserção é sempre no topo da pilha e a remoção também.
Muito usadas pelo SO: um exemplo é na chamada de funções onde o endereço de retorno é empilhado.
Não confundir o termo heap da figura que é uma área de armazenagem alocada, como por exemplo: malloc com a ED Heap(árovre)
Quando se pensa em um pilha, fazemos alusão a duas operações: PUSH(empilha) e POP(desempilha).
Se a pilha cresce descontrolada, pode acontecer um “estouro de pilha”(overflow).
2. Operações realizadas com a Pilha
criar uma estrutura de pilha;
inserir um elemento no topo;
retirar o elemento do topo;
verificar se a pilha está vazia;
liberar a pilha.
3. Programa que manipula uma PILHA
#include <iostream>
using namespace std;
/* variaveis globais que podem ser alteradas todas as funções */
 int qtde=0, /* numero de elementos ja inseridos na pilha */
 pilha[10]; 
/* Insere */
void empilha(int valor)
{ int x;
 if(qtde == 10) /* se a pilha estiver cheia */
 cout<<"\nPILHA CHEIA. O VALOR DIGITADO NAO FOI INSERIDO."; 
 else 
 { for(x=qtde;x>0;x--) 
 pilha[x]=pilha[x-1]; 
 pilha[0]=valor;
 qtde++;
 }
}
/* Remove */
int desempilha()
{
 int x; int valor;
 if(qtde == 0) /* se a pilha estiver vazia */
 { cout<<"\nPILHA Vazia";
 valor=-999; 
 }
 else
 { 
 valor=pilha[0]; /* guarda valor removido */
 for(x=1;x<qtde;x++)
 pilha[x-1]= pilha[x];
 qtde--;
 }
 return valor;
}
/* Mostra a pilha */
void imprime()
{ 
 int i;
 if(qtde==0) cout<<"\nPILHA vazia";
 else
 {
 cout<<"\n\nElementos da PILHA\n\n";

Outros materiais

Materiais relacionados

Perguntas relacionadas

Perguntas Recentes