Mudanças entre as edições de "PRG29002 - Programação I - Eng.Telecom 2016-1"
Linha 518: | Linha 518: | ||
Uma variável ponteiro tem como conteúdo um endereço. Portanto a variável ponteiro possui um endereço e contém um endereço como conteúdo. Este recurso é largamente utilizado para passar parâmetros como referência (ao invés de copiar uma variável quando se quiser processá-la em alguma função), bem como para algoritmos diversos que buscam formas mais otimizadas de executar operações. | Uma variável ponteiro tem como conteúdo um endereço. Portanto a variável ponteiro possui um endereço e contém um endereço como conteúdo. Este recurso é largamente utilizado para passar parâmetros como referência (ao invés de copiar uma variável quando se quiser processá-la em alguma função), bem como para algoritmos diversos que buscam formas mais otimizadas de executar operações. | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | int main(void) { | ||
+ | // your code goes here | ||
+ | int i = 10; | ||
+ | int *p; | ||
+ | p = &i; | ||
+ | printf("\n &i=%x",&i); | ||
+ | printf("\n i=%=d",i); | ||
+ | printf("\n *p=%d",*p); | ||
+ | printf("\n p=%x",p); | ||
+ | printf("\n &p=%x",&p); | ||
+ | return 0; | ||
+ | } | ||
+ | </syntaxhighlight> | ||
;Ponteiro para inteiro | ;Ponteiro para inteiro |
Edição das 17h44min de 14 de junho de 2016
Professor da Disciplina: Cleber Jorge Amaral
e-mail: cleber.amaral@ifsc.edu.br
Critérios e instrumentos de avaliação
- Conceito => Somatório(Nota)/QtNotas
- Esta é uma previsão, eventuais mudanças serão comunicadas no decorrer das atividades
- Nota[1]: Nota da Avaliação 1 (a definir data e formato)
- Nota[2]: Nota da Avaliação 2 (a definir data, formato e necessidade desta segunda avaliação)
- Nota[3]: Média das notas das Listas de exercícios
- Nota[4]: Nota do Projeto final
- Frequência
- Mínimo 75%
Datas importantes
- 13/04/2016
- Lista de exercícios 1: Entregar por e-mail ou manuscrito
- Desafio 1 (projeto de cafeteira): Entregar por e-mail ou manuscrito a Narrativa, Fluxograma e Pseudocódigo
- 20/04/2016
- Lista de exercícios 2: Entregar por e-mail (seguir instruções) ou manuscrito
- Lista de exercícios 3: Entregar por e-mail (seguir instruções) ou manuscrito
- O estudante deve entregar na forma de fluxograma cada desafio que resolvemos na aula de 13/04 na forma de pseudocódigo, e devem ser entregues na forma de pseudocódigo os fluxogramas que fizemos em sala -
- Os títulos dos algoritmos são citados na mídia 1.3 (link abaixo) mas os detalhes foram trabalhados em sala e fotografados pelos próprios alunos
- 27/04/2016
- Lista de exercícios 4: Entregar por e-mail (seguir instruções) ou manuscrito
- 11/05/2016
- Lista de exercícios 5: Entregar por e-mail (seguir instruções)
- 17/05/2016
- Prova 1: Algoritmos e lógica utilizando pseudocódigo e fluxogramas
- 25/05/2016
- Lista de exercícios 6: Entregar via moodle
- 28/05/2016
- Desafio 2 (jogo da velha): Entregar via moodle
- 08/06/2016
- Lista de exercícios 7: Entregar via moodle (atraso nos 6 primeiros dias contarão -1)
- 14/06/2016
- Apresentação das propostas de projeto final
- 22/06/2016
- Prova 2: Prática
- 26 e 27/07/2016
- Avaliação 3: Apresentação do projeto
Material de aula
Inauguração
- 0.0: Ementa da disciplina
- Ementa da disciplina na wiki: Engenharia de Telecomunicações 2ª Fase
Introdução aos Algoritmos e Pseudocódigo
- 1.0: Introdução aos algoritmos
- 1.1: Algoritmos continuação
- 1.2: Algoritmos - repetição e subrotinas
- 1.3: Algoritmos - fixação
- 1.4 Algoritmos - Preparação para avaliação
Programação em C
Introdução
Controle de fluxo
Funções
Variáveis e operadores
Exercicios complementares - Vetores |
---|
Exemplo: Para os vetores x[]={1,1,3,4,5} e y[]={1,2,3,3,5} temos três elementos iguais (nas posições 0, 2 e 4). |
Variáveis locais e Globais |
---|
|
Gerando números pseudo-aleatórios |
---|
|
Tabela ASCII |
---|
|
Dicas para resolução dos exercícios da lista 7 |
---|
|
Obtendo o código de um caractere UTF-8 |
---|
Para obter o código UTF-8 de um caracter especial (retorno 0xC3) é necessário executar um segundo scanf, conforme exemplo: #include <stdio.h>
int main()
{
unsigned char c;
printf("Digite um caracter especial ou não:\n");
//Primeiro scanf
scanf("%c", &c);
//Se for um caracter especial
if(0xC3 == c)
{
//Segundo scanf para obter segunda codificação deste char UTF8
scanf("%c", &c);
printf("Digitado um caracter especial: 0x%x\n",c);
}
else
{
printf("Digitado um caracter convencional: 0x%x\n",c);
}
return 0;
}
|
Tipos de dados compostos
Estruturas |
---|
Assim como o vetor a estrutura é um conjunto de dados, mas traz uma vantagem: a possibilidade de possuir "campos" de diferentes tipos de variáveis. Por exemplo, a struct TPessoa poderia ter os campos nome (char[40]) e idade (int). A declaração genérica da estrutura é: struct TNome_do_tipo { //variável 1 //variável 2 //variável N } nome_instancia;
#include <stdio.h>
struct TUsuario /* struct TUsuario é o nome do tipo que está sendo criado */
{
char userID[20];
char senha[20];
} Usuario; /* aqui é definida uma variável do tipo struct TUsuario */
struct TUsuario TabelaUsuario[20];
main()
{
scanf("%s", Usuario.userID);
scanf("%s", Usuario.senha);
scanf("%s", TabelaUsuario[10].userID);
scanf("%s", TabelaUsuario[10].senha);
}
Neste exemplo, foi definido um tipo (modelo) para o registro (struct TUsuario) e foi criada uma variável chamada Usuario a partir deste tipo. Na sequência foi criada mais uma variável (um vetor de estruturas) chamada TabelaUsuario. Note que basta usar as palavras chave struct Usuario para criar novas variáveis. O tipo completo é definido uma única vez no início.
#include <stdio.h>
#define NUM_MAX 3
struct TAluno {
char nome[30];
char matricula[11];
float b1,b2,b3,b4;
} Turma[NUM_MAX];
void print_aluno(struct TAluno aux)
{
printf("Nome -> %s\n", aux.nome);
printf("Matrícula -> %s\n", aux.matricula);
printf("Bimestre 1 -> %f\n", aux.b1);
printf("Bimestre 2 -> %f\n", aux.b2);
printf("Bimestre 3 -> %f\n", aux.b3);
printf("Bimestre 4 -> %f\n", aux.b4);
}
main()
{
int i;
for(i=0;i<NUM_MAX;i++) {
printf("Entre com o nome do aluno\n");
scanf("%s", Turma[i].nome);
printf("Entre com a matrícula do aluno\n");
scanf("%s", Turma[i].matricula);
printf("Entre com a nota do bimestre 1\n");
scanf("%f", &Turma[i].b1);
printf("Entre com a nota do bimestre 2\n");
scanf("%f", &Turma[i].b2);
printf("Entre com a nota do bimestre 3\n");
scanf("%f", &Turma[i].b3);
printf("Entre com a nota do bimestre 4\n");
scanf("%f", &Turma[i].b4);
}
for(i=0;i<NUM_MAX;i++) {
printf("=========== Aluno %d ============\n", i);
print_aluno(Turma[i]);
}
}
O exemplo a seguir demonstra como se pode copiar uma variável struct para outra do mesmo tipo. #include <stdio.h>
struct THoras{
int hora;
int minuto;
int segundo;
};
struct THoras Ontem = {2,10,57};
void main()
{
struct THoras Hoje;
Hoje = Ontem;
printf("Hora hoje = %d, Minuto hoje = %d e Segundo hoje %d\n", Hoje.hora, Hoje.minuto, Hoje.segundo);
}
Vamos ver um exemplo com estruturas definidas dentro de estruturas: #include <stdio.h>
struct TEndereco{
char rua[50];
char numero[10];
};
struct TCidadao{
char nome[50];
char cpf[20];
struct TEndereco endereco;
int num_filhos;
};
void main()
{
struct TCidadao Cidadao;
printf("Entre com o nome\n");
scanf ("%s",Cidadao.nome);
printf("Entre com o cpf\n");
scanf ("%s",Cidadao.cpf);
printf("Entre a rua\n");
scanf ("%s",Cidadao.endereco.rua);
printf("Entre a numero\n");
scanf ("%s",Cidadao.endereco.numero);
printf("Entre com o número de filhos\n");
scanf ("%d",&Cidadao.num_filhos);
}
Como toda variável, é possível dar valores para uma variável do tipo struct definida no programa: #include <stdio.h>
struct TEndereco {
char rua[50];
int numero;
};
struct TCidadao{
char nome[50];
char cpf[20];
struct TEndereco endereco;
};
int main(void)
{
//Inicializando com parâmetros em sequencia (ordem tem que ser respeitada)
struct TCidadao CidadaoMaria = {"Maria","42342342234",{"Rua AlfaBeta",145}};
//Inicializando com parâmetros via campo (não é necessário respeitar qualquer ordem)
struct TCidadao CidadaoJose = {.cpf = "1234567890", .endereco.numero = 541,.nome = "Jose",.endereco.rua = "Rua GamaDelta"};
printf("Rua do cidadao %s = %s\n", CidadaoMaria.nome, CidadaoMaria.endereco.rua);
printf("Rua do cidadao %s = %s\n", CidadaoJose.nome, CidadaoJose.endereco.rua);
}
Se não for usado o operador "&" , um parâmetro que é estrutura será passado por cópia. Não apresentaremos agora a passagem por endereço pois necessita do conceita de ponteiro. Observe o exercício abaixo. #include <stdio.h>
struct TEndereco{
char rua[50];
char numero[10];
};
struct TCidadao{
char nome[50];
char cpf[20];
struct TEndereco endereco;
int num_filhos;
};
void print_struct (struct TCidadao aux)
{
printf("nome=%s cpf=%s\n", aux.nome, aux.cpf);
printf("endereço inicial do aux %p\n", &aux);
}
void main()
{
struct TCidadao Cidadao;
printf("Entre com o nome\n");
scanf ("%s",Cidadao.nome);
printf("Entre com o cpf\n");
scanf ("%s",Cidadao.cpf);
printf("Entre a rua\n");
scanf ("%s",Cidadao.endereco.rua);
printf("Entre a numero\n");
scanf ("%s",Cidadao.endereco.numero);
printf("Entre com o número de filhos\n");
scanf ("%d",&Cidadao.num_filhos);
print_struct(Cidadao);
printf("endereço inicial do Cidadao %p\n", &Cidadao);
}
|
Unions |
---|
Union é um recurso do C que permite declarar um conjunto de dados que irá ocupar um mesmo espaço. É bastante empregado quando se deseja economizar espaço ou não se tem certeza sobre qual tipo de dado deve ser armazenado para determinada instancia. No exemplo a seguir é criada uma struct chamada TProduto e dentro destra estrutura há uma área de detalhamento do produto que é de uso genérico, para alguns produtos há campos específicos para preenchimento e outros não se tem ao certo os detalhes, portanto fica um campo de uso geral.
#include <stdio.h>
struct TRoupeiro{
char cor[20];
int volume;
float peso;
};
struct TProduto{
int id;
char nome[20];
union {
struct TRoupeiro roupeiro;
char descricao_generica[sizeof(int)+sizeof(float)+20];
};
};
int main(void)
{
struct TProduto vaso_decorativo = {
.id = 2,.nome = "Vaso decorativo 1",
.descricao_generica = "em vidro - peça única"
};
struct TProduto guarda_roupas_solteiro = {
.id = 1,.nome = "Roupeiro 3 portas",
.roupeiro.cor = "CZ", .roupeiro.volume = 304,.roupeiro.peso = 50.0
};
printf("nome=%s, descrição=%s, cor=%s, volume=%d, peso=%f\n",
guarda_roupas_solteiro.nome,
guarda_roupas_solteiro.descricao_generica,
guarda_roupas_solteiro.roupeiro.cor,
guarda_roupas_solteiro.roupeiro.volume,
guarda_roupas_solteiro.roupeiro.peso
);
printf("nome=%s, descrição=%s, cor=%s, volume=%d, peso=%f\n",
vaso_decorativo.nome,
vaso_decorativo.descricao_generica,
vaso_decorativo.roupeiro.cor,
vaso_decorativo.roupeiro.volume,
vaso_decorativo.roupeiro.peso
);
}
|
Ponteiros
Ponteiros |
---|
A memória de um computador pode ser vista como um vetor de bytes. Neste espaço vimos a utilização de variáveis diversas que podem armazenar valores que podem ser obtidos do usuários, serem resultados de ariméticas e muitas outras operações. O ponteiro nada mais é que um tipo de dado igualmente armazenado em memória, porém este dado se refere a um endereço da memória, ou seja, a um outro objeto. Este recurso é muito útil para diversos propósitos, basta pensar na própria aplicação do conceito "endereço", imagine como seria localizar uma casa em uma cidade sem haver uma forma de endereçar e armazenar os endereços das casas. Explorando esta analogia, cada lote possui um endereço e pode ter um conteúdo de diferentes tipos como uma casa, um prédio ou um conjunto de lojas, enfim, trazendo para o C seria como os tipos int, char, vetores diversos, etc. Assim é a memória, cada byte possui um endereço. O tamanho da memória é definido pelo tamanho do barramento de endereços usado para acessá-la. Uma variável ocupa uma área da memória. Tipicamente uma variável to tipo char se utiliza de um byte. Já uma variável do tipo int pode (dependendo do sistema) usar 4 bytes contíguos.
Uma variável ponteiro tem como conteúdo um endereço. Portanto a variável ponteiro possui um endereço e contém um endereço como conteúdo. Este recurso é largamente utilizado para passar parâmetros como referência (ao invés de copiar uma variável quando se quiser processá-la em alguma função), bem como para algoritmos diversos que buscam formas mais otimizadas de executar operações. #include <stdio.h>
int main(void) {
// your code goes here
int i = 10;
int *p;
p = &i;
printf("\n &i=%x",&i);
printf("\n i=%=d",i);
printf("\n *p=%d",*p);
printf("\n p=%x",p);
printf("\n &p=%x",&p);
return 0;
}
Observe o programa abaixo. A variável p é um ponteiro para inteiro. Isto significa que ela pode armazenar um endereço de um inteiro. #include <stdio.h>
main()
{
int x;
int *p;
x=5;
printf("Valor de x antes = %d\n", x);
p = &x;
*p=10;
printf("Valor de x depois = %d\n", x);
printf("Valor de p = %p\n", p);
}
Observe que para se referenciar o conteúdo da posição de memória apontada por p deve-se usar o asterisco: *p
main()
{
int x=10;
int y, *p;
}
Complete o código para copiar o conteúdo de x para y, sem que qualquer variável apareçam no lado esquerdo de um sinal de atribuição. Ou seja, sem envolver diretamente x e y.
main()
{
int x,y,w,*p1,*p2;
x = 20;
w = 30;
p1 = &x;
p2 = &w;
y = *p1 + *p2;
}
main()
{
int x,y,w,*p1,*p2, *p3;
x = 20;
w = 30;
p1 = &x;
p2 = &w;
y = *p1 + w;
p3 = &y;
*p3 = *p3 + 10;
y = *p1 + *p2 + *p3;
}
#include <stdio.h>
void main()
{
int x,y;
int *p;
y=0;
p=&y;
x=*p;
x=4;
(*p)++;
x--;
(*p) += x;
printf("\ny=%d x=%d\n",y,x);
}
Os ponteiro para char são muito utilizados pois permitem apontar para strings. A ideia é que ele aponte para o primeiro caracter (char) da string. Veja o exemplo abaixo. #include <stdio.h>
main()
{
char x[10]="ifsc";
char *p;
p = &x[2];
printf("x[2] = %c\n", *p);
p = x;
printf("string %s\n", p);
while (*p!=0) {
printf("Endereco %p conteúdo %c\n", p,*p);
p++;
}
}
Neste foi usado o incremento de um ponteiro, o que implica em adicionar ao endereço armazenado em p uma quantidade relativa ao tamanho do tipo apontado. No caso é 1 (tamanho de um char é um byte).
main()
{
char x[10]="ifsc";
char *p, y;
p = x + 2;
y= *p;
}
#include <stdio.h>
main()
{
int x[10]= {0,1,2,3,4,5,6,7,8,9};
int *p;
int i;
p = x;
i=0;
while (i<10) {
printf(" endereco %p e conteudo %d\n", p, *p);
p++;
i++;
}
}
OBSERVE que p++ incrementa em 4 unidades.
Observe como podemos usar ponteiros na passagem de parâmetros. #include <stdio.h>
void str_cpy(char *pdest, char *pfonte)
{
while (*pfonte!=0) {
*pdest++ = *pfonte++;
}
*pdest = 0;
}
int str_len (char *p)
{
int i=0;
while (*p++!=0)
i++;
return i;
}
main()
{
char fonte[10]="ifsc";
char destino[10];
str_cpy(destino, fonte);
printf("string destino = %s\n", destino);
printf("tamanho de dest = %d\n", str_len(destino));
}
Um ponto interessante é que ponteiros permitem, na chamada de uma função, passar valores por referência: void alfa(int *p)
{
*p=10;
}
main()
{
int x;
x =5;
printf("Valor de x antes da chamada de alfa = %d\n", x);
alfa(&x);
printf("Valor de x depois da chamada de alfa = %d\n", x);
}
Um ponteiro para um ponteiro é como se você anotasse o endereço de um ponteiro na agenda que tem o endereço da casa do seu amigo. Pode-se declarar um ponteiro para ponteiro com a seguinte notação:
NOTE: Na linguagem C pode-se declarar ponteiros para ponteiros para ponteiros para ponteiros... e assim por diante. #include <stdio.h>
void main()
{
float fpi=3.1415, *pf, **ppf;
pf=&fpi; // pf armazena o endereco de fpi
ppf=&pf; // ppf armazena o endereco de pf
printf("\n%f", **ppf); // imprime o valor de fpi por ppf
printf("\n%f", *pf); // imprime o valor de fpi por pf
}
NOTE: Para acessar o valor apontado por um ponteiro para ponteiro, o operador asterisco deve ser aplicado duas vezes.
Como visto em aulas anteriores, variáveis ponteiros possuem como conteúdo um endereço. É perfeitamente possível construir vetores e matrizes de ponteiros.
#include <stdio.h>
int main()
{
int i;
char *vp[4];
char alfa[5]="IFSC";
char beta[5]="TELE";
char delta[5]="RAC";
char gamma[5]="CGER";
vp[0] = alfa;
vp[1] = beta;
vp[2] = delta;
vp[3] = gamma;
for(i=0;i<4;i++)
printf("%s\n", vp[i]);
}
Observe que vp é um vetor de ponteiros para char e cada elemento aponta para uma cadeia de caracteres.
Um bom exemplo de vetor de ponteiros é a passagem de parâmetros na linha de comando. Cada parâmetro é tratado como uma cadeia de caracteres apontada por um elemento do vetor argv. O número de parâmetros é passado em argc. Note que argv[0] aponta para uma string que indica o nome do programa.
#include <stdio.h>
main(int argc, char *argv[])
{
int i;
for (i=0;i<argc;i++) {
printf("%s\n", argv[i]);
}
printf("Numero de parametros passados = %d\n", argc-1); /* o primeiro é o nome do arquivo executavél" */
}
Ponteiros podem apontar para qualquer "objeto" de qualquer tipo. Vamos verificar como é possível apontar para uma estrutura: #include <stdio.h>
struct TRegistro {
char nome[20];
int idade;
} Tabela[4] = {
{"joao",18,},
{"maria",18,},
{"jose",19,},
{"lara",17,},
}
;
struct TRegistro *p;
main()
{
p = &Tabela[3]; /*p aponta para o registro 3 da tabela */
printf("O nome na posição 3 é %s e idade = %d\n", p->nome,p->idade);
}
NOTE que o uso de p->nome é uma alternativa ao uso de (*p).nome No primeiro caso pode-se ler: o campo nome do objeto que é apontado por p.
No exemplo a abaixo a função RetornarStruct() retorna um ponteiro para uma estrutura. O cuidadado que se deve ter é que a função não deveria apontar para uma estrutura que foi criada localmente na função! #include <stdio.h>
struct TRegistro {
char nome[20];
int idade;
} Tabela[4] = {
{"joao",18,},
{"maria",18,},
{"jose",19,},
{"lara",17,},
}
;
struct TRegistro *p;
struct TRegistro * RetornarStruct(int indice)
{
return &Tabela[indice];
}
main()
{
p = RetornarStruct(2); /*p aponta para o registro 3 da tabela */
printf("O nome na posição 2 é %s e idade = %d\n", p->nome,p->idade);
}
#include <stdio.h>
struct TRegistro {
char nome[20];
int idade;
} Tabela[4] = {
{"joao",18,},
{"maria",18,},
{"jose",19,},
{"lara",17,},
};
struct TRegistro *p;
void MudarStruct(struct TRegistro *p1, int indice)
{
Tabela[indice] = *p1;
}
main()
{
struct TRegistro aux = {"luisa",16};
MudarStruct(&aux,2);
p = &Tabela[2];
printf("O nome na posição 2 é %s e idade = %d\n", p->nome,p->idade);
}
Exercício: No programa acima construir uma função que imprime a Tabela usando ponteiros. A função deve receber como parâmetro um ponteiro para o início da tabela e o tamanho da tabela.
EXERCÍCIO 1: Implementar a função str_cat que concatena duas strings usando ponteiros. EXERCÍCIO 2: Ordenar valores de um vetor de inteiros passando por referencia o ponteiro para esse vetor. EXERCÍCIO 3: Implememtar um programa que recebe 3 parâmetros na linha de comando: dois números reais e um operador (char). Operador pode ser + ou menos. O programa deve mostrar o resultado da operação.
EXERCÍCIO 4: Implementar um programa chamado cmpcadeia que testa se duas strings passadas na linha de comando são iguais. O programa deve imprimir uma mensagem indicando se são iguais ou diferentes. Usar a função strcmp da biblioteca. Caso sejam passados mais ou menos que dois parâmetros o programa deve se encerrar mostrando uma indicão do tipo:
EXERCÍCIO 5: Renomeie o executável e veja seja a mensagem de erro mostra o nome correto do programa.
|
Trabalhando com funções
- Parâmetros de funções como valor
- Parâmetros de funções como referência
- Recursividade
- Cláusula Return
Mais sobre a função main()
Início e fim do programa |
---|
O programa inicia pela primeira instrução contida na função main() e também se encerra na última instrução. O retorno padrão da função main é um int que representa um código de erros reconhecidos por muitos sistemas operacionais. Se o programa terminou sua execução corretamente o retorno deverá ser 0 (zero). int main(void)
{
//Programa
return 0;
}
|
A função exit |
---|
Uma alternativa a terminação do programa chegando ao fim da função main é a função exit da biblioteca <stdlib.h>. Para esta função deve-se passar um argumento inteiro que tem o mesmo significado do código de retorno da função main, portanto exit(0) representa uma terminação normal, alternativamente exit(EXIT_SUCCESS). Para representar uma terminação anormal pode-se utilizar exit(EXIT_FAILURE). |
Os argumentos argc e argv |
---|
Os argumentos argc e argv A função main() pode ter parâmetros formais, mas o programador não pode escolhores quais serão eles. A declaração que se pode ter para a função main() é: int main (int argc, char *argv[]); Exemplo Escreva um programa que faça uso dos parâmentros argv e argc. O programa deverá receber da linha de comando o dia, mês e ano correntes (dd/mm/aaaa), e imprimir a data em formato apropriado. Veja o exemplo, supondo que o executável se chame data: $ data 07 06 2016 O programa deverá imprimir: $ 07 de junho de 2016
void main(int argc, char *argv[]) { int mes; char *nomemes [] = {"janeiro","fevereiro","março","abril","maio","junho","julho","agosto","setembro","outubro","novembro","dezembro"}; if(argc == 4) /* Testa se o numero de parametros fornecidos esta' correto o primeiro parametro e' o nome do programa, o segundo o dia o terceiro o mes e o quarto os dois ultimos algarismos do ano */ { mes = atoi(argv[2]); /* argv contem strings. A string referente ao mes deve ser transformada em um numero inteiro. A funcao atoi esta sendo usada para isto: recebe a string e transforma no inteiro equivalente */ if (mes<1 || mes>12) /* Testa se o mes e' valido */ printf("Erro!\nUso mes: mm, deve ser de 1 a 12.\n"); else printf("\n%s de %s de %s\n\n", argv[1], nomemes[mes-1],argv[3]); } else printf("Erro!\nUso: dd/mm/aaaa, devem ser inteiros, ou estão faltando.\n"); } |
Referências importantes
- Códigos de formatação do printf
- Ordem de precedência de operadores C
- Tabela ASCII (ISO 8859-1)
- Lista de Caracteres codificação UTF-8
Ferramentas úteis
- VisualG3: Uma IDE para desenvolvimento de programas em pseudocódigo (freeware), permite editar e compilar programas utilizando uma sintaxe própria de pseudocódigo muito parecida com a que trabalhamos em sala. Muito útil para verificar o funcionamento real dos algoritmos.
- LibreOffice: O LibreOffice é um programa gratuito (freeware) e de código aberto (opensource). Além de editor de textos, planilhas e apresentações tem a ferramenta Draw que permite a criação de fluxogramas.
- VirtualBox: O Oracle VirtualBox é um programa gratuito (freeware) que permite criar e instanciar máquinas virtuais. O uso de máquinas virtuais é bastante interessante quando desejamos ter diferentes sistemas operacionais em um computador bem como quando se está realizando ensaios e deseja-se isolar estes experimentos do sistema principal.
- Ubuntu: O Ubuntu é uma distribuição linux (freeware e opensource) bastante estável e com uma comunidade bastante ativa que está sempre atualizando o sistema e presente nos foruns e redes sociais para dirimir dúvidas.
- LinuxMint: O LinuxMint é uma distribuição linux (freeware e opensource) bastante estável e confortável aos usuários windows, pois traz um gerenciador de janelas configurado de uma forma mais natural para estes usuários e vem com um conjunto de programas pré-instalados que consegue atender a maior parte das demandas inicias.
Orientações para entrega dos trabalhos
- Para listas a serem entregues via moodle:
- Nome do arquivo: "seu nome completo/ demais colegas do grupo" - "lista de exercícios 1", "desafio 1", etc.
- Formato do arquivo em anexo: PDF (cada lista num único arquivo feito em editor de texto, exportado para PDF).
- Para listas a serem entregues por email (para cleber.amaral@ifsc.edu.br), período válido até a meia noite do prazo:
- Assunto do e-mail: "PRG29002 - xxx" onde xxx é "lista de exercicios 1", "desafio 1", etc.
- Nome do arquivo anexo: "seu nome completo/ demais colegas do grupo" - "lista de exercícios 1", "desafio 1", etc.
- Formato do arquivo em anexo: PDF (cada lista num único arquivo feito em editor de texto, exportado para PDF).
- Regra válida a partir de 14/04 (isento apenas trabalhos "lista 1")
Trabalhos entregues com atraso
- Para os trabalhos não entregues no prazo (não justificados) temos a penalidade de 1 ponto por dia de atraso
- Excepcionalmente para as lista1 e lista7 com até 6 dias de atraso terá desconto de 1 ponto apenas, seguindo a regra acima para entregas deste trabalho após este prazo
- Desafios não tem extensão de prazo, não adianta enviar se o prazo se esgotou
- Para o desafio1 o sistema de desconto por dia de atraso foi utilizado, este ficou como exceção
Eventos da área de desenvolvimento
- Maio de 2016 - Florianópolis TDC2016
- Outubro de 2016 - Rio de Janeiro QConRio2016
Horário de Monitoria
Sites úteis
- cplusplus.com: Traz tutoriais, artigos e descrições de funções C e C++
- codechef.com: Permite a edição, compilação e testes online de códigos em várias linguagens inclusive ANSI C
- codecademy.com: Tem cursos gratuitos de programação, bastante didáticos em inclusive em português. Porém não tem curso de C, uma alternativa interessante para quem quiser aprender uma outra linguagem que tem boa aceitação inclusive para desenvolvimento de sistemas embarcados é o Python
- kaggle.com: Site tem publicado centenas de algoritmos em diversas linguagens para resolver os mais variados problemas. Tem também competições de algoritmos
Projeto
O aluno deve propor ao professor um projeto de sua preferência que respeite os requisitos mínimos. Sendo aceito deverá desenvolver o projeto e apresentá-lo.
Requisitos mínimos
- Realizar acesso a arquivo, lendo e escrevendo informações
- Utilizar funções (ao menos duas sendo ao menos uma com argumentos)
- Apresentar menu utilizando switch case e conter laço infinito
- Aceitar argumento de entrada no programa
- Utilizar comentários
- Utilizar alguma biblioteca (além da stdio.h)
- Utilizar ao menos 3 dos seguintes recursos
- Utilizar diretivas de pré-compilação
- Utilizar Ponteiros
- Utilizar Structs ou Unions
- Utilizar alocação dinâmica de memória
Modelo
- Trabalho individual
Metodologia
- Apresentar a proposta de projeto ao professor
- Documentar o escopo do projeto utilizando descrição narrativa (descrição simples)
- Cenário
- Problema
- Dados de entrada e saída
- O planejamento do cronograma não será cobrado porém cabe ao aluno se organizar quanto ao tempo para entrega no prazo
- Desenvolver o projeto
- Apresentar individualmente ao professor
- Serão realizados testes diversos, arguido sobre o funcionamento, possibilidades de alterações, etc
Algumas ideias de projetos
- Sugestão geral: veja em outras disciplinas que processos podem ser automatizados e proponha um projeto que realiza esta tarefa como de cálculos diversos de eletrônica, de rádio transmissão, etc.
- Implementar o jogo Pedra, papel ou tesoura. Neste jogo dois ou mais jogadores em diferentes computadores devem rodar um aplicativo que fará a leitura de um arquivo compartilhado. O algoritmo deve tratar as etapas do jogo (Setup do aplicativo, entrada na sala, escolha da figura e apresentação do resultado)
- Implementar o jogo da velha escrevendo em arquivo. Neste jogo dois jogadores em diferentes computadores devem rodar um aplicativo que fará a leitura de um arquivo compartilhado. O algoritmo deve tratar as etapas do jogo (Setup do aplicativo, entrada na sala, seleção das casas e apresentação do resultado)
- Implementar controle de empréstimo de objetos. Neste software o usuário poderá digitar nomes de objetos que emprestou, a pessoa a quem emprestou e automaticamente o software guarda a data. Deve haver uma opção para gerar relatório dos itens emprestados e opção para marcar a devolução (podendo manter o registro em histórico ou apagando o registro).
- Implementar software gerador de lista de compras. Neste software o usuário poderá digitar itens de supermercado com nome e quantidade. O software escreve num arquivo que poderá depois ser impresso. O software também pode ter função de numa segunda execução já trazer a antiga listagem digitada e permitir que o usuário apenas selecione novas quantidades ou inclua novos itens.
- Implementar software para realização de cálculos de eletrônica. Neste software um menu apresenta várias opções de cálculo como de potencia através de tensão e corrente, como obtenção do valor de um resistor, como solução de equivalência de paralelo de vários resistores e outras. Num arquivo texto pode ser armazenado um histórico de operações realizadas.
- Implementação de software para apostas na mega sena. Neste software são dadas sugestões de números para apostas de acordo com o número do sorteio da mega sena. Com este histórico armazenado é possível então entrar com um número de sorteio e digitar quais foram os números verdadeiramente sorteados na loteria federal checagem os acertos.
Turma Conceitos Numéricos
Conceitos Individuais - Avaliações principais
Matrícula | A1 |
151002039-0 | 6 |
152000674-8 | 0 |
151001400-4 | 0 |
152000542-3 | 8 |
152001576-3 | 9 |
151006902-0 | 3 |
151005163-5 | 10 |
151005591-6 | 4 |
151003419-6 | 0 |
152000616-0 | 0 |
152000226-2 | 8 |
152000502-4 | 4 |
152001502-0 | 5 |
151001656-2 | 4 |
152000293-9 | 7 |
152000120-7 | 6 |
152006025-4 | 8 |
152000331-5 | 5 |
Consolidação - Avaliações principais
Conceito | A1 |
10 | 5% |
9 | 5% |
8 | 16% |
7 | 5% |
6 | 11% |
<=5 / Ausentes | 55% |
Conceitos Individuais - Avaliações secundárias
Matrícula | L1 | D1 | L2 | L3 | L4 | L5 | D2 | T8 |
151002039-0 | 10 | 6 | 0 | 0 | 8 | 0 | 0 | |
152000674-8 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | |
151001400-4 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
152000542-3 | 10 | 10 | 8 | 10 | 10 | 9 | 0 | |
152001576-3 | 6 | 10 | 3 | 0 | 10 | 10 | 10 | |
151006902-0 | 0 | 10 | 0 | 0 | 0 | 0 | 0 | |
151005163-5 | 0 | 6 | 0 | 0 | 0 | 0 | 0 | |
151005591-6 | 10 | 10 | 9 | 9 | 10 | 9 | 0 | |
151003419-6 | 8 | 0 | 3 | 10 | 6 | 0 | 0 | |
152000616-0 | 10 | 10 | 0 | 0 | 8 | 0 | 0 | |
152000226-2 | 6 | 10 | 0 | 0 | 0 | 0 | 0 | |
152000502-4 | 10 | 10 | 7 | 4 | 9 | 5 | 8 | |
152001502-0 | 10 | 10 | 10 | 10 | 8 | 8 | 0 | |
151001656-2 | 10 | 10 | 6 | 9 | 9 | 9 | 0 | |
152000293-9 | 10 | 10 | 4 | 0 | 9 | 10 | 0 | |
152000120-7 | 10 | 0 | 7 | 10 | 9 | 4 | 0 | |
152006025-4 | 10 | 10 | 5 | 10 | 7 | 0 | 0 | |
152000331-5 | 8 | 10 | 3 | 9 | 10 | 10 | 0 |
Turma Conceitos por Letras
Conceitos Individuais - Avaliações principais
Matrícula | A1 |
142003344-1 | D |
141005012-2 | 0 |
142001814-0 | D |
142001213-4 | D |
142002143-5 | B |
142001834-5 | 0 |
142003393-0 | 0 |
142001425-0 | 0 |
132005743-8 | D |
121003322-4 | X |
Consolidação - Avaliações principais
Conceito | A1 |
A | 0% |
B | 10% |
C | 0% |
D | 40% |
Ausentes | 50% |
Conceitos Individuais - Avaliações secundárias
Matrícula | L1 | D1 | L2 | L3 | L4 | L5 | T7 | T8 |
142003344-1 | C | A | D | X | X | X | X | |
141005012-2 | X | X | X | X | X | X | X | |
142001814-0 | A | X | C | C | C | X | X | |
142001213-4 | C | A | X | D | X | B | X | |
142002143-5 | C | A | X | X | B | C | X | |
142001834-5 | X | X | X | X | X | X | X | |
142003393-0 | X | X | X | X | X | X | X | |
142001425-0 | X | X | X | X | X | X | X | |
132005743-8 | X | X | X | X | X | X | X | |
121003322-4 | X | C | X | X | X | X | X |
Critério de conversão Numérico x Letra
- A: 9,0 a 10,0
- B: 7,5 a 8,9
- C: 6,0 a 7,4
- D: 0,0 a 5,9