Month: August 2018

parte 5 – gestão dinâmica de memória (lista ligada)

Principal vantagem de se usar lista ligada: flexibilidade

O acesso é sequencial, em que cada estrutura contém: os campos e um ponteiro para o próximo elemento da lista
operações com listas ligadas:
1) criar a lista
2) verificar se está vazia
3) pesquisar/lustar
4) adicionar um elemento
5) retirar um elemento
6) destruir a lista

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TAM 100


typedef struct objeto livro, *plivro;

struct objeto{
    char titulo[TAM], autor[TAM];
    int cota;
    plivro prox; //ponteiro para o proximo elemento da lista
};


//
int lista_vazia(plivro p);
plivro insere_inicio(plivro p);
plivro insere_final(plivro p);
plivro insere_ordenado(plivro p);
void mostra(plivro p);
plivro elimina(plivro p);
void destruir(plivro p);
plivro ler_ficheiro(plivro p);
void guarda_ficheiro(plivro p);

//2) verificar se está vazia
int lista_vazia(plivro p){
    if(p==NULL){
        return 1;
    }else{
        return 0;
    }
}

int menu(){
    int i;
    puts("1 - adiciona livro - inicio");
    puts("2 - adiciona livro - final");
    puts("3 - adiciona livro - ordenado");
    puts("4 - elimina livro");
    puts("5 - lista livros");
    puts("6 - esvaziar a lista");
    puts("7 - carregar lista de um ficheiro");
    puts("8 - terminar");
    puts("Escolha uma opcao: ");
    
    do{
        scanf(" %d", &i);
    }while(i <0 || i >8);
    
    return i;
}

plivro insere_inicio(plivro p){
    plivro novo;
    novo = malloc(sizeof(livro)); //aponta para um qq espaço em memória
    
    if(novo == NULL){
        printf("\nerro: alocacao de memoria para esta tarefa de insere_inicio");
        return p;
    }else{
        printf("Titulo: ");
        scanf(" %99[^\n]", novo->titulo);
        printf("Autor: ");
        scanf(" %99[^\n]", novo->autor);
        printf("Cota: ");
        scanf("%d", &novo->cota);
               
        //surge agora uma parelha obrigatória
        novo->prox=p; //aponto o novo para a primeira posição
        p=novo; //a primeira posição é o novo
                
        return p;
    }
    free(novo);
}

plivro insere_final(plivro p){
    plivro novo, aux;
    novo = malloc(sizeof(livro)); //aponta para um espaço em memoria
    if(novo == NULL){
        printf("\nerro: alocacao de memoria para esta tarefa de insere_inicio");
        return p;
    }else{
        printf("Titulo: ");
        scanf(" %99[^\n]", novo->titulo);
        printf("Autor: ");
        scanf(" %99[^\n]", novo->autor);
        printf("Cota: ");
        scanf("%d", &novo->cota);
        novo->prox=NULL;
        
        //se estiver vazio, insere no inicio
        if(p == NULL){
            p = novo;
        }else{
        //se já tiver pelo menos um elemento
            aux=p;
            while(aux->prox != NULL){
                aux = aux->prox;
            }
            aux->prox = novo;
        }
        return p;
    }
    free(novo);
}

plivro insere_ordenado(plivro p){
     plivro novo, aux;
    novo = malloc(sizeof(livro)); //aponta para um espaço em memoria
    if(novo == NULL){
        printf("\nerro: alocacao de memoria para esta tarefa de insere_inicio");
        return p;
    }else{
        printf("Titulo: ");
        scanf(" %99[^\n]", novo->titulo);
        printf("Autor: ");
        scanf(" %99[^\n]", novo->autor);
        printf("Cota: ");
        scanf("%d", &novo->cota);
        novo->prox=NULL;
        
        //se estiver vazio
        if(p == NULL || strcmp(novo->titulo, p->titulo) < 0){
        //if(p == NULL || novo->cota < p->cota){
            novo->prox = p;
            p = novo;
        }else{
        //se já tiver pelo menos um elemento
            aux=p;
             while(aux->prox != NULL && strcmp(novo->titulo, aux->titulo) >0){
             //while(aux->prox != NULL && novo->cota > aux->cota){
                aux = aux->prox;
            }
            novo->prox = aux->prox;
            aux->prox = novo;
        }
        return p;
    }
    
    free(novo);

}


void mostra(plivro p){
    
    if(p==NULL){
        printf("\nerro: lista vazia, sem elementos para listar!\n\n");
    }else{
    while(p!=NULL){
        printf("%s\t%s\t%d\n", p->titulo, p->autor, p->cota);
        p = p->prox;
    }
    }
}


