Lista de struct global, armazenamento e manipulação por funções void

Mais uma vez recorro a vocês para solucionar um problema que não consigo, ou não tenho conhecimento suficiente para executá-lo.

Seguinte:

1 - Tenho uma lista global, onde serão armazenados 4 resultados fixos e indexados, onde 0 seria para um vetor e seus respectivos resultados, 1 para outro e assim sucessivamente, 2, 3 …:

typedef struct{
	int numcomp = 0;
	int numtrocas = 0;
 	int tempo[2] = {0,0,0};
 	
}
RESULTADOS[3];

2- Preciso saber como seria o escopo do argumento e como serão as chamadas para inserção dos dados na função,ou seja que irão modificar os índices [] e seus elementos da struct?

Exemplo:

Aqui chamo o algoritmo de ordenação e irei inserir minha primeira lista:

bubbleSort(int vet[], int num, rs[0])

void bubbleSort(int vet[], int num, Aqui seria o argumento Padrão Independente do Indice)

 {


int i, continua, aux, fim = num;
		
		do{
			continua = 0;
			
			for(i = 0; i < fim -1; i++ ){
				
				asapii.numcomp++;
				if(vet[i] > vet[i+1]){
					aux = vet[i];
					vet[i] = vet[i+1];
					vet[i+1] = aux;
					asapii.numtrocas++;
					continua = 1;
				}
			}
			
			fim--;
							
		}while(continua != 0);
		
		rs[0].tempo = clock()/ CLOCKS_PER_SEC;
}

para inserir o tempo eu tenho outra função, mas sabendo resolver isso, imagino que será fácil implementar para o tempo.

Por se tratar de algo simples, vou te dar o código pronto. Leia e tente entender o que está acontecendo. Poste as dúvidas que você tiver que eu respondo.

Como o bubble sort é um algoritmo extremamente ineficiente (O(n^2)), não use ele em vetores muito grandes (mais do que uns 30000 numeros), senão vai demorar muito para terminar de executar.

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

typedef struct {
    unsigned long long numcomp;
    unsigned long long numtrocas;
    double tempo;
} Estatistica;

void bubbleSort(int* vet, int size, Estatistica* estatistica) {
    clock_t start = clock();
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size - 1; j++) {
            estatistica->numcomp++;
            if (vet[j] > vet[j+1]) {
                estatistica->numtrocas++;
                int aux = vet[j];
                vet[j] = vet[j+1];
                vet[j+1] = aux;
            }
        }
    }
    clock_t end = clock();
    estatistica->tempo = (double)(end - start) / CLOCKS_PER_SEC;
}

void imprimeEstatisticas(int* vet, int size, Estatistica* estatistica) {
    // descomente se quiser ver o vetor ordenado
    // printf("\nVetor: ");
    // for (int i = 0; i < size; i++)
    //     printf("%d ", vet[i]);
    printf("\n# Estatisticas #\n");
    printf("Comparacoes: %llu\n", estatistica->numcomp);
    printf("Trocas: %llu\n", estatistica->numtrocas);
    printf("Tempo de execucao: %f\n\n", estatistica->tempo);
}
// fiz isso aqui pra você poder testar com o vetor do tamanho que quiser, tem um exemplo na main
int* criaVetor(int size) {
    srand(time(0));
    int* vetor = calloc(size, sizeof(int));
    for (int i = 0; i < size; i++)
        vetor[i] = rand();
    return vetor;
}

int main(int argc, char** argv) {
    int quantidadeDeEstatisticas = 4;
    Estatistica* estatisticas = calloc(quantidadeDeEstatisticas, sizeof(Estatistica));

    int vetA[5] = {5, 4, 3, 2, 1}; // Caso 1: numeros ordenados ao contrario
    int vetB[5] = {1, 2, 3, 4, 5}; // Caso 2: numeros ordenados
    int vetC[5] = {5, 2, 1, 4, 3}; // Caso 3: aleatorio simples

    int tamanhoVetMuitoGrande = 20000;
    int* vetorMuitoGrande = criaVetor(tamanhoVetMuitoGrande); // Caso 4: tamanho arbitrário, de preferencia grande

    bubbleSort(vetA, 5, &estatisticas[0]);
    bubbleSort(vetB, 5, &estatisticas[1]);
    bubbleSort(vetC, 5, &estatisticas[2]);
    bubbleSort(vetorMuitoGrande, tamanhoVetMuitoGrande, &estatisticas[3]);

    imprimeEstatisticas(vetA, 5, &estatisticas[0]);
    imprimeEstatisticas(vetB, 5, &estatisticas[1]);
    imprimeEstatisticas(vetC, 5, &estatisticas[2]);
    imprimeEstatisticas(vetorMuitoGrande, tamanhoVetMuitoGrande, &estatisticas[3]);

    free(estatisticas);
    free(vetorMuitoGrande);
    return 0;
}

