Le Gandalf du pointeur y a pas a chercher c'est ICI ! Franchement tu assures grave et en plus on teste tout ca en s'amusant. On sent vraiment que tu aimes ce que tu fais et ca passe vraiment bien dans tes videos..... Encore Encore !!!! Le pire dans tout ca c'est qu'on est en C et on a l'impression de toucher du doigt le polymorphisme du C++ avec la genericite. Bravo !
Bonjour J'ai créer ma chaine pour essayer d'initier les personnes au langage et Introduire la notion de généricité n'est pas facile, tu t'en ai bien sortie. bonne continuation
Salut super vidéo. À 14 minutes c'était pas un caste sur un char ? tu voulais afficher son adresse comme %p fait dans printf ? il y a un x dedans je pense que c'est le problème.
Salut, en fait, le fait que je cast le pointeur void* en pointeur int* ça fait croire au compilateur qu'il doit afficher un entier sur 4 octets à partie de l'adresse indiquée, ce qui fait qu'il va bien trouver la valeur du char pointé mais il va aussi chercher sur les 3 octets d'à côté, ce qui nous donne à l'affichage des valeurs inatendues, sur le coup je ne m'était pas rendu compte de la subtilité ahah.
@@nassimamrane5052 Je pense que si on avait voulu afficher la valeur entière du char (et non le caractère), il aurait fallu rajouter un autre case dont le code serait: "printf("%hhd ", *(char *)var);" Le "%hhd" permet d'afficher la valeur entière d'un 'char' et non le caractère ascii
@@codingoverflow Ah merci intéressant j'essayerai de voir comment faire quand viendra mon tour de coder la fonction printf je vais à 42. Et grâce à toi j'ai donné une bonne piste à un ami de là-bas sur comment le coder merci.
J'avoue que sur le premier exemple je ne vois aucun interet de faire bien degueu : printf("&d "), compare(&c, &d, cmpFloat)); ... quand ca fonctionne tres bien, avec un code bien plus light : printf("%d ", cmpFloat(c, d)) ? Moins de code, moins d'erreurs. 😂
14:00 je crois que c'est parce que il va lire sur 4 octet et le l’afficher en int car ta pas préciser qu'il devait afficher le décimal d'un char, il va donc prendre ton premier octet dans le quelle ce trouve ton 'F' et les 3 octet d’après en mémoire et lire les 32 bite compris dans ces 4 octet a la suite et l’afficher en int. vue q'un int fait 4 octet c'est ce qu'il comprend
salut voici un code pour inverser la liste (elle-même) : void ft_list_reverse(t_list **list) { t_list *tmp; t_list *next; next = NULL; while (*list) { tmp = (*list)->next; (*list)->next = next; next = *list; *list = tmp; } *list = next; } Il fonctionne mais je pige pas tout à fait ce qu'il fait j'essaye de printf la valeur de next chaque tour de boucle et je vois qu'il le fait dans l'ordre pourtant à la fin il est bien inversé que ce passe-t-il s'il te plaît.
Salut, en gros, la variable 'tmp' contiendra toujours le pointeur vers l'élément de la liste venant après l'élément courant. la variable 'next' contiendra toujours le pointeur vers l'élément courant de la liste. Le fait d'écrire (*list)->next = next; indique que l'on attribue à l'élément suivant de la liste le pointeur de l'élément précédant de la liste étant donné que le 'next' provient du tour de boucle précédent. Le fait d'écrire *list = tmp; indique que l'élément courant de la liste devient l'élément qui était sensé être le suivant dans la liste. Je ne sais pas si mon explication est très claire, c'est pas évident d'expliquer ce genre de code par écrit ahah. Si jamais tu ne comprends pas malgré ma maigre explication, tu peux essayer de faire un schéma de l'algorithme, ça peut toujours aider à visualiser :) Petit conseil: N'hésite pas à initialiser des pointeurs à NULL lorsque tu les déclares, sinon il y a un risque pour que leur valeur soit aléatoire lorsqu'ils sont créés. Il me semble aussi que le while(list) devrait plutôt ressembler à while(*list) car dans la boucle, c'est la valeur pointée par le pointeur 'list' qui change au cours des itérations et non le pointeur en soi ;)
@@codingoverflow re après m'être cassé la tête des jours j'ai enfin comprit ce que ça fait en fait on réécrit la liste en mettant la première valeur à la fin. En gros sur une liste qui contient dans l'ordre 10-15-20. Donc list->data = 10, list->next->data = 15 et list->next->data = 20. Premier tour : tmp = (*list)->next // On sauvegarde dans tmp le reste de la liste pour laisser juste 10. ensuite (*list)->next = next //donc NULL pour le début. next = *list; // next = 10 maintenant. *list = tmp; // la liste est égal au reste donc le début est maintenant 15. Deuxième tour : tmp = (*list)->next // On sauvegarde dans tmp le reste de la liste pour laisser juste 15. (*list)->next = next // vaut maintenant 10 next = *list; // next = 15 maintenant. *list = tmp; // la liste est égal au reste donc le début est maintenant 20. Dernier tour : tmp = (*list)->next // On sauvegarde dans tmp le reste de la liste pour laisser juste 20. (*list)->next = next // vaut maintenant 15. next = *list; // next = 20 maintenant. *list = tmp; // la liste est égal au reste donc le début est maintenant NULL. donc à la fin de la boucle on ajoute *list = next pour spécifier que le début vaut 20.
@@nassimamrane5052 En effet, à chaque tour de boucle, next va contenir les valeurs dans l'ordre. Mais chaque valeur de next est utilisée dans le tour de boucle suivant. Par exemple, si je prends la liste [10, 15, 20], Avant de rentrer dans la boucle: next = NULL, tmp = ?, la liste vaut [10, 15, 20] Premier tour de boucle: *list != NULL donc on entre dans la boucle, tmp = (*list)->next donc tmp = [15, 20] (*list)->next = next donc (*list) = [10] next = *list donc next = [10] *list = tmp donc (*list) = [15, 20] Deuxième tour de boucle: *list != NULL donc on entre dans la boucle, tmp = (*list)->next donc tmp = [20] (*list)->next = next donc (*list) = [15, 10] next = *list donc next = [15, 10] *list = tmp donc (*list) = [20] Troisième tour de boucle: *list != NULL donc on entre dans la boucle, tmp = (*list)->next donc tmp = NULL (*list)->next = next donc (*list) = [20, 15, 10] next = *list donc next = [20, 15, 10] *list = tmp donc (*list) = NULL Quatrième tour de boucle: *list == NULL donc on entre pas dans la boucle enfin *list = next donc *list = [20, 15, 10] La liste est bien inversée :)
Le Gandalf du pointeur y a pas a chercher c'est ICI ! Franchement tu assures grave et en plus on teste tout ca en s'amusant. On sent vraiment que tu aimes ce que tu fais et ca passe vraiment bien dans tes videos..... Encore Encore !!!! Le pire dans tout ca c'est qu'on est en C et on a l'impression de toucher du doigt le polymorphisme du C++ avec la genericite. Bravo !
Merci beaucoup, ça fait plaisir :D
Bonjour
J'ai créer ma chaine pour essayer d'initier les personnes au langage et Introduire la notion de généricité n'est pas facile, tu t'en ai bien sortie.
bonne continuation
Merci beaucoup :)
Salut super vidéo. À 14 minutes c'était pas un caste sur un char ? tu voulais afficher son adresse comme %p fait dans printf ? il y a un x dedans je pense que c'est le problème.
Salut, en fait, le fait que je cast le pointeur void* en pointeur int* ça fait croire au compilateur qu'il doit afficher un entier sur 4 octets à partie de l'adresse indiquée, ce qui fait qu'il va bien trouver la valeur du char pointé mais il va aussi chercher sur les 3 octets d'à côté, ce qui nous donne à l'affichage des valeurs inatendues, sur le coup je ne m'était pas rendu compte de la subtilité ahah.
@@codingoverflow Ahh mais du coup ça serait quoi la solution il ferait pareil avec un (char *) ?
@@nassimamrane5052 Je pense que si on avait voulu afficher la valeur entière du char (et non le caractère), il aurait fallu rajouter un autre case dont le code serait: "printf("%hhd
", *(char *)var);"
Le "%hhd" permet d'afficher la valeur entière d'un 'char' et non le caractère ascii
@@codingoverflow Ah merci intéressant j'essayerai de voir comment faire quand viendra mon tour de coder la fonction printf je vais à 42. Et grâce à toi j'ai donné une bonne piste à un ami de là-bas sur comment le coder merci.
@@nassimamrane5052 Avec plaisir :D
Merci pour ta video, pour la suite parle juste unpeu plus fort et sa serais parfait
D'acc j'en prends note ;)
+1
J'avoue que sur le premier exemple je ne vois aucun interet de faire bien degueu : printf("&d
"), compare(&c, &d, cmpFloat)); ... quand ca fonctionne tres bien, avec un code bien plus light : printf("%d
", cmpFloat(c, d)) ? Moins de code, moins d'erreurs. 😂
tweede
14:00 je crois que c'est parce que il va lire sur 4 octet et le l’afficher en int car ta pas préciser qu'il devait afficher le décimal d'un char, il va donc prendre ton premier octet dans le quelle ce trouve ton 'F' et les 3 octet d’après en mémoire et lire les 32 bite compris dans ces 4 octet a la suite et l’afficher en int. vue q'un int fait 4 octet c'est ce qu'il comprend
Effectivement , je viens de tester ce que tu me dis et ça fonctionne, j'aurais du mettre "%hhd" et pas "%d" :D
salut voici un code pour inverser la liste (elle-même) :
void ft_list_reverse(t_list **list)
{
t_list *tmp;
t_list *next;
next = NULL;
while (*list)
{
tmp = (*list)->next;
(*list)->next = next;
next = *list;
*list = tmp;
}
*list = next;
}
Il fonctionne mais je pige pas tout à fait ce qu'il fait j'essaye de printf la valeur de next chaque tour de boucle et je vois qu'il le fait dans l'ordre pourtant à la fin il est bien inversé que ce passe-t-il s'il te plaît.
Salut, en gros,
la variable 'tmp' contiendra toujours le pointeur vers l'élément de la liste venant après l'élément courant.
la variable 'next' contiendra toujours le pointeur vers l'élément courant de la liste.
Le fait d'écrire (*list)->next = next; indique que l'on attribue à l'élément suivant de la liste le pointeur de l'élément précédant de la liste étant donné que le 'next' provient du tour de boucle précédent.
Le fait d'écrire *list = tmp; indique que l'élément courant de la liste devient l'élément qui était sensé être le suivant dans la liste.
Je ne sais pas si mon explication est très claire, c'est pas évident d'expliquer ce genre de code par écrit ahah. Si jamais tu ne comprends pas malgré ma maigre explication, tu peux essayer de faire un schéma de l'algorithme, ça peut toujours aider à visualiser :)
Petit conseil:
N'hésite pas à initialiser des pointeurs à NULL lorsque tu les déclares, sinon il y a un risque pour que leur valeur soit aléatoire lorsqu'ils sont créés.
Il me semble aussi que le while(list) devrait plutôt ressembler à while(*list) car dans la boucle, c'est la valeur pointée par le pointeur 'list' qui change au cours des itérations et non le pointeur en soi ;)
@@codingoverflow re après m'être cassé la tête des jours j'ai enfin comprit ce que ça fait en fait on réécrit la liste en mettant la première valeur à la fin.
En gros sur une liste qui contient dans l'ordre 10-15-20.
Donc list->data = 10, list->next->data = 15 et list->next->data = 20.
Premier tour :
tmp = (*list)->next // On sauvegarde dans tmp le reste de la liste pour laisser juste 10.
ensuite (*list)->next = next //donc NULL pour le début.
next = *list; // next = 10 maintenant.
*list = tmp; // la liste est égal au reste donc le début est maintenant 15.
Deuxième tour :
tmp = (*list)->next // On sauvegarde dans tmp le reste de la liste pour laisser juste 15.
(*list)->next = next // vaut maintenant 10
next = *list; // next = 15 maintenant.
*list = tmp; // la liste est égal au reste donc le début est maintenant 20.
Dernier tour :
tmp = (*list)->next // On sauvegarde dans tmp le reste de la liste pour laisser juste 20.
(*list)->next = next // vaut maintenant 15.
next = *list; // next = 20 maintenant.
*list = tmp; // la liste est égal au reste donc le début est maintenant NULL.
donc à la fin de la boucle on ajoute *list = next pour spécifier que le début vaut 20.
@@nassimamrane5052
En effet, à chaque tour de boucle,
next va contenir les valeurs dans l'ordre.
Mais chaque valeur de next est utilisée
dans le tour de boucle suivant.
Par exemple, si je prends la liste [10, 15, 20],
Avant de rentrer dans la boucle:
next = NULL,
tmp = ?,
la liste vaut [10, 15, 20]
Premier tour de boucle:
*list != NULL donc on entre dans la boucle,
tmp = (*list)->next donc tmp = [15, 20]
(*list)->next = next donc (*list) = [10]
next = *list donc next = [10]
*list = tmp donc (*list) = [15, 20]
Deuxième tour de boucle:
*list != NULL donc on entre dans la boucle,
tmp = (*list)->next donc tmp = [20]
(*list)->next = next donc (*list) = [15, 10]
next = *list donc next = [15, 10]
*list = tmp donc (*list) = [20]
Troisième tour de boucle:
*list != NULL donc on entre dans la boucle,
tmp = (*list)->next donc tmp = NULL
(*list)->next = next donc (*list) = [20, 15, 10]
next = *list donc next = [20, 15, 10]
*list = tmp donc (*list) = NULL
Quatrième tour de boucle:
*list == NULL donc on entre pas dans la boucle
enfin *list = next donc *list = [20, 15, 10]
La liste est bien inversée :)
@@codingoverflow D'accord ok je vois bien maintenant mdrr super merci
@@nassimamrane5052 Avec plaisir :)
first