plivro elimina(plivro p){
    int apaga;
    plivro atual, anterior=NULL;
    
    atual= p;
    
    if(p==NULL){
        printf("\nerro: lista vazia sem informacao\n");
        return p;
    }else{
        mostra(p);
        printf("qual o livro e cota que pretende eliminar?");
        scanf("%d", &apaga);
        while(atual!=NULL && atual->cota != apaga){
            anterior = atual;
            atual = atual->prox;
        }
        if(anterior ==NULL){
            p = atual->prox;
        }else{
            anterior->prox = atual->prox;
        }
    free(atual);
    return p;
    }
}

void destruir(plivro p){
    plivro aux;
    
    if(p==NULL){
        printf("\nerro: nada para apagar!\n");
    }
    
    while(p!=NULL){
        aux = p;
        p=p->prox;
        free(aux);
    }

}

plivro ler_ficheiro(plivro p){
    FILE *f;
    plivro novo=NULL;
        
    if(p!=NULL){
        printf("\nerro: lista ja preenchida\n");
        return p;
    }else{
    
    f = fopen("listaLivros.dat", "rb");
    if(f==NULL){
        printf("\n erro no acesso ao ficheiro \n");
        return p;
    }else{
       
       while(feof(f) == 0){
            novo = malloc(sizeof(livro));
            fread(novo, sizeof(livro), 1, f);
            novo->prox = p;
            p = novo; //erro aqui
        }
    }
    }
    free(novo);
    fclose(f);
    return p;
}

void guarda_ficheiro(plivro p){
    FILE *f;
    
    f = fopen("listaLivros.dat", "wb");
    if(f==NULL){
        printf("\n erro no acesso ao ficheiro \n");
        return;
    }else{
        while(p != NULL){
        fwrite(p, sizeof(livro), 1, f);
        p=p->prox;
        }
        fclose(f);
        free(p);
    }
}


int main() {
    int escolha;
    plivro lista = NULL; //1) criar a lista
    
    if(lista_vazia(lista)==1){
    do{
        escolha = menu();
        switch(escolha){
            case 1: lista = insere_inicio(lista); break;
            case 2: lista = insere_final(lista); break;
            case 3: lista = insere_ordenado(lista); break;
            case 4: lista = elimina(lista); break;
            case 5: mostra(lista); break;
            case 6: destruir(lista); break;
            case 7: lista= ler_ficheiro(lista); break;
        }
    
    }while(escolha != 8);
    }else{
        printf("nao foi possivel inicializar!");
    }

    guarda_ficheiro(lista);
    return 0;
}



Tags : , ,

parte 4 – ficheiros (ainda…)

falta rever a situação de:
ftell –> exemplo ftell(f)/sizeof(struct pessoa) -> diz-me por exemplo quantas pessoas estão no ficheiro
fseek
SEEK_CUR
SEEK_END
SEEK_SET

Tags : , ,

parte 4 – ficheiros (texto)

O trabalho com ficheiros de texto já é um pouco diferente

notas acerca dos ficheiros de texto:
leitura de espaços vazios ou tabs é a mesma coisa

#include <stdio.h>
#include <stdlib.h>

/*
//exemplo do ficheiro de texto
Ana Mendes
3 5 7 12 20 1 3

Marcia Dantas
1	2	3	4	5	6	7
 */


int main() {
    FILE *f;
    char nome[100];
    f = fopen("ex3_dados.txt", "r");
    int i, lista[7];
    
    if(f != NULL){
           while(feof(f) == 0){
            fscanf(f, " %[^\n] ", nome);        
            printf("%s \n", nome);
            for(i=0; i< 7; i++){
                fscanf(f, "%d", &lista[i]);   
            }
            for(i=0; i< 7; i++){
                printf("%d ", lista[i]);   
            }
            //printf("\n");
            putchar('\n');
        }
    }else{
        printf("\n o ficheiro nao foi encotnrado!");
    }
    return 0;
}


Para trabalhar com o exemplo do banco e clientes, mas desta vez com ficheiros de texto, sem guardar o total de registos. Não consegui resolver a situação de ler ficheiros como deve ser..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TAM 5


/*
 //exemplo do conteudo do ficheiro de texto
 nome: pedro	Nº conta: 1	Saldo: 100
 */

typedef struct dados{
    char numeroConta[15];
    char nome[50];
    int montante;
} cliente;


int menu(){
    int i;
    puts("1 - adiciona cliente");
    puts("2 - elimina cliente");
    puts("3 - lista clientes");
    puts("4 - mostra mais rico");
    puts("5 - terminar");
    puts("Escolha uma opcao: ");
    
    do{
        scanf(" %d", &i);
    }while(i <0 || i >5);
    
    return i;
}

