Aller au contenu

debut en C


Messages recommandés

Tu t'es bien remis en débug (et non release) ? C'est important pour le bon fonctionnement des points d'arrêt.

oui

[EDIT]

ceci dit, est ce que ce serait pas du au *STD1_surf1[510][510], je me demande quelque part si c'est la meilleur solution, j'ai eu l'impression qu'en untilisant un pointeur simple (ce que j'avais fait au depart) et en utilisant l'icrementation pour les couleur et la position, c'etait beaucoup plus rapide dans le sens ou il a pas a alloué un tableau de 260100 cases

(pour infos, la dernière fois qu'il s'est executer il a mis pas loin de 3 seconde a calculer la surface) ???

[EDIT 2]

depuis que j'ai coder avec un pointeur normale j'ai plus le probleme du stack overflow.

par contre question vitesse c'est toujours pas sa.(toujour 3 a 4 seconde pour calculer les couleurs de la surface).

Lien vers le commentaire
Partager sur d’autres sites

  • Réponses 69
  • Créé
  • Dernière réponse

c'est à l'appréciation du développeur.

elles sont utilisées dans certains shell, par exemple pour stocker l'historique des commandes, ou les différentes variables.

il me semble également qu'emacs les utilise pour bufferiser les fichiers.

ça peut s'utiliser comme un [type]**, avec l'avantage de ne pas avoir à realloc pas la première dimension (tu n'as en fait qu'une liste de [type]* (tu me suis ?)).

dans le cas de la gestion du clavier dans une appli (principalement shells/éditeurs), l'utilisation d'une liste chaînée de char, dont chaque maillon représente une touche tapée, ça à l'avantage de rendre l'édition plus simple (à traiter).

un couper/coller se résume à une édition de liens.

pas besoin d'utiliser un tableau statique, de malloc à une taille définie ou de realloc (le tout se basant globalement sur des valeurs arbitraires, injustifiables même si défendables) ; la taille de ton buffer est théoriquement infinie, et techniquement limité à ta mémoire userland.

après, si on s'étend aux arbres (même principe, mais chaque maillon pointe sur deux (ou plus) autres elts, en plus de la référence au maillon père), c'est utilisé pour tout ce qui est algo A* / Dijkstra, ou plus généralement, les algorithmes qui devront prendre une décision en fonction de la pondérance des différents choix qui s'offrent à lui.

Lien vers le commentaire
Partager sur d’autres sites

ça peut s'utiliser comme un [type]**, avec l'avantage de ne pas avoir à realloc pas la première dimension (tu n'as en fait qu'une liste de [type]* (tu me suis ?)).

oui a peut près, pour le cas d'un editeur, partant du principe qu'on ne sait pas quel quantité de texte ont vas taper, il crée une chaine pour chaque caractère de facon a pouvoir en stocker une taille "infinie" ou en tout cas pas limitée a la taille d'un malloc préalable.

partant de ce principe j'imagine que sa peut egalement etre appliqué au image video, qui se chargerais en memoire par serie de X element avant d'etre trasferer a la carte video par bloc de Y et ainsi permettre de gagner en temps de traitement. et si j'extrapole un peut plus de permettre le streaming, les infos etant ainsi gérer en parrallèle ??

après, si on s'étend aux arbres (même principe, mais chaque maillon pointe sur deux (ou plus) autres elts, en plus de la référence au maillon père), c'est utilisé pour tout ce qui est algo A* / Dijkstra, ou plus généralement, les algorithmes qui devront prendre une décision en fonction de la pondérance des différents choix qui s'offrent à lui.

la j'avoue ue c'est plus :dd: , quand tu parle de "decisions"... tu parle de conditions a tester ou est ce que le concept va plus loins que sa ????

Lien vers le commentaire
Partager sur d’autres sites

partant de ce principe j'imagine que sa peut egalement etre appliqué au image video, qui se chargerais en memoire par serie de X element avant d'etre trasferer a la carte video par bloc de Y et ainsi permettre de gagner en temps de traitement. et si j'extrapole un peut plus de permettre le streaming, les infos etant ainsi gérer en parrallèle ??
mouai. tu t'emballes un peu quand même.

Pour ce qui est du graphique, en général, tu reste sur les lib de base. Après, libre à toi de t'interfacer avec elles à ta guise.

Les rares que j'ai vu faire autrement allaient directement écrire sur la carte. Mais ça demande pas mal de pratique :D

Et, pour le streaming: la couche réseau fait tout. Je vois ce que tu veux dire (formatage à la volée de structures envoyées par le réseau), mais dans la pratique, ce n'est pas toi qui fait ce travail (à moins d'aller recoder une partie de ton système)