Olá amigo, boa tarde. Belo código.

Infelizmente não consegui exito ainda, mesmo implementando sua struct estatística, quando executo meu código e seleciono a opção de ordenação uma tela de erro aparece pedindo para fechar o programa.

Ou seja, compila mas não reconhece o que utilizei.

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#define aleatorio 100
#define vetor1 15
#define bs 1

typedef struct{
int numcomp;
int numtrocas;
int tempo;

}ESTATISTICAS;

void menu();
void subMenu();
//void cronometro(clock_t start, clock_t end);
int* geraVetor(int tamanho);
void imprimeVetor(int *vet, int tamanho);

//algoritmos de ordenação
void bubbleSort(int vet[], int num, ESTATISTICAS* estatisticas);

int main(){

menu();

}

void menu(){

int continuar = 1;
	
	do{
		system("cls");
		printf("### SELECIONE O METODO DE ORDENACAO ###\n");
		printf("\n1 - BUBBLE SORT");
		printf("\n2 - SELECTION SORT");
		printf("\n3 - INSERTION SORT");
		printf("\n4 - MOSTRAR RESULTADOS DE ORDENAÇÃO");
		printf("\n0 - SAIR\n\n\n");
		
		scanf("%d",&continuar);
		system("cls");
		
		
		switch(continuar){
			
			case 1:
				printf("### VETOR 15 POSICOES ###\n");
				
				int *ptr;
				ptr = geraVetor(vetor1);
				//imprimeVetor(ptr, vetor1);
				
				ESTATISTICAS* estatisticas;
				clock_t  start, end;
				
				start = clock();
				bubbleSort(ptr,vetor1, &estatisticas);
				//imprimeVetor(ptr, vetor1);
				end = clock();
				
				//cronometro(start,end);
				
				
				free(ptr);
			
				printf("\nCOMPARACOES: %d",estatisticas->numcomp);
				printf("\n\nTROCAS: %d", estatisticas->numtrocas);
				//printf("\n\nTEMPO: %d",resultados->tempo);
				printf("\n\n\n");
				system("pause");
				subMenu();
				
			break;
		}
		
	}while(continuar);

}

void subMenu(){

int continuar = 1;
	
	do{
		system("cls");
		printf("### VOLTAR AO MENU INICIAL ###\n");
		printf("\n1 - SELECIONAR OUTRO ALGORITMO DE ORDENACAO");
		printf("\n0 - SAIR\n\n\n");
		
		scanf("%d",&continuar);
		system("cls");
		
		
		switch(continuar){
			
			case 1:
				main();
				
			case 0:
			exit(0);
			break;
		}
		
	}while(continuar);

}