cliente escreve_cliente(){
    cliente t;
    printf("Qual o numero da conta?");
    scanf(" %14s", t.numeroConta);
    printf("Qual o nome?");
    scanf(" %99[^\n]", t.nome);
    printf("Qual o montante?");
    scanf("%d", &(t.montante));
    
    return t;
}

void adiciona_cliente(cliente tabC[], int *totalC){
    
    if(*totalC>=TAM){
        printf("tabela de cliente cheia");
    }else{
        tabC[*totalC] = escreve_cliente();
        (*totalC)++;
    }
}

void mostra_todos(cliente tab[], int totalC){
    if(totalC==0){
        printf("nao existem clientes\n");
    }else{
    for(int i=0; i< totalC; i++){
        printf("%s \t %s \t %d \n", tab[i].numeroConta, tab[i].nome, tab[i].montante);
    }
    }
}



void procura_mais_rico(cliente tab[], int totalC){
    cliente maiorT;
    
    int aux=0, i=0;
    if(totalC==0){
        printf("nao existem clientes\n");
    }else{
        maiorT.montante = tab[i].montante;
        for(; i< totalC; i++){
            if(tab[i].montante > maiorT.montante ){
                aux = i;
            }
        }
        printf("\no maior vem %d:\n" , aux);
        printf("%s \t %s \t %d \n", tab[aux].numeroConta, tab[aux].nome, tab[aux].montante);
    
    }
}


void elimina_cliente(cliente tab[], int *totalC){
    char st[15];
    int i;
    
    printf("Qual o numero da conta a eliminar? (%d)", *totalC);
    scanf(" %14s", st);
    
    if(totalC<0){
        printf("nao existem clientes. nao se pode eliminar nada\n");
    }else{
        for(i=0; i < *totalC && strcmp(st, tab[i].numeroConta)!=0; i++) //serve para posicionar o i quando encontrei
            ;
        
        if(i==*totalC){
            printf("cliente nao existe\n");
        }else{
            tab[i]=tab[*totalC-1]; //serve para arrastar o ultimo para a posição atual
            (*totalC)--; 
        }
        }
}
    
void guarda_dados_texto(cliente *b, int total){
    FILE *f;
    
    f = fopen("bancoBinario2.txt", "wt");
    if(f==NULL){
        printf("\n erro no acesso ao ficheiro \n");
        return;
    }else{
        for(int i=0; i < total; i++){
            fprintf(f, "nome: %s\tN.conta: %s\tSaldo: %d\n", b[i].nome, b[i].numeroConta, b[i].montante);
        }
        fclose(f);
    }
}


int ler_dados_texto(cliente *b){
    FILE *f;
    int total=0;
    
    f = fopen("bancoBinario2.txt", "r");
    if(f==NULL){
        printf("\n erro no acesso ao ficheiro \n");
        return 0;
    }else{
        while(feof(f) == 0){
            printf("\nvou ler");
            fscanf(f, " %[^\n] %[^\n] %[^\n]", b[total].nome, b[total].numeroConta, &b[total].montante);
            total++;
        }
        fclose(f);
        return total;
    }
}

int main() {
    printf("estruturas\n");
    int totalClientes=0, escolha;
    cliente Banco[TAM];
    
    totalClientes = ler_dados_texto(Banco);
    printf("\n\n%d\n\n", totalClientes);
    
    do{
        escolha = menu();
        switch(escolha){
            case 1: adiciona_cliente(Banco,&totalClientes); break;
            case 2: elimina_cliente(Banco,&totalClientes); break;
            case 3: mostra_todos(Banco,totalClientes); break;
            case 4: procura_mais_rico(Banco,totalClientes); break;
        }
    
    }while(escolha != 5);
    
    guarda_dados_texto(Banco, totalClientes);
    
    return 0;
}
Tags : , ,

parte 4 – ficheiros (binários)

Existem dois tipos de ficheiros: binários e de texto
se for feito uso de um ficheiro binário é recomendável que se guarde o numero de estruturas logo no inicio do ficheiro e de seguida as estruturas

versão light onde indico qual o numero de estruturas que existem e que vão ser guardadas no ficheiro


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TAM 5

typedef struct dados{
    char numeroConta[15];
    char nome[50];
    int montante;
} cliente;


int menu(){
    int i;
    puts("1 - adiciona cliente");
    puts("2 - elimina cliente");
    puts("3 - lista clientes");
    puts("4 - mostra mais rico");
    puts("5 - terminar");
    puts("Escolha uma opcao: ");
    
    do{
        scanf(" %d", &i);
    }while(i <0 || i >5);
    
    return i;
}

cliente escreve_cliente(){
    cliente t;
    printf("Qual o numero da conta?");
    scanf(" %14s", t.numeroConta);
    printf("Qual o nome?");
    scanf(" %99[^\n]", t.nome);
    printf("Qual o montante?");
    scanf("%d", &(t.montante));
    
    return t;
}