la j'avoue ue c'est plus :dd: , quand tu parle de "decisions"... tu parle de conditions a tester ou est ce que le concept va plus loins que sa ????
je parle d'une décision prise par ton IA, en fonction d'un groupe de données.

Suivant, l'IA, ça va du if (x < 2) aux réseaux de neurones.

Lien vers le commentaire
Partager sur d’autres sites

bon alors j'ai une question qui va peut etre paraitre ultra-bete alors tapez pas hein... merci. :roule::roule:

voila je voudrais savoir s'il est possible de construire un tableau de pointeur ou chaque "case" contiendrai un pointeur sur un element de type différent, de façon a ce que sa me permette ensuite un truc du genre :

void tab[];
tab[0]= contient un pointeur sur les données contenue par un char tableau[];
tab[1]= contient un pointeur sur les données contenue par un int variable_qqch;
tab[2]= contient un pointeur sur les données pointées par un void *ptr;
tab[3]= contient un pointeur sur les données pointées par un struct->element // d'accord c'est peut etre bien celui la le plus bizarre;
tab[4]=contient un pointeur sur les données contenue par un float.
etc...

et d'autre "truc" dans le meme genre est ce que pour y arriver je devrais passer par des truc allambiqué ou pas et comment faire...ou est ce que c'est definitivement capout, foutu, a jeter aux orties .....

pour info j'ai déja reussi a faire le tab[0]= char tableau[]

mais des que je met un int par contre la sa coince, il me le converti automatiquement en char.

est ce que par exemple en creant un void *ptr pour chaque case du tableau je pourrait y arriver de facon a faire pointé le ptr sur les exemple que j'ai donné au dessus ??? et dans ce cas comment construire l'ensemble ???

Lien vers le commentaire
Partager sur d’autres sites

C'est possible mais c'est un peu "moche"... En plus ça t'oblige à garder l'info sur quel type est stocké ou, puisqu'il va falloir caster à chaque fois que tu récupères une des valeurs. Donc en gros il faut vraiment que tu n'aie pas le choix sinon ça t'apportera plus de problèmes qu'autre chose. Bref.

Donc par exemple :

void *tab;
int i = 10;
tab = malloc(sizeof(tab*2)); // Deux éléments

// Chaine de caractère
tab[0] = "blablabla";

// Entier
tab[1] = malloc(sizeof(i));
*tab[1] = i;

J'ai pas testé mais ça doit ressembler à ça

Lien vers le commentaire
Partager sur d’autres sites

possible, mais dans un cas pareille, le mieux (on y revient toujours), c'est une struct contenant:

void* elt;

unsigned int type;

struct *next;

ok mais dans ce cas j'ai boligatoirement 1 seul type par structure, et pour pallié a sa ont pourrais faire pointer elt vers une autre struct mais sa obligerai a rajouter une enum pour chaque nouvel struct, ce qui ne rend pas le principe vraiment générique...

sinon les base de données sont elles aussi construites sur le principe des liste chainées ???

je pensais par exemple a :

chaque champs est composé d'une liste de x elmt de type x

chaque ligne est composé d'une liste des liste de champs précedents (en ligne)

la base complete et composée d'une liste des "ligne" precedentes

dernier point :

alors j'ai trouver une solution comment dire... curative qui "resout" plus ou moins le probleme (en tout cas dans l'idée, meme si elle me plait pas vraiement par ce que je pense qu'a terme elle devrais bouffer beaucoup de memoire, mais elle est plus simple à gérer avant de revenir au premier concept).

mais j'ai un probleme :

blist tmp= ma_liste_passé_en_parametre;

//***************************************************
	while(tmp->string[si])
	{
		if(tmp->string[si]!=NULL) // ne sert à rien, c'etait juste au cas ou
		{
			printf("\nchaine[%d] = %s", si, tmp->string[si]);
			si++;
		}
	}