/*
void cronometro(clock_t start, clock_t end){

int tmpexe = (end - start)/ CLOCKS_PER_SEC;

int horas_seg = 3600;

tempo[0].hr = (tmpexe / horas_seg);
tempo[0].min = (tmpexe - (horas_seg * 	tempo[0].hr))/60;
tempo[0].seg = (tmpexe - (horas_seg * 	tempo[0].hr)- (	tempo[0].min *60));

}

/
int
geraVetor(int tamanho) {

//int *ptr = malloc(tamanho * sizeof(int));

int *ptr = (int*) malloc(tamanho *sizeof(int));

for (int i = 0; i < tamanho; i++){
	
	//atribui valores randomicos com base no intervalo da variavel aleatorio
	ptr[i] = (rand() % aleatorio) + 1;
	
	//verifica se existe valores iguais
	for(int j=0; j < i; j++){
		
		if(ptr[j] == ptr[i]){
			
			ptr[i] = (rand() % aleatorio) + 1;
			j=0;
			
		}
	}
}
    
return ptr;

}

void imprimeVetor(int *vet, int tamanho){
//exibe qualquer vetor
system("\n\n");
for(int i = 0; i < tamanho; i++){
printf("%d - %d |\n",i,vet[i]);
}
system("\n\n");
}

void bubbleSort(int vet[], int num, ESTATISTICAS* estatisticas){

int i, continua, aux, fim = num;
		
		do{
			continua = 0;
			
			for(i = 0; i < fim -1; i++ ){
				
				estatisticas->numcomp;
				if(vet[i] > vet[i+1]){
					aux = vet[i];
					vet[i] = vet[i+1];
					vet[i+1] = aux;
					estatisticas->numtrocas;
					continua = 1;
				}
			}
			
			fim--;
							
		}while(continua != 0);
		
		//rs[0].tempo = clock()/ CLOCKS_PER_SEC;

}

Primeira coisa: dentro da função menu, dentro do switch, dentro do case 1:, você faz assim:

ESTATISTICAS* estatisticas;

Essa linha declara um ponteiro que aponta para nulo, 0. Aloca memória para essa estrutura para que ela possa ser utilizada. Faz assim:

ESTATISTICAS* estatisticas = malloc(sizeof(estatisticas)); // aloca memória suficiente para caber uma struct do tipo ESTATISTICAS

Segundo: logo abaixo, você faz:

bubbleSort(ptr, vetor1, &estatisticas);

O terceiro argumento da função bubbleSort é um ponteiro. Portanto, você não precisa do operador de resolução de endereços &, pois a variável passada já é um ponteiro. Você está passando o endereço do ponteiro, sendo que você quer passar o valor do ponteiro (que é um endereço para a struct alocada em memória). Faz assim:

bubbleSort(ptr, vetor1, estatisticas);

Vai arrumando aí enquanto eu procuro mais coisas. Me diz se der certo.

Olá amigo, boa notie, obrigado pela pronta resposta !

quando você me pede para alocar do tamanho da struct:

ESTATISTICAS* estatisticas = malloc(sizeof(estatisticas));

O devC me devolve os seguintes erros:

10 16 C:\Users\gu1lh\Desktop\Estrutura de dados 2\TrabalhoEstrutura1VA.cpp [Warning] non-static data member initializers only available with -std=c++11 or -std=gnu++11

11 17 C:\Users\gu1lh\Desktop\Estrutura de dados 2\TrabalhoEstrutura1VA.cpp [Warning] non-static data member initializers only available with -std=c++11 or -std=gnu++11

C:\Users\gu1lh\Desktop\Estrutura de dados 2\TrabalhoEstrutura1VA.cpp In function ‘void menu()’:

58 62 C:\Users\gu1lh\Desktop\Estrutura de dados 2\TrabalhoEstrutura1VA.cpp [Error] invalid conversion from ‘void*’ to ‘ESTATISTICAS*’ [-fpermissive]

tive o mesmo problema anteriormente quando criei a função para gerar vetor, ajustando com o que me foi respondido não obtive exito para essa alocação.

ESTATISTICAS* estatisticas = (ESTATISTICAS*) malloc(sizeof(estatisticas));

Ele tá reclamando que “não se pode fazer um cast implícito de void* (retorno do malloc) para ESTATISTICAS* (o ponteiro)”. Na verdade pode sim, os compiladores hoje já aceitam fazer esse cast livre. O compilador do DevC provavelmente é velho ou não é “C de verdade” (segundo a especificação ANSI). A solução é fazer oq eu falei ali em cima, coloca um cast.

Mais informações aqui: http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc

E pelo que eu vi, você tá usando um compilador de C++ (pelos warnings). Por isso que pode estar dando esse erro ali, pois em C++ o cast é obrigatório. Não se indica o uso de malloc em C++, mas sim do operador new.

Ok, compilo corretamente apos essa conversão e casting.

porém algo inesperado no valor de numero de comparações é exibido na tela. Alterei a linha onde o mesmo é incrementado para o valor fixo 1, e esse valor me foi exibido, porém quando executo o contador numcomp++ normalmente um valor muito alem do numero de comparações e informado.

Já em numtrocas o valor é retornado de forma correta.

printf("\nCOMPARACOES: %d",estatisticas->numcomp);
printf("\n\nTROCAS: %d", estatisticas->numtrocas);

void bubbleSort(int vet[], int num, ESTATISTICAS* estatisticas){

int i, continua, aux, fim = num;

		do{
			continua = 0;

			for(i = 0; i < fim -1; i++ ){

				estatisticas->numcomp += 1;
				if(vet[i] > vet[i+1]){
					aux = vet[i];
					vet[i] = vet[i+1];
					vet[i+1] = aux;
					estatisticas->numtrocas++;
					continua = 1;
				}
			}

			fim--;

		}while(continua != 0);

		//rs[0].tempo = clock()/ CLOCKS_PER_SEC;

}

acho que fui redundante, casting e conversão =)

Peço que o tópico seja fechado pois consegui resolver o problema inicializando a variável na chamada da struct. Obrigado