void adiciona_cliente(cliente tabC[], int *totalC){
    
    if(*totalC>=TAM){
        printf("tabela de cliente cheia");
    }else{
        tabC[*totalC] = escreve_cliente();
        (*totalC)++;
    }
}

void mostra_todos(cliente tab[], int totalC){
    if(totalC==0){
        printf("nao existem clientes\n");
    }else{
    for(int i=0; i< totalC; i++){
        printf("%s \t %s \t %d \n", tab[i].numeroConta, tab[i].nome, tab[i].montante);
    }
    }
}



void procura_mais_rico(cliente tab[], int totalC){
    cliente maiorT;
    
    int aux=0, i=0;
    if(totalC==0){
        printf("nao existem clientes\n");
    }else{
        maiorT.montante = tab[i].montante;
        for(; i< totalC; i++){ if(tab[i].montante > maiorT.montante ){
                aux = i;
            }
        }
        printf("\no maior vem %d:\n" , aux);
        printf("%s \t %s \t %d \n", tab[aux].numeroConta, tab[aux].nome, tab[aux].montante);
    
    }
}


void elimina_cliente(cliente tab[], int *totalC){
    char st[15];
    int i;
    
    printf("Qual o numero da conta a eliminar? (%d)", *totalC);
    scanf(" %14s", st);
    
    if(totalC<0){
        printf("nao existem clientes. nao se pode eliminar nada\n");
    }else{
        for(i=0; i < *totalC && strcmp(st, tab[i].numeroConta)!=0; i++) //serve para posicionar o i quando encontrei
            ;
        
        if(i==*totalC){
            printf("cliente nao existe\n");
        }else{
            tab[i]=tab[*totalC-1]; //serve para arrastar o ultimo para a posição atual
            (*totalC)--; 
        }
        }
}
    
void guarda_dados_binario(cliente *b, int totalC){
    FILE *f;
    
    f = fopen("bancoBinario.bin", "wb");
    if(f==NULL){
        printf("\n erro no acesso ao ficheiro \n");
        return;
    }else{
    
        fwrite(&totalC, sizeof(int), 1, f);
        fwrite(b, sizeof(cliente), totalC, f);
        fclose(f);
    }
}


int ler_dados_binario(cliente *b){
    FILE *f;
    int total;
    
    f = fopen("bancoBinario.bin", "rb");
    if(f==NULL){
        printf("\n erro no acesso ao ficheiro \n");
        return 0;
    }else{
    
        fread(&total, sizeof(int), 1, f);
        fread(b, sizeof(cliente), total, f);
        fclose(f);
        return total;
    }
}

int main() {
    printf("estruturas\n");
    int totalClientes=0, escolha;
    cliente Banco[TAM];
    
    totalClientes = ler_dados_binario(Banco);
    
    do{
        escolha = menu();
        switch(escolha){
            case 1: adiciona_cliente(Banco,&totalClientes); break;
            case 2: elimina_cliente(Banco,&totalClientes); break;
            case 3: mostra_todos(Banco,totalClientes); break;
            case 4: procura_mais_rico(Banco,totalClientes); break;
        }
    
    }while(escolha != 5);
    
    guarda_dados_binario(Banco, totalClientes);
    
    return 0;
}

versão hardcore onde NAO indico qual o numero de estruturas que existem e que vão ser guardadas no ficheiro

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TAM 5

typedef struct dados{
    char numeroConta[15];
    char nome[50];
    int montante;
} cliente;


int menu(){
    int i;
    puts("1 - adiciona cliente");
    puts("2 - elimina cliente");
    puts("3 - lista clientes");
    puts("4 - mostra mais rico");
    puts("5 - terminar");
    puts("Escolha uma opcao: ");
    
    do{
        scanf(" %d", &i);
    }while(i <0 || i >5);
    
    return i;
}

cliente escreve_cliente(){
    cliente t;
    printf("Qual o numero da conta?");
    scanf(" %14s", t.numeroConta);
    printf("Qual o nome?");
    scanf(" %99[^\n]", t.nome);
    printf("Qual o montante?");
    scanf("%d", &(t.montante));
    
    return t;
}

void adiciona_cliente(cliente tabC[], int *totalC){
    
    if(*totalC>=TAM){
        printf("tabela de cliente cheia");
    }else{
        tabC[*totalC] = escreve_cliente();
        (*totalC)++;
    }
}

void mostra_todos(cliente tab[], int totalC){
    if(totalC==0){
        printf("nao existem clientes\n");
    }else{
    for(int i=0; i< totalC; i++){
        printf("%s \t %s \t %d \n", tab[i].numeroConta, tab[i].nome, tab[i].montante);
    }
    }
}



