algoritmos e estruturas de dados ii por que alunos de engenharia
TRANSCRIPT
16/08/2011
1
Algoritmos e Estruturas de Dados II
Gisele L. Pappa, Clodoveu Davis e Raquel
Por que alunos de engenharia são obrigados a fazer AEDS2?
Por que alunos de computação são obrigados a fazer AEDS2?
AEDS2: e a diversão começa!
Como criar seu próprio Facebook?
• Como representar seu perfil,ou seja, como armazenar asInformações pessoais?
• Como armazenar sua lista deamigos?
• Como armazenar 1 bilhãode usuários?
• Como buscar um novo amigo?
• Como sugerir novos amigos?
•Como ordenar suas fotos em ordem cronológica?
16/08/2011
2
Ementa
• Tipos Abstratos de Dados (TADs)
• Análise de Algoritmos
O(n), O(n log n), )(n!), ...
• Estruturas de dados
listas, filas, pilhas e árvores
• Métodos de ordenação
quick, heap, merge, select, etc
• Métodos de pesquisa
hash, árvores binárias, árvores digitais
Parte 1Prova 1 – 13/09
TP1
Parte 2Prova 2 – 06/10
TP2
Parte 3Prova 3 – 17/11
TP3
Por que esse auditório vai começar assim....
E terminar assim???? Avaliação
• 3 provas (total 60 pontos)
• 3 trabalhos práticos power – (total 35 pontos)
• Implementação
• Documentação
• Teste
• 1 trabalho prático menos power (3 pontos)
• Exercícios (total 2 pontos)
Moddle
• Todas informações relacionadas ao curso, incluindo notas de aulas, estarão disponíveis no Moodle
• Sistema de submissão de trabalhos práticos
• Prático
http://aeds.dcc.ufmg.br
Detalhes
• Linguagem: C
• Software Recomendado: CodeBlocks
• Instruções de instalação no Learnloop
• Sistema operacional recomendado: Linux
• Alta carga extra classe
16/08/2011
3
Programação em Crecomendações e boas práticas
Clodoveu Davis
Gisele L. Pappa
Tópicos
• Indentação
• Comentários
• Modularização
• Compilação e Debug
• Entrada e saída
• Vetores e Strings
• Passagem de parâmetros
• Structs
Boas Práticas
• Com um pequeno esforço extra, programas escritos em C podem se tornar mais legíveis e mais facilmente “debugáveis”
• No caso de disciplinas de programação, isso ainda ajuda no entendimento das idéias e na correção de trabalhos
Indentação
• É usual empregar TABS para indicar blocos de programação
– Em geral, 1 tab equivale a 8 espaços, MAS NÃO USAR ESPAÇOS para alinhar
• Há vários estilos
• Quando o bloco é longo, é usual colocar um pequeno comentário após o fechamento indicando o que está sendo fechado
Indentação
• K&R: Kernighan & Ritchie
Indentação
• 1TBS: One True Brace Style
16/08/2011
4
Indentação
• Allman
Comentários
• Importantes para compreensão do código
• Mais importantes em código mais complexo
• Úteis para explicar o conteúdo de variáveis, mas não substituem um bom critério de atribuição de nomes
• Não exagerar!
Comentários
• No início de cada módulo de código (arquivos .c, .h)
• Uma linha em cada função, explicando o que ela faz– Não é necessário explicar COMO ela faz, o código deve ser
claro o bastante para permitir esse entendimento em uma função razoavelmente pequena
– Se necessário, considerar a quebra em outras funções
• Comentário na linha da declaração, se necessário, para esclarecer o significado/o uso de uma variável
• Comentário na linha do fecha-chave, para ajudar a entender blocos e loops
Comentários
• No início de um bloco/arquivo fonte
Comentários
• Em função (simples)
Comentários
• Em funções (arquivo .h)
16/08/2011
5
Comentários
• Em variáveis
• Em structs
Comentários
• No fim de um bloco de programa
• No código
Modularização
• Planejar a quebra de um programa em módulos– Um módulo não significa necessariamente um arquivo
fonte; muitas vezes, é um par de arquivos .c / .h
– Existe sempre um arquivo fonte para o programa principal (main), e outros para funções adicionais ou componentes
• Montar módulos especificamente para tipos abstratos de dados [aula: TAD]
• Procurar dar independência aos módulos, para que possam eventualmente ser reaproveitados
Modularização
Modularização Modularização
16/08/2011
6
Modularização
Atenção: incluir timer.h e timer.c no projeto
Modularizaçãotransformação em biblioteca
timer.lib
Copiar timer.h para o diretório “includes” do compilador
Copiar timer.lib para o diretório lib do compilador
Constantes e #define
• Não usar “números mágicos” no código
• Algumas constantes usadas no programa podem ter que ser modificadas, e é mais fácil fazer isso em um lugar só
• Sempre que for tornar o código mais legível, usar #define para dar um nome à constante– Em geral, nomes de constantes são em maiúsculas
#define PI 3.141592
#define MAX_VETOR 1000
Nomes de variáveis
• Algumas variáveis merecem nomes significativos: MAX_VETOR, numClientes, listaAlunos
• Variáveis auxiliares em geral recebem nomes curtos: i, j, aux, x
– Cuidado para não fazer confusão– Não abusar: i, ii, iii, aux1, aux2, aux3...
– Variáveis inteiras: i, j, k– Variáveis reais: x, y, z– Strings: s1, s2– Booleanas: nome do teste (existe, valido, ocorre)
Nomes de variáveis
• Estilos variados:– Só minúsculas (i, num, conta)
– Só maiúsculas (constantes: PI, E, MAX)
– CamelCase (numMat, anguloEntrada)
– Indicação do tipo no início do nome (iNum, iValor, fRaio, fAltura, dVolume)
• Há quem prefira inserir comentários e usar nomes de variáveis em inglês, por ficar mais próximo da linguagem de programação
Organização e limpeza
• Procurar dar um aspecto organizado ao código, ajuda na compreensão
• Entender o código fonte como um instrumento de comunicação
• Comentar excessivamente código mal escrito não ajuda
• Dar nomes adequados a variáveis ajuda bastante
16/08/2011
7
Parênteses e espaçamento
• Usar espaços antes de parênteses, depois de vírgulas, ao redor de operadores bináriosif (x == 10) y = 5;
for (i = 0; i < 10; i++) {
x += a;
a = f(b);
}
• Cuidado com notações compactas demais, e com comandos embutidos em outrosif (x++ == b) y = 5;
Correção e robustez
• Testes: prever todo tipo de problema e variações na entrada de dados
– Limites de vetores
– Valores inteiros e de ponto flutuante
– Contadores e incremento
– Testes de fim de arquivo
– Teste de disponibilidade de memória para alocação
Compilação
• LER as mensagens de erro e ENTENDER a origem do problema
• Warnings: indicam problemas potenciais, devem ser resolvidos
• Muitas vezes a mensagem de erro não reflete o que está ocorrendo– Observar a linha em que o erro foi indicado, a
linha anterior, o bloco de código em que ocorreu, e o corpo da função em que ocorreu
Debugger
• Ajuda a acompanhar os valores das variáveis ao longo da execução
– Observar o valor de variáveis (watches)
– Posicionar pontos de interrupção (breakpoints)
– Executar passo a passo
• Videhttp://wiki.codeblocks.org/index.php?title=Debugging_with_Code::Blocks
• Documentação do CodeBlockshttp://wiki.codeblocks.org/index.php?title=Main_Page
ENTRADA E SAÍDA
I/O em C
• Formalmente, rotinas de entrada e saída não fazem parte da linguagem, e sim de bibliotecas que acompanham os compiladores
– Felizmente, são padronizadas
– Exige-se a linha #include <stdio.h> para usá-las
16/08/2011
8
I/O em C
• printf(string [, valor , valor, ...]);
– O string contém uma “máscara” (template) com lacunas reservadas para os valores que serão impressos
– Pode não existir lacuna
printf(“O valor de x eh %d”, x);
printf(“Area: %f\n”, PI*d*d/4);
printf(“Nome: %s”, nomeAluno);
printf
• Especificadores de formato
– %c (char)
– %s (string)
– %d (int)
– %ld (long int)
– %f (float)
– %lf (double)
– %e (float notação científica)
– %g (e ou f, ou seja, notação científica se necessário)
printf
• Especificação completa
Caracteres de escape
• Acrescentados à máscara para provocar reposicionamento do cursor
– \n: nova linha
– \t: tabulação
– \r: backspace
– \\: caractere da barra invertida
Entrada
• Com máscara: scanf(string, *var [, *var, ...]);
– Mesmos especificadores de formato do printf
– A função precisa receber o endereço da variável à qual o valor digitado será atribuídoscanf(“%d”, &num)
scanf(“%c%d”, &letra, &num);
scanf(“%c”, &ch);
scanf(“%s”, s); // string
scanf(“%13c”, s); //le 13 caracteres
scanf(“ %c”, &ch); //pula brancos
Entrada
16/08/2011
9
Entrada
• Observe que scanf interrompe a leitura de um string quando encontra um branco, se usado com %s
• Uso de %[]:
– %[aeiou]: apenas as vogais são permitidas
– %[^aeiou]: as vogais não são permitidas
– %[^\n]: interrompe quando recebe um [enter]
– %60[^\n]: admite até 60 caracteres, e para quando encontra um enter
Entrada
• Linhas inteiras: gets(string)
– Lê uma linha inteira, excluindo \n, e coloca \0 no final
– Com limite de tamanho: • fgets(string, tamMax, stdin)
Entrada
• Caracteres individuais: getchar()
– O caractere digitado é o valor de retorno da função
I/O para arquivos
• A entrada do teclado e saída para o monitor são realizadas internamente considerando três dispositivos virtuais: stdin, stdout e stderr
– Como são dispositivos padrão, referências a stdin e stdout eles são omitidas dos comandos
• I/O para arquivos é muito semelhante à operação com stdin e stdout, mas um handle
ao arquivo tem que ser fornecido
I/O para arquivos
• O handle é obtido no momento da abertura do arquivoFILE *inFile; // variável handle
FILE *outfile;
...
//abre o arquivo para leitura (r) ou gravacao (w)
inFile = fopen(“arquivo.txt”, “r”);
outFile = fopen(“saida.txt”, “w”);
...
fscanf(inFile, “%d”, &num);
...
fprintf(outFile, “O valor lido eh %8.2d\n”, num);
...
fclose(inFile);
fclose(outFile);
I/O para arquivos
• fopen: modos de abertura
16/08/2011
10
I/O para arquivos
• Se o handle retornar nulo do comando fopen, então ocorreu erro (arquivo não encontrado, arquivo travado contra gravação, permissão negada pelo sistema operacional, etc.)
• Testar:if ((inFile = fopen(“arquivo.txt”, “r”)) == NULL)
{
printf(“Nao consegui abrir.\n”);
exit(1);
}
I/O para arquivos
• gets() � fgets(arq, tamMax, string);
• getchar() � fgetc(arq);
• putc(ch) � fputc(arq, ch)
• printf � fprintf(arq, string, valor)
• scanf � fscanf(arq, string, endereço)
• feof(arq)
– Retorna booleano indicando se o fim do arquivo foi atingido
– Neste caso, o fgetc retorna a constante EOF, definida em stdio como 0xFFFF
I/O para arquivos
• Exemplo
Exercício (POSCOMP 2009)#include<stdio.h>
#include<string.h>
int main (void)
{
char texto[]= "foi muito facil";
int i;
for (i = 0; i < strlen(texto); i++){
if (texto[i] == ' ') break;
}
i++;
for ( ; i < strlen(texto); i++)
printf("%c", texto[i]);
return 0;
}
O que será impresso quando o programa for executado?
I/O para arquivos
• Exemplo (variação)
VETORES E STRINGS
16/08/2011
11
Alocação estática de memória
• Ao se declarar uma variável qualquer, o compilador deixa reservado um espaço suficiente na memória para armazená-la
int a; // 2 bytes
long b; // 4 bytes
float x; // 4 bytes
double y; // 8 bytes
char c; // 1 byte
Alocação estática de memória
• Ao fazer a alocação estática, apenas o espaço necessário na memória é reservado
• O conteúdo de cada posição não é alterado, e portanto uma variável apenas declarada pode conter qualquer coisa
• Inicializar as variáveis, atribuindo valores, antes do uso
– Inclusive vetores, matrizes e strings
Vetores
• Quando se declara um vetor, o valor entre chaves indica quantas vezes o espaço de memória necessário para o tipo básico será alocado
int v[100]; // 100 * sizeof(int) = 200 bytes
long vl[200]; // 200 * sizeof(long) = 800 bytes
double z[1000]; // 1000 * sizeof(double) = 8000 bytes
Vetores
• A referência a uma posição de um vetor indica o cálculo de uma posição de memória a partir do início do vetorfloat x[1000];
// x[20] está na posição x + 20*sizeof(float)
• Na verdade, o símbolo x é um apontador para o início da região de memória reservada para o vetor
Vetores
• C NÃO AVISA NEM PRODUZ ERRO QUANDO O LIMITE DE UM VETOR OU MATRIZ FOR EXCEDIDOy = x[2000]; // não dá erro, mas vai acessar
// uma parte inesperada da memória
– Erro mais comum (runtime): segmentation fault
• É responsabilidade do programador verificar os limites, e garantir que não sejam excedidos
Matrizes = Vetores de mais de uma dimensão
• Na verdade, a alocação na memória é linear
• Muda apenas o cálculo da posição de memória do elemento referenciado
int M[5][5];
...
M[0][0] = 15;
M[2][3] = 2; // posicao: M + (2*5 + 3)*sizeof(int)
16/08/2011
12
Strings
• Um string é um vetor do tipo char
• Para manipulação do string, atribuindo e recuperando valores, e realizando operações sobre ele, é importante entender essa característica
• Quando o conteúdo de um string não ocupa todo o espaço disponível, usa-se um caractere ‘\0’ (ou NULL, código ASCII 0) como delimitador
Strings
• Strings constantes aparecem no código entre aspas
printf(“%s”, “Bom dia!”);
• O delimitador \0 está incluído:
Strings
• Não é possível fazer atribuições diretas para strings
• Usar a função strcpy ou a função strncpy
Strings
• Na inicialização, pode-se usar o mesmo recurso disponível para vetores
• char nome[] = {‘A’, ‘n’, ‘a’, ‘\0’};
• Ou• char nome[] = “Ana”;
Strings
• Como o nome do string representa o endereço onde começa o string, é possível manipulá-lo diretamente
– Cuidado!
• Exemplochar nome[] = “Alexandre”;
printf(“%s\n”, nome + 3); // imprime “xandre”
Strings
• Funções
– strlen(st): retorna o comprimento do string (com exceção do \0)
– strcat(st1, st2): concatena o s2 no s1 (s1 tem que ter espaço)
– strcmp(s1, s2): retorna <0 se s1 é menor que s2, ==0 se s1 é igual a s2, e >0 se s1 é maior que s2 (ordem alfabética)
• A comparação entre strings também tem que ser feita caractere a caractere, portanto não se pode usar s1==s2; isso só compara os endereços
16/08/2011
13
Strings
• strncat, strncmp, strncpy: idem aos anteriores, mas especifica o número de caracteres que serão considerados
Strings• strtok: extrai “tokens”, substrings delimitados
• Exemplolong int num; char linha[256];
...
while (!feof(infile)) {
fgets(linha, 256, infile);
p1 = strtok(linha, " \n"); //delim: branco ou fim de linha
while ((p1 != NULL) && (!feof(infile)))
{
num++;
fprintf(outfile, "%s\n", p1);
p1 = strtok(NULL, " \n");
}
}
printf("O arquivo de entrada tinha %ld palavras.\n", num);
fclose(infile);
Strings
• Vetores de strings podem ser criados
• Exemplo
char DiaSemana[7][14] = {“Domingo”,
“Segunda”, “Terça”, “Quarta”,
“Quinta”, “Sexta”, “Sabado”};
...
printf(“%s\n”, DiaSemana[3]);
Algoritmos e Estrutura de Dados II
Alocação Estática x Dinâmica• Linguagens de programação como Pascal, C e C++
permitem dois tipos de alocação de memória: Estática e
Dinâmica
• Na alocação estática, o espaço de memória para as
variáveis é reservado no início da execução, não podendo
ser alterado depois
– int a; int b[20];
• Na alocação dinâmica, o espaço de memória para as
variáveis pode ser alocado dinamicamente durante a
execução do programa
Algoritmos e Estrutura de Dados II
E Java?
• Em java não existe manipulação explícita de apontadores.
• Todo objeto é criado dinamicamente (new) e as variáveis apontam para os objetos
– Variáveis dos tipos básicos são alocadas estaticamente (não é necesário o new)
• A desalocação de memória é feita automaticamente (garbage collection)
Algoritmos e Estrutura de Dados II
Alocação Dinâmica• A memória alocada dinamicamente é acessada
através de Apontadores (pointers) que na verdade são variáveis que armazenam o endereço de uma área de memória
• A memória alocada dinamicamente faz parte de uma área de memória chamada heap
– Basicamente, o programa aloca e desaloca porções de memória do heap durante a execução
16/08/2011
14
Algoritmos e Estrutura de Dados II
Alocação Dinâmica
a
HeapMemória Estática
10
0x214
0x218
0x222
0x226
0x230
0x234
0x238
0x242
0x246
a é um intb é um apontador para um int
b 0x234
10
0x016
0x020
Algoritmos e Estrutura de Dados II
Apontadores – Notação em C
• definição de p como um apontador para uma variável do tipo T
– T *p;
• Alocação de memória para uma variável apontada por p
– p = (T*) malloc(sizeof(T));
• Desalocação de memória
– free(p);
• Conteudo da variável apontada por P
– *p;
• Valor nulo para um apontador
– null;
• Endereço de uma variável a (endereço do primeiro byte)
– &a;
Algoritmos e Estrutura de Dados II
Endereço da Variável• Endereço do primeiro byte.
• Exemplo
2293612
2293611
2293552
2293544
int i;
char c;
int v[5];
struct {
int x,y;
} p;
printf("%d\n", &i);
printf("%d\n", &c);
printf("%d\n", &v);
printf("%d\n", &p);
Endereços Impressos:
P – 8 bytes
P – 8 bytes
Algoritmos e Estrutura de Dados II
Alocação Dinâmica
int *a, b;...b = 10;a = (int *) malloc(sizeof(int));*a = 20;a = &b;*a = 30; // qual o valor de b?
HeapMemória Estática
Algoritmos e Estrutura de Dados II
Alocação Dinâmica
int *a, b;...b = 10;a = (int *) malloc(sizeof(int));*a = 20;a = &b;*a = 30; // qual o valor de b?
a
20
b
HeapMemória Estática
10
X
30
Memória não foi desalocada. O espaço continua ocupado
Algoritmos e Estrutura de Dados II
Erros Comuns
• Esquecer de alocar memória e tentar acessar o conteúdo da variável
• Copiar o valor do apontador ao invés do valor da variável apontada
• Esquecer de desalocar memória
– Ela é desalocada ao fim do programa ou procedimento função onde a variável está declarada, mas pode ser um problema em loops
• Tentar acessar o conteúdo da variável depois de desalocá-la
16/08/2011
15
Algoritmos e Estrutura de Dados II
Alocação Dinâmica de Vetores
• Normalmente, a alocação dinâmica é utilizada para criar vetores em tempo de execução
• Exemplo:
int *p;
p = (int *)malloc(10*sizeof(int));
– Aloca um vetor de inteiros com x posições. A manipulação pode ser feita normalmente: p[i] = ...
– O apontador p guarda o endereço (aponta) da primeira posição do vetor.
Algoritmos e Estrutura de Dados II
Vetores e Apontadores• Na verdade, em C todo vetor (mesmo alocados
de forma estática) pode ser visto como um apontador.
• Pode se trabalhar usando ambas notações:
– *p é equivalente a p[0]
– p é equivalente a &p[0]
– *(p + i) é equivalente a p[i]
– considerando v um vetor alocado estaticamente, e p dinamicamente, pode-se fazer p = v, mas não v = p (v é, de certa forma, um “ponteiro constante”)
6 4
p
0 1 ...
Alocação Dinâmica de Matrizes• Declaração de Matriz Dinâmica: int** result_matrix;
int** read_matrix(int size_x, int size_y)
{
int** matrix;
int i;
matrix = calloc(size_x, 1+sizeof(int*)); // alloc one
extra ptr
for(i = 0;i<size_x;i++) {
matrix[i] = calloc(size_y, sizeof(int));
}
matrix[size_x] = NULL; // set the extra ptr to NULL
for(int i = 0;i<size_x;i++) {
for(int j = 0;j<size_y;j++) {
matrix[i][j] = i*10+j;
}
}
return matrix;
}
Matrizes
void free_matrix(int **matrix, int rows){
int i;for(i=0; i<rows; i++){
free(matrix[i]);}free(matrix);
}
Reallocvoid *realloc(void *ptr, size_t size)
int main() { char buf[80], *message; puts("Enter a line of text."); gets(buf); /* Allocate the initial block and copy the string to it. */message = realloc(NULL, strlen(buf)+1); strcpy(message, buf); puts(message); puts("Enter another line of text."); gets(buf); // Increase the allocation, and concatenate the string to it.message = realloc(message,(strlen(message) + strlen(buf)+1)); strcat(message, buf); puts(message); return 0;
}Algoritmos e Estrutura de Dados II
Exercício: O que vai ser impresso?double a;
double *p, *q;
a = 3.14;
printf("%f\n", a);
p = &a;
*p = 2.718;
printf("%f\n", a);
a = 5;
printf("%f\n", *p);
p = NULL;
p = (double *)malloc(sizeof(double));
*p = 20;
q = p;
printf("%f\n", *p);
printf("%f\n", a);
free(p);
printf("%f\n", *q);
int a, b, i, v[10];
int *p;
b = 10;
p = &b;
a = *p + 100;
printf("%d\n", a);
a = *&b;
printf("%d\n", a);
for(i=0; i<10; i++)
v[i] = i;
p = v;
for(i=0; i<5; i++)
*(p+i) = 10*i;
p = p + 5;
*p = -5;
for(i=0; i<10; i++)
printf(“%d”,v[i]);
3.142.718
5.020.0
5.0?
11010
010203040-56789
16/08/2011
16
Algoritmos e Estrutura de Dados II
Apontadores para Tipos Estruturados• Apontadores podem ser utilizados com tipos
estruturados. Isso é muito comum na criação de estruturas encadeadas (listas, filas, etc...)
typedef struct {
int idade;
double salario;
} TRegistro;
...
TRegistro *a;
...
a = (TRegistro *) malloc(sizeof(TRegistro);
a->idade = 30; // equivalente: (*a).idade
a->salario = 80; Algoritmos e Estrutura de Dados II
Passagem de Parâmetros• Em pascal e C++, parâmetros para função podem ser
passados por valor ou por referência
– Por valor: o parâmetro formal (recebido no procedimento) é
uma cópia do parâmetro real (passado na chamada)
– Por referência: o parâmetro formal (recebido no procedimento)
é uma referência para o parâmetro real (passado na chamada)
• As modificações efetuadas acontecem no parâmetro real
• Em C só existe passagem por valor, logo deve-se
implementar a passagem por referência utilizando-se
apontadores
Algoritmos e Estrutura de Dados II
Passagem de Parâmetros (C)
void SomaUm(int x, int *y)
{
x = x + 1;
*y = (*y) + 1;
printf("Funcao SomaUm: %d %d\n", x, *y);
}
int main()
{
int a=0, b=0;
SomaUm(a, &b);
printf("Programa principal: %d %d\n", a, b);
}
1 1
0 1
Algoritmos e Estrutura de Dados II
Passagem de Parâmetros• E para alocar memória dentro de um procedimento?
– Em pascal, basta passar a variável (apontador) como referência.
– Em C também, mas como não há passagem por referência as
coisas são um pouco mais complicadas
void aloca(int *x, int n)
{
x=(int *)malloc(n*sizeof(int));
x[0] = 20;
}
int main()
{
int *a;
aloca(a, 10);
a[1] = 40;
}
Error!Access Violation!
void aloca(int **x, int n)
{
*x=(int *)malloc(n*sizeof(int));
*x[0] = 20;
}
int main()
{
int *a;
aloca(&a, 10);
a[1] = 40;
}
OK
Algoritmos e Estrutura de Dados II
Exercícios
1. Faça um programa que leia um valor n, crie dinamicamente um vetor de n elementos e passe esse vetor para uma função que vai ler os elementos desse vetor.
2. Declare um TipoRegistro, com campos ainteiro e b que é um apontador para char. No seu programa crie dinamicamente uma váriavel do TipoRegistro e atribua os valores 10 e ‘x’ aos seus campos.
Algoritmos e Estrutura de Dados II
Respostas (1)
void LeVetor(int *a, int n){
int i;
for(i=0; i<n; i++)
scanf("%d",&a[i]);
}
int main(int argc, char *argv[]) {
int *v, n, i;
scanf("%d",&n);
v = (int *) malloc(n*sizeof(int));
LeVetor(v,n);
for(i=0; i<n; i++)
printf("%d\n",v[i]);
}
Apesar do conteúdo ser modificadoNão é necessário passar por referência pois todo vetor jáé um apontador...
16/08/2011
17
Algoritmos e Estrutura de Dados II
Respostas (2)
typedef struct {
int a;
char *b;
} TRegistro;
int main(int argc, char *argv[])
{
TRegistro *reg;
reg = (TRegistro *) malloc(sizeof(TRegistro));
reg->a = 10;
reg->b = (char *) malloc(sizeof(char));
*(reg->b) = 'x';
printf("%d %c",reg->a, *(reg->b));
}
É necessário alocar espaço parao registro e para o campo b.*(reg->b) representa o conteúdoda variável apontada por reg->b
Passagem de parâmetros para o programa
• Chamada: C:\> prog.exe arg1 arg2 arg3
• Declaração completa da função mainint main(int argc, char *argv[])
• argc: número de parâmetros passados na linha de comando
• argv: um vetor de argc strings
– argv[0]: nome do programa
– argv[1]: primeiro parâmetro
– argv[argc – 1]: último parâmetro
– argv[argc] é sempre NULL
Referências
• Mizrahi, V. V. Treinamento em Linguagem C. Pearson, 2008.
• Kernighan B.W., Ritchie, D.M. C A linguagem de programação (padrão ANSI). Campus, 1989.
• Vide Moodle para links (inclusive cursos online), exemplos e exercícios