ce code est contenu dans ma fonction de lecture de liste (elle m'est surtout utile pour la debug et preparer le terrain)

ma strucutre ressemble a sa :

typedef struct base_list B_list;
struct base_list
{
char **string;
//code....
}; 
typedef B_list* blist;

le double pointeur string me sert a faire des matrice de chaine de caractère. en ligne ont malloc le nombre de chaine a creer, en colonne ont malloc la taille de chaque chaine.

bref tout sa pour en venir a mon soucis : je ne peut pas me permettre de passé ces informations en entrée de ma fonction de lecture (y'en a trop, et sa peut changé d'un element de la liste a l'autre...)

[EDIT2] bon alors j'ai trouver (a priori) une solution pour calculer dans la fonction le nombre de colonne de ma matrice, donc en gros je fait comme si chacun des premier caractère de mes différentes chaines constituait une chaine

strlen(tmp->string)

sa a l'air de fonctionner puisque ma sortie me renvoie les bonne valeurs pour le coup.

par contre je trouve pas sa terrible perso, d'autant plus que dans ce cas les warnings signifie que tout vas bien, un peut bizarre non ?

avec des posts aussi long

[EDIT3]probleme resolu _msize resout tout (ou presque)

@spaz001 et shtong, j'aimerais bien savoir par quoi vous remplacez _msize...??

Lien vers le commentaire
Partager sur d’autres sites

[EDIT3]probleme resolu _msize resout tout (ou presque)

@spaz001 et shtong, j'aimerais bien savoir par quoi vous remplacez _msize...??

Vais juste répondre à ça.

Quand TU alloues un tableau, TU sais quelle taille il fait.

On ne recherche pas la taille d'un tableau, on la sauvegarde.

Lien vers le commentaire
Partager sur d’autres sites

[EDIT3]probleme resolu _msize resout tout (ou presque)

@spaz001 et shtong, j'aimerais bien savoir par quoi vous remplacez _msize...??

Vais juste répondre à ça.

Quand TU alloues un tableau, TU sais quelle taille il fait.

On ne recherche pas la taille d'un tableau, on la sauvegarde.

tu m'a eu :D

j'avais pas vue les choses comme sa, meme si sa risque de bouffé encore plus de memoire sa va surement simplifier mon algo...

et m'obliger a tout réecrire :francais:

merki

ps :(par contre d'un autre point de vue sa fait double emploie puisque quelque part cette info est stocké dans les octet de controle du pointeur...et puisque l'info est dispo pourquoi eviter de s'en servir..??? comme le disais shtong les performances... en meme temps c'est juste récupéré une valeur ...?)

Lien vers le commentaire
Partager sur d’autres sites

[EDIT3]probleme resolu _msize resout tout (ou presque)

@spaz001 et shtong, j'aimerais bien savoir par quoi vous remplacez _msize...??

Vais juste répondre à ça.

Quand TU alloues un tableau, TU sais quelle taille il fait.

On ne recherche pas la taille d'un tableau, on la sauvegarde.

tu m'a eu ;)

j'avais pas vue les choses comme sa, meme si sa risque de bouffé encore plus de memoire sa va surement simplifier mon algo...

et m'obliger a tout réecrire :transpi:

merki

ps :(par contre d'un autre point de vue sa fait double emploie puisque quelque part cette info est stocké dans les octet de controle du pointeur...et puisque l'info est dispo pourquoi eviter de s'en servir..??? comme le disais shtong les performances... en meme temps c'est juste récupéré une valeur ...?)

Parce que cette information n'est pas sauvegardé pour toi, rien que ça devrait être suffisant.

Et, c'est un peu comme si, plutôt que d'aller lire la mémoire normalement, en utilisant les adresses retournées par malloc, tu t amusais à aller chercher où dans la barette de RAM sont situés ces infos, pour aller les lire directement, sans passer par l'OS.

C'est pas que tu peux pas le faire, mais, c'est juste pas un comportement normal, prends plutôt des bonnes habitudes de programmation, parce que msize, tu l'auras pas dans tous les langages.

Et comme le dit Shtong, pour les perfs, car non, cela ne se résume sans doute pas à récupérer une valeur, il doit y avoir plein d'autres vérif faites par cette fonction pour vérifier si tu lui donne bien le début d'une adresse mémoire allouée.

Lien vers le commentaire
Partager sur d’autres sites

bon bas j'ai reussi a faire un truc qui ressemble plus ou moins (surtout moint) à quelque chose sur mes structure en partant du principe de creer une structure qui couvre disons 90% des cas et d'utiliser toujours la meme structure pour ces cas la.

comme sa :

typedef struct base_list B_list;
struct base_list
{
char **string;
int size_string;
int *integral;
int size_int;
double *real;
int size_dble;
struct base_list *nxt;
}; 
typedef B_list* blist;

et en utilisant stdarg dans quasiment toute mes fonctions (add_tete, add_queue, etc...) pour attribuer les valeur au différent struct->elmt.

jusque la sa fonctionne, meme si il y a beaucoup d'amelioration possible...

mais encore une fois je sais pas si sa a un grand intéret ??? :transpi:

Lien vers le commentaire
Partager sur d’autres sites

Je préfères largement la version que t'as proposé Mephisto, pour plusieurs raisons :

- Elle est réellement flexible (contient vraiment ce que tu veux dans le void*).

- Elle prends moins de place, et surtout pas de place pour rien (dans ta solution plus de la moitié de la mémoire allouée pour la structure est utilisée)

Lien vers le commentaire
Partager sur d’autres sites

Je préfères largement la version que t'as proposé Mephisto, pour plusieurs raisons :

- Elle est réellement flexible (contient vraiment ce que tu veux dans le void*).

- Elle prends moins de place, et surtout pas de place pour rien (dans ta solution plus de la moitié de la mémoire allouée pour la structure est utilisée)

je suis d'accord avec toi la dessus.

par contre perso j'ai toujours des probleme des type lorsque je veut attribuer un reel a void *ptr, d'autant plus que le traitement des void est completement différent des autres types, et d'un autre coté sa permet pas d'avoir plusieur type par atome.

enfin sa permet effectivement de faire des fonction generique pour le chainage, mais pas pour le 'attribution/traitement des valeur.

l'idée que j'avais eu pour regler le probleme c'etait de creer une fonction qui "formate" mes structure de telle sorte que je puisse acceder à n'importe quelle struct->elmt par une incrementation, dou l'idée un void tab[] contenant des pointeur sur les champs de ma structure (j'accede a struct->elmt par tab[0], a struct->elmt2 par tab[1] etc....). j'etait partis du principe que sa aurait rendu ma structure completement transparente au "regard" de la fonction chargé de chainée, faire des traitement sur les valeur, etc...

mais a à l'air foutu ....

Lien vers le commentaire
Partager sur d’autres sites

J'ai bien sûr fait la connerie d'une part d'utiliser & à la place de * (pour modifier la valeur pointée et non l'adresse), et aussi de faire un cast pour dire au compilateur que les types sont bien compatibles !