void procura_mais_rico(cliente tab[], int totalC){
    cliente maiorT;
    
    int aux=0, i=0;
    if(totalC==0){
        printf("nao existem clientes\n");
    }else{
        maiorT.montante = tab[i].montante;
        for(; i< totalC; i++){
            if(tab[i].montante > maiorT.montante ){
                aux = i;
            }
        }
        printf("\no maior vem %d:\n" , aux);
        printf("%s \t %s \t %d \n", tab[aux].numeroConta, tab[aux].nome, tab[aux].montante);
    
    }
}


void elimina_cliente(cliente tab[], int *totalC){
    char st[15];
    int i;
    
    printf("Qual o numero da conta a eliminar? (%d)", *totalC);
    scanf(" %14s", st);
    
    if(totalC<0){
        printf("nao existem clientes. nao se pode eliminar nada\n");
    }else{
        for(i=0; i < *totalC && strcmp(st, tab[i].numeroConta)!=0; i++) //serve para posicionar o i quando encontrei
            ;
        
        if(i==*totalC){
            printf("cliente nao existe\n");
        }else{
            tab[i]=tab[*totalC-1]; //serve para arrastar o ultimo para a posição atual
            (*totalC)--; 
        }
        }
}
    
void guarda_dados_binario(cliente *b, int total){
    FILE *f;
    
    f = fopen("bancoBinario2.bin", "wb");
    if(f==NULL){
        printf("\n erro no acesso ao ficheiro \n");
        return;
    }else{
    
        fwrite(b, sizeof(cliente), total, f);
        fclose(f);
    }
}


int ler_dados_binario(cliente *b){
    FILE *f;
    int total=0;
    cliente aux;
    
    f = fopen("bancoBinario2.bin", "rb");
    if(f==NULL){
        printf("\n erro no acesso ao ficheiro \n");
        return 0;
    }else{
           
        fread(&aux, sizeof(cliente), 1, f);
        
        while(feof(f) == 0){
            b[total++]= aux;
            fread(&aux, sizeof(cliente), 1, f);
        }
        
        fclose(f);
        return total;
    }
}

int main() {
    printf("estruturas\n");
    int totalClientes=0, escolha;
    cliente Banco[TAM];
    
    totalClientes = ler_dados_binario(Banco);
    
    do{
        escolha = menu();
        switch(escolha){
            case 1: adiciona_cliente(Banco,&totalClientes); break;
            case 2: elimina_cliente(Banco,&totalClientes); break;
            case 3: mostra_todos(Banco,totalClientes); break;
            case 4: procura_mais_rico(Banco,totalClientes); break;
        }
    
    }while(escolha != 5);
    
    guarda_dados_binario(Banco, totalClientes);
    
    return 0;
}
Tags : , ,

parte 3 – estruturas

notas acerca das estruturas:

criar um novo tipo struct dados: 1º criar as variáveis, 2º declarar as variáveis

1º criar as variáveis

struct dados {
char nome[TAM];
char nconta[15];
int montate;
};

2º declarar as variáveis

struct dados m;

ou

Cliente b;

para aceder aos campos faz-se uso do ponto final -> m.nome
associar um novo nome à estrutura: typedef declaração-do-tipo sinónimo;

typdef struct dados cliente;

estruturas encadeadas:

struct data{
int dia, mes, ano;
};

struct dados{
char nome[TAM];
char nconta[15];
int montate;
};

notas acerca das estruturas:
operador de atribuição só para estruturas do mesmo tipo (faz copia em bloco ao invés de um a um)
comparação é sempre feita campo a campo
ponteiros e estruturas (*p).c equivalente a p->c
construir um vetor de estururas, struct dados clientes[30];
para calcula a dimensão de um vetor faz-se uso do sizeof(clientes) ou sizeof(struct dados) *30

exemplo clássico de trabalho com estruturas, sendo que o eliminar foi construído da seguinte forma:
mover o ultimo para a posição a eliminar e actualizar o total de posições

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TAM 5

typedef struct dados{
    char numeroConta[15];
    char nome[50];
    int montante;
} cliente;


int menu(){
    int i;
    puts("1 - adiciona cliente");
    puts("2 - elimina cliente");
    puts("3 - lista clientes");
    puts("4 - mostra mais rico");
    puts("5 - terminar");
    puts("Escolha uma opcao: ");
    
    do{
        scanf(" %d", &i);
    }while(i <0 || i >5);
    
    return i;
}

cliente escreve_cliente(){
    cliente t;
    printf("Qual o numero da conta?");
    scanf(" %14s", t.numeroConta);
    printf("Qual o nome?");
    scanf(" %99[^\n]", t.nome);
    printf("Qual o montante?");
    scanf("%d", &(t.montante));
    
    return t;
}

void adiciona_cliente(cliente tabC[], int *totalC){
    
    if(*totalC>=TAM){
        printf("tabela de cliente cheia");
    }else{
        tabC[*totalC] = escreve_cliente();
        (*totalC)++;
    }
}

void mostra_todos(cliente tab[], int totalC){
    if(totalC==0){
        printf("nao existem clientes\n");
    }else{
    for(int i=0; i< totalC; i++){
        printf("%s \t %s \t %d \n", tab[i].numeroConta, tab[i].nome, tab[i].montante);
    }
    }
}



void procura_mais_rico(cliente tab[], int totalC){
    cliente maiorT;
    
    int aux=0, i=0;
    if(totalC==0){
        printf("nao existem clientes\n");
    }else{
        maiorT.montante = tab[i].montante;
        for(; i< totalC; i++){
            if(tab[i].montante > maiorT.montante ){
                aux = i;
            }
        }
        printf("\no maior vem %d:\n" , aux);
        printf("%s \t %s \t %d \n", tab[aux].numeroConta, tab[aux].nome, tab[aux].montante);
    
    }
}


void elimina_cliente(cliente tab[], int *totalC){
    char st[15];
    int i;
    
    printf("Qual o numero da conta a eliminar? (%d)", *totalC);
    scanf(" %14s", st);
    
    if(totalC<0){
        printf("nao existem clientes. nao se pode eliminar nada\n");
    }else{
        for(i=0; i < *totalC && strcmp(st, tab[i].numeroConta)!=0; i++) //serve para posicionar o i quando encontrei
            ;
        
        if(i==*totalC){
            printf("cliente nao existe\n");
        }else{
            tab[i]=tab[*totalC-1]; //serve para arrastar o ultimo para a posição atual
            (*totalC)--; 
        }
        }
}
    


int main() {
    printf("estruturas\n");
    int totalClientes=0, escolha;
    cliente Banco[TAM];
    
    do{
        escolha = menu();
        switch(escolha){
            case 1: adiciona_cliente(Banco,&totalClientes); break;
            case 2: elimina_cliente(Banco,&totalClientes); break;
            case 3: mostra_todos(Banco,totalClientes); break;
            case 4: procura_mais_rico(Banco,totalClientes); break;
        }
    
    }while(escolha != 5);
    
    return 0;
}



Tags : , ,

parte 2 – ponteiros (ou apontador)

notas acerca dos ponteiros, ou apontadores (aceder indirectamente a variáveis, através da sua localização):

Utilizar ponteiros para estabelecer a comunicação entre funções, se pretendo alterar o valor de uma variável dentro de uma função, tenho que passar como argumento um ponteiro para a variável e não uma copia do seu valor;

declaração: tipo *nome_ptr;

inicialização: tipo *nome_ptr = %qualquercoisaInt;

dois operadores:
& : obter o endereço de uma variável
* : aceder à variável para onde um ponteiro aponta

= : permite a atribuição entre ponteiros

notasM: quando faço p = &j; //estou a alterar o valor que está em j

notas acerca dos arrays (vetores):

[propriedade 1]

num array uni-dimensional a[i] ou *(a+i) é a mesma coisa. representam o primeiro elemento

[propriedade 2]

aritmética -> (p+i) ou (p-i) estou a deslocar posições dentro de um array

p+i equivalente a &a[i]

a[i] equivalente *(a+i)

declaração de uma função que recebe um vetor como argumento:
tipo funcao(tipo_de_vetor vetor[dimensao])
tipo funcao(tipo_de_vetor vetor[])
tipo funcao(tipo_de_vetor *vetor)

o uso da função é feito com nome do vector APENAS!

STRINGS

puts() //escreve strings <=> putchar()

strlen() //conta caracteres

strcat() //junta strings

tentar clearerr(stdin);

ao invés de usarmos array de caracteres (char st[TAM]) podemos usar ponteiro para carácter (char *p), vantagem? espaço em memória! Mas só funciona se as strings forem constantes.

como resolver isto?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TAM 4

void mostra1(char **vB){

    for(int i=0; i<TAM; i++){
        puts(vB[i]);
    }

}

void mostra2(char *vA){

    for(int i=0; i<TAM; i++){
        //puts( vA[i]);
        //printf("%d\n", vA[i]);
    }

}

int main() {
    
    char vetorA[TAM][10]={"pedro","andre","maria","carlos"};
    char *vetorB[]={"portugal","espanha","marrocos","franca"};

    mostra1(vetorB);
    puts(vetorA[1]);
    mostra2(vetorA[TAM]);
    
    return (0);
}