Code qui fonctionne (testé)

typedef struct storage storage;

struct storage
{
void* elm;
unsigned int type;
storage* next;
};

int main(int argc, char *argv[])
{
int i = 10;

storage *machin = malloc(sizeof(storage));
machin->elm = malloc(sizeof(i));
*((int*)(machin->elm)) = i;

return;
}

Pourquoi faire comme ça ? Tout simplement parce que elm est un pointeur. Donc si tu faisais machin->elm = i, tu modifierais l'adresse du pointeur et pas la valeur de la variable ! Pire, si tu essayes de mettre un entier long (ou tout du moins plus grand que la taille d'un pointeur), tu vas dépasser l'emplacement réservé au pointeur en mémoire et modifier la valeur suivante (type dans mon exemple) sans le vouloir...

Lien vers le commentaire
Partager sur d’autres sites

j'imagine deja que la reponse est non mais ont sais jamais alors je vais quand meme poser la question :

y a t'il une fonction en C qui permette de detecter le type d'une variable (tapez pas!) ...?

Non, une donnée, c'est une suite de bits, sa représentation (entier, pointeur, caractère, trucmuche), c'est à toi de la connaitre.

Lien vers le commentaire
Partager sur d’autres sites

Non, une donnée, c'est une suite de bits, sa représentation (entier, pointeur, caractère, trucmuche), c'est à toi de la connaitre.

donc dés qu'on veut utiliser du void ont est obligé de casté... et de prévoir tous les cas dans les fonction concernées ?

a toi de déterminer ce que *tous* implique, mais c'est l'idée.

Lien vers le commentaire
Partager sur d’autres sites

Non, une donnée, c'est une suite de bits, sa représentation (entier, pointeur, caractère, trucmuche), c'est à toi de la connaitre.

donc dés qu'on veut utiliser du void ont est obligé de casté... et de prévoir tous les cas dans les fonction concernées ?

a toi de déterminer ce que *tous* implique, mais c'est l'idée.

bah, au moins tout les type de base, l'avantage c'est qu'on fonctionne sur un ensemble de type determiné et fini, mais si ont va jusqu'aux types structurés, *tous*, représente, a fortiori, l'infini... donc j'imagine qu'ont peut pas vraiement faire de fonction "parfaitement" génériques

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.


×
×
  • Créer...