ainda sobre o strcmp e para relembrar
se == 0, significa que são iguais
se < 0, a primeira é mais pequena que a segunda se > 0, a segunda é maior do que a segunda

Tags : , ,

Mais um livro a ter em conta…

Mais um livro a ter em conta Think Like A Game Designer – The Step-By-Step Guide To Unlocking Your Creative Potential de Justin Gary. Apesar de não ser explicitamente para videojogos, fala sobre o assunto de gamedesign. Vou tentar aceder a qualquer coisa e ao índice e verificar se vale a pena.

(07/09/2020) e acho que vale a pena, já que encontrei uma parte do livro de acesso gratuito e do qual consta o seguinte “If you’re interested in learning how to make games, or even if you already do and just want to do it better, this book’s for you“, e “A game designer uses the interaction of players and rules to create an experience for the audience“, e “to become a great game designer: 1. Play lots of games. 2. Watch people play lots of games. 3. Bring awareness to the emotions that arise during play.”…

+infos(oficial): https://www.thinklikeagamedesigner.com/

Tags : , ,

Livros interessantes… (e que gostava de ter acesso)

Resonant Games Design Principles for Learning Games that Connect Hearts, Minds, and the Everyday de Eric Klopfer, Jason Haas, Scot Osterweil and Louisa Rosenheck (LINK)

Future Gaming Creative Interventions in Video Game Culture de Paolo Ruffino (LINK)

Connected Gaming What Making Video Games Can Teach Us about Learning and Literacy de Yasmin B. Kafai and Quinn Burke (LINK)

How Games Move Us Emotion de Design de Katherine Isbister (LINK)

e estudos compilados em livros:

Handbook of Computer Game Studies de Joost Raessens and Jeffrey Goldstein (LINK)

Video Games Around the World de Mark J. P. Wolf (LINK)

Computer Games and the Social Imaginary de Graeme Kirkpatrick (LINK)

Computer Games: Text, Narrative and Play de Diane Carr, David Buckingham, Andrew Burn e Gareth Schott (LINK)

Tags : , ,

Como espalhar a noticia acerca do tal videojogo..

Um gráfico que mostra algumas dicas acerca do desenvolvimento de uma das etapas importantes acerca do desenvolvimento de um videojogo..

Tags : ,

O que fazer para dar vida ao tal videojogo

Mais um gráfico que ilustra algumas ideias acerca do que fazer quando se pretende desenvolver um videojogo…

Tags : , ,

Perspectivas de num videojogo

Uma gráfico acerca das perspectivas de um videojogo..

Tags : ,

Entrevista a uma editora de videojogos: Cereal Games

Tags : ,

Um exemplo de uma storyboard

encontrei um exemplo real de uma storyboard, de um jogo em desenvolvimento onde se devem fazer opções ao longo do percurso

Tags : ,

curso: 3D for Games (em Lisboa)

“Dia 8 de Outubro abre o Programa 3D for Games. Vais ter a oportunidade de aprender Modelação, Escultura, Texturas, Iluminação e Render especialmente direcionadas para videojogos.”

+infos(oficial): http://www.odd-school.com/

+infos(rede social): https://www.facebook.com/oddschool/

Tags : , , ,

+Dicas acerca do desenvolvimento de videojogos

Não encontrei o nome do autor do post onde li algumas informações acerca de factos e dicas relacionados com o desenvolvimento de videojogos.

Coisas que afectam normalmente o sucesso de um videojogo..
Lack of creativity and innovative appeal
Interesting monetization tactics
Banal features and lack of engaging elements
Poor user acquisition
Complicated or confusing game play

dicas:
1) Research to outsmart the competition
2) Determine the game platform
3) UI/UX Design should be a stunner
4) Create addictive stories
5) Create social engagement
6) Hook users with sensational sound effects
7) Don’t prioritize Monetization
8) Practice relentless testing standards
9) Introduce frequent updates
10) Be creative and proactive for Marketing

+infos(fonte): https://www.redbytes.in/how-to-make-a-video-game/

Tags :

Mais umas referências de livros acerca do game design

Aqui estão mais umas boas referências de livros acerca do desenvolvimento de videojogos :)

A Theory of Fun for Game Design de Raph Koster

The Art of Game Design: A Book of Lenses de Jesse Schell


Game Design Workshop: A Playcentric Approach to Creating Innovative Games de Tracy Fullerton

 
Challenges for Game Designers de Brenda Brathwaite & Ian Schreiber


Reality Is Broken: Why Games Make Us Better and How They Can Change the World de Jane McGonigal


Level Up! The Guide to Great Video Game Design de Scott Rogers


Game Feel: A Game Designer’s Guide to Virtual Sensation de Steve Swink


How Games Move Us: Emotion by Design (Playful Thinking) de Katherine Isbister


On Game Design de Chris Crawford


Game Design: How to Create Video and Tabletop Games, Start to Finish de Lewis Pulsipher

+infos(fonte): LINK

 

Tags : ,

GDC 2018 SPECIAL

A malta da sonniss.com voltou a disponibilizar um pack de musicas e sons livres de serem usados.

+infos(a oferta): LINK

Tags : ,

Ainda sobre os old games..

Existem sites que fazem negócio mantendo videojogos ao dispor dos utilizadores, apesar das tecnologias terem evoluído. Um desses exemplos é a malta do GOG.com, que fazem realmente um excelente trabalho.

Uma das coisas interessantes que se verifica é que muitos dos videojogos que foram desenvolvidos na década de oitenta e noventa não se sabe quem são os seus “donos” e mais terrível é que muitos dos donos não têm sequer o código fonte.

+infos(GOG): LINK

Tags :

Roms, Nintendo or else

Eu nunca tive uma grande finidade pelos jogos da nintendo, não sei porquê mas foram episódios que me passaram ao lado. Não quero com isto dizer que não se trata de uma editora que faz coisas interessantes, que tem o seu nicho de sucesso, mas agora começo a perceber um pouco mais do que afinal é isso de construir um jogo na década de 80 e perpetuar a sua existência sem qualquer limite.

Site de ROMs com videojogos existem vários, contudo dois dos maiores foram recentemente encerrados por causa de um processo desencadeado pela Nintendo: O loveROMS e o LoveRETRO.

Algumas das situações não se podem esconder no assunto de se proteger um videojogo que saiu há cerca de 1, 2 ou 4 anos, mas sim impossibilitar que videojogos deixem de ser jogados porque entretanto as tecnologias evoluíram. Eu compreendo que alguns deles até estão disponíveis para serem jogados online (e oficialmente) em ecrãs de 4k e consolas topo de gama, mas para quê? que miúdos vão hoje experimentar um jogo da década de 80 quando têm ao seu dispor uma montanha de jogos indie que são gratuitos?

Atitudes destas como a da Nintendo não só vêm prejudicar o perpetuar de uma história bonita, que é a manutenção pela comunidade de um portefólio de videojogos, como não vai permitir que outros miúdos que não vão comprar esses videojogos os possam experimentar sem qualquer tipo de impedimento.

“shame on you nintendo”

+infos(noticia em destaque):  LINK

+infos(noticia comentada): LINK

Tags : , ,

Bundle de livros..

O site humble bundle está com duas promoções de livros acerca de videojogos, uma relacionado com a programação de videojogos e a outra relacionada com o design.

a primeira campanha, “Humble Book Bundle: Game Design & Puzzlecraft”, continha alguns dos seguintes livros (infelizmente não fui a tempo para retirar a lista completa):
women in tech: take your career to the next level with pratical advice and inspiring stories by Tarah Wheeler
game theory in the age o chaos by Mike Selinker
a theory of fun for game design by Raph Koster
complete kobold guide to game design by Wolfgang Baur et al.
the bones: us and our dice, by Jeff Tidball and Will Hindmarch
puzzlecraft: the dlc, by mike selinker and Thomas Snyder
level uo!: the guide to great video game design, by Scott Rogers
kobold guide to board game design: the dlc by Mike Selinker


a segunda campanha, e que por esta altura ainda está a decorrer tem os seguintes livros:
Introduction to Game Development by James Parker
Python Pocket Primer by Oswald Campesato
Digital Filmmaking by Peter Shaner
Video Game Addiction by David Olle, J. Westcott
Hollywood Studio Production Techniques by Winnie Wong
Classic Game Design by Franz Lanzinger
Video Game Writing Second Edition by Maurice Suckling, Marek Walton
Game Testing Third Edition by C. Schultz, R. Denton Bryant
Introduction to 3D Game Programming Using DirectX 11 by Frank Luna
iOS for Game Programmers by Allen Sherrod
Programming Essentials Using Java by Wm. McAllister, S.J.Fritz
3D Character Development Workshop by Erik Van Horn
Computer Graphics Programming in OpenGL with Java by V. Scott Gordon, John L. Clevenger
Python 3 Pocket Primer by James Parker
Artificial Intelligence in the 21st Century Second Edition by S. Lucci, D.Kopec
Introduction to 3D Game Programming with DirectX12 by Frank Luna
Storyboarding Second Edition by Stephanie Torta, Vladmir Minuty
Photo Restoration Using Adobe Photoshop CC 2017 Second Edition by Vickie Wolper
Python An Introduction to Programming by James Parker

+infos(primeira): https://www.humblebundle.com/books/puzzlecraft-books

+infos (segunda): https://www.humblebundle.com/books/program-your-own-games-books

Tags : , ,