IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Quelques précisions. . .


Sujet :

C

  1. #101
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par Array Voir le message
    Thierry, pour ta fonction, je vais l'enregistrer dans un fichier, mais il me reste à aborder les pointeurs, et donc, j'ai de la difficulté à la comprendre, faute de connaissances... Je tâcherai de lire...
    Merci,

    Cordialement,

    Array
    Il y a des cas où ce type de techniques peut être très intéressant. L'exemple de la fonction qsort() en est un exemple. Les structures de données de la GLib en sont un autre. A l'inverse, vouloir rendre son code générique peut, selon les cas, rendre un programme inutilement complexe et ainsi nuire à sa lisibilité. Comme toujours en programmation, le bon sens est roi: "Keep it short and simple!" est une stratégie souvent gagnante. Pose des questions si tu ne comprends pas.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  2. #102
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Citation Envoyé par Thierry
    Il y a des cas où ce type de techniques peut être très intéressant. L'exemple de la fonction qsort() en est un exemple. Les structures de données de la GLib en sont un autre. A l'inverse, vouloir rendre son code générique peut, selon les cas, rendre un programme inutilement complexe et ainsi nuire à sa lisibilité. Comme toujours en programmation, le bon sens est roi: "Keep it short and simple!" est une stratégie souvent gagnante. Pose des questions si tu ne comprends pas.
    Encore une fois, je te remercie pour le dévouement dont tu fais preuve. Sincèrement, je l'apprécie.


    Voilà j'ai commencé avec les pointeurs et j'aurais quelques petites questions...

    Suis-je exact?:

    Soit les déclarations suivantes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int *ptr;
    int abc;
    [...]
    1- Si je fais *ptr = &abc;
    Le pointeur ptr aura mémorisé l'addresse de "abc", et donc, *ptr représente
    abc.

    2- Si ja fais "ptr = 28;" suivi de "*ptr = 276;", la variable ayant l'adresse "28" aura la valeur "276". Donc, "ptr = x" modifie le pointeur lui-même et "*ptr = 276" modifie la variable ayant le numéro d'addresse enregistré dans "ptr".

    3- &abc représente l'adresse de la variable "abc".

    -----------------------

    4- Cela n'a probablement rien à avoir avec les pointeurs, mais je voudrais également savoir s'il est possible de changer la valeur maximale d'un "int", pour que cela prenne moins de mémoire.

    Par exemple, soit une variable ayant pour déclaration "int i = 23;" et "i" n'irais jamais plus haut que "23", comment pourrais-je donner une valeur maximale à "i", afin d'économiser de la mémoire!?


    Merci,

    Sincèrement,

    Array

  3. #103
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Array Voir le message
    Soit les déclarations suivantes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int *ptr;
    int abc;
    [...]
    1- Si je fais *ptr = &abc;
    Le pointeur ptr aura mémorisé l'addresse de "abc", et donc, *ptr représente
    abc.
    Pour être tout à fait précis, disons que *ptr a la valeur de abc.

    2- Si ja fais "ptr = 28
    Le comportement est indéterminé. Rien ne prouve que la valeur 28 représente une adresse valide.

    Il y a 4 possibilité basiques et portables d'initialiser un pointeur :
    • l'adresse d'une variable.
    • le contenu d'un pointeur valide.
    • la valeur retournée par malloc(). (et ses soeurs)
    • la valeur retournée par fopen(). (type FILE *)


    3- &abc représente l'adresse de la variable "abc".
    C'est pas 'représente', c'est 'a pour valeur et type', ...
    -----------------------
    4- Cela n'a probablement rien à avoir avec les pointeurs, mais je voudrais également savoir s'il est possible de changer la valeur maximale d'un "int", pour que cela prenne moins de mémoire.
    Non. C'est une constante liée à l'implémentation. Il existe de entier de taille diverses... : char, short, int, long... Choisi celui qui te convient...
    Ne te focalise pas trop sur les 'économies de mémoire'. Ca n'a vraiment de sens que pour les gros tableaux...
    Pas de Wi-Fi à la maison : CPL

  4. #104
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Merci Emmanuel pour cette réponse enrichissante.
    Bien que je n'aie pas de problèmes au niveau des pointeurs (du moins pour l'instant), je fais face à un autre problème.

    Voici un programme très très rudimentaire.
    Je l'ai juste fait pour vous illustrer mon problème.


    En gros, le porgramme attend qu'on lui donne une ligne contenant uniquement une division...

    Comme : 18/2

    La fonction getn isiole le 18 et le 2 d'une chaîne de caractères, puis on effectue la division...
    Si l'on entre pas une division ou un chiffre trops gros, il peut arriver toutes sortes d'erreurs. Enfin bref, ce n'est que pour vous montrer de quoi il en est...

    Voici le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
     
    #include <stdlib.h>
    #include <stdio.h>
     
    unsigned long long int getn(char s[], int n);
    int ctoi(int c);
     
    int main(void) {
    	char s[1000];
    	int i = 0;
    	unsigned long long int n,d,q;
    	while (0 == 0) {
    		printf("\n\n\n");
    		fgets(s, 1000, stdin);
    		while (i <= 1000 && s[i] != '\n') {
    			s[i] = ctoi(s[i]);
    			++i;
    		}
    		i = 0;
    		n = getn(s, 1);
    		d = getn(s, 2);
    		q = n/d;
    		printf("n is \"%I64u\"\nd is \"%I64u\"\n", n, d);
    		printf("ANS : %I64u\n", q);
    		q = n - (q * d);
    		printf("MOD : %I64u\n", q);
    	}
    	return 0;
    }
     
    unsigned long long int getn(char s[], int n) {
    	unsigned long long int d;
    	int i = 0;
    	d = 0;
    	int lasti;
    	int ilen;
    	int a = '/';
    	if (n == 1) {
    		a = '/';
    		lasti = 0;
    	}
    	else
    		a = '\n';
    	while (s[i] != a) {
    		if (n > 1) {
    			if (s[i] == '/' && n > 1)
    				lasti = i;
    		}
    		++i;
    	}
    	--i;
    	ilen = i-lasti;
    	while (i >= 0) {
    		if (n > 1 && i == lasti)
    			break;
    		else {
    			d = pow(10, (ilen-(i-lasti))) * s[i] + d;
    			printf("--- d:%I64u\n", d);
    			--i;
    		}
              printf("********\n");
    	}
    	return d;
    }
     
    int ctoi(int c) {
    	if (c == '0')
    		return 0;
    	else if (c == '1')
    		return 1;
    	else if (c == '2')
    		return 2;
    	else if (c == '3')
    		return 3;
    	else if (c == '4')
    		return 4;
    	else if (c == '5')
    		return 5;
    	else if (c == '6')
    		return 6;
    	else if (c == '7')
    		return 7;
    	else if (c == '8')
    		return 8;
    	else if (c == '9')
    		return 9;
    	else
    		return c;
    }
    Pour de simples divisions telles que 18/9, le programme donnera la bonne réponse.

    Cependant, si je lui soumet la division "2222222222222222222/2", il écrit ceci:

    --- d:2
    --- d:22
    --- d:222
    --- d:2222
    --- d:22222
    --- d:222222
    --- d:2222222
    --- d:22222222
    --- d:222222222
    --- d:2222222222
    --- d:22222222222
    --- d:222222222222
    --- d:2222222222222
    --- d:22222222222222
    --- d:222222222222222
    --- d:2222222222222222
    --- d:22222222222222224
    --- d:222222222222222208
    --- d:2222222222222222336
    ********
    --- d:2
    ********
    n is "2222222222222222336"
    d is "2"
    ANS : 1111111111111111168
    MOD : 0
    J'en ai déduit que, dans la formule "d = pow(10, (ilen-(i-lasti))) * s[i] + d;", les chiffres, passé un certain nombre, se corrompent... C'est-à-dire que passé une certaine valeur, les chiffres deviennent erronés...

    Pourquoi!?

    Pourtant, l'équation qui est la cause du problème n'est pas erronée...


    Merci,

    Sincèrement,

    Array

  5. #105
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Array Voir le message
    J'en ai déduit que, dans la formule "d = pow(10, (ilen-(i-lasti))) * s[i] + d;", les chiffres, passé un certain nombre, se corrompent... C'est-à-dire que passé une certaine valeur, les chiffres deviennent erronés...

    Pourquoi!?
    Tu peux déjà corriger ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    Project   : Forums
    Compiler  : GNU GCC Compiler (called directly)
    Directory : C:\dev\forums\
    --------------------------------------------------------------------------------
    Switching to target: default
    Compiling: main.c
    main.c: In function `main':
    main.c:28: warning: will never be executed
    main.c:28: warning: will never be executed
    main.c: In function `getn':
    main.c:57: warning: implicit declaration of function `pow'
    main.c:35: warning: 'lasti' might be used uninitialized in this function
    Linking console executable: console.exe
    Process terminated with status 0 (0 minutes, 6 seconds)
    0 errors, 4 warnings
    Pas de Wi-Fi à la maison : CPL

  6. #106
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Heh.

    Justement, j'allais en parler.

    Comment me débarasser des messages d'erreurs tels que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Intel(R) C++ Compiler for applications running on IA-32, Version 10.0
    Build 20070613 Package ID: W_CC_C_10.0.026
    Copyright (C) 1985-2007 Intel Corporation.  All rights reserved.
    
    original.c
    original.c(56): warning #266: function "pow" declared implicitly
      			d = pow(10, (ilen-(i-lasti))) * s[i] + d;
      			    ^
    
    ipo: remark #11001: performing single-file optimizations
    ipo: remark #11005: generating object file C:\DOCUME~1\YANNIC~1\LOCALS~1\Temp\ipo_1484.obj
    Microsoft (R) Incremental Linker Version 6.00.8168
    Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
    
    -out:original.exe 
    -nodefaultlib:libguide_stats.lib 
    -nodefaultlib:libguide40_stats.lib 
    -defaultlib:libguide.lib 
    C:\DOCUME~1\YANNIC~1\LOCALS~1\Temp\ipo_1484.obj
    Les avertissements de déclarations implicites fusent souvent lorsque je compile... Comment s'en débarasser?


    Merci,

    Array

  7. #107
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Il faut inclure le fichier d'en-tête déclarant la fonction.
    Sans doute <math.h> ici... (sauf que chez M$, certaines fonctions mathématiques sont déclarées dans float.h à la place).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #108
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Merci!

    En effet, c'était bien le fichier math.h.
    J'avais cru entendre que pow() était dans stdlib.h, même s'il me semblait plus logique que ce soit dans math.h.
    Je croyais que si je n'incluais pas le bon fichier d'en-tête standard, le compilateur me retournerais une erreur, ce qui n'est guère le cas.


    D'autre part, une autre question vient de surgir dans ma tête.

    Je désirerais savoir après quelle valeur un nombre ne peut plus être un char?
    Autrement dit, quel est le dernier nombre représentant un "char"?

    Voyez-vous, j'ai un programme qui, lorsqu'il aura passé sur un caractère dans un fichier quelconque, additionnera une valeur à la valeur du char lu et l'emmagasinera dans un tableau de int, de manière à ce que le nombre ne puisse plus être un "char". Je fais cela parce qu'il se peut que, après une première procédure, il revienne en arrière, dans les index précédents du tableau, afin d'effectuer d'autres procédures. Comme ça, avec un if (n > 100000) [par exemple si 100 000 est la valeur que je cherche et "n" représentant le (char + 100 000)], il pourra savoir s'il la déjà classé comme vu et, si oui, faire la soustraction de 100 000 pour avoir le "char" originel.

    Voilà,

    Merci,

    Sincèrement,

    Array

  9. #109
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Array Voir le message
    En effet, c'était bien le fichier math.h.
    J'avais cru entendre que pow() était dans stdlib.h, même s'il me semblait plus logique que ce soit dans math.h.
    Je croyais que si je n'incluais pas le bon fichier d'en-tête standard, le compilateur me retournerais une erreur, ce qui n'est guère le cas.
    Le langage C autorise l'appel sans prototypes, mais le comportement est indéfini. C'est pourquoi la plupart des compilateurs peuvent être réglés pour générer un avertissement en cas d'oubli. C'est ce qu'a fait ton compilateur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    original.c
    original.c(56): warning #266: function "pow" declared implicitly
    Si tu as des doutes sur l'interface, le comportement ou le fichier d'en-tête d'une fonction, le mieux est de lire la doc :

    http://www.opengroup.org/onlinepubs/...tions/pow.html
    Je désirerais savoir après quelle valeur un nombre ne peut plus être un char?
    Autrement dit, quel est le dernier nombre représentant un "char"?
    La valeur d'un char est comprise entre CHAR_MIN et CHAR_MAX. Ces valeurs sont définies dans <limits.h>

    Attention, ces valeurs sont valables pour une implémentation donnée. Elles ne peuvent être utilisées qu'en 'interne'. Si il s'agit de transfert de données (fichiers, réseau), il faut utiliser d'autres conventions, indépendantes du langage et de la machine, et qui correspondent besoins réels (par exemple ASCII : 0-127 etc.).
    Pas de Wi-Fi à la maison : CPL

  10. #110
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Merci.
    J'utiliserai donc (CHAR_MAX + 1)!

    D'autre part...
    Voilà qu'un problème viens encore une fois me frapper de plein fouet!


    Comme dans la fonction call_for_each() de Thierry, j'essaie d'utiliser les pointeurs de type "void".

    Cependant, je fais face à quelques problèmes.

    Soit un code simplet comme celui-ci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int funcn(void *gpln) {
    	int i = 0;
    	while (i <= 4) {
    		printf("%c\n", gpln[i]);
    		++i;
    	}
    	return 0;
    }
     
    int main(void) {
    	char tab[] = "hello";
    	funcn(tab);
    	return 0;
    }
    Évidemment, mon compilateur me retourne une erreur...
    Comment utiliser les index de tableau?
    Comment faire en sorte que ce code fonctionne???!!!

    Une deuxième question fuse également :

    Comment, dans une fonction, savoir le nombre d'éléments passe en argument, par exemple dans ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <stdio.h>
     
    int func(int tab[]) {
           size_t tab_sz;
           [...]
           printf("Size of tab[] : %d\n", tab_sz);
    }
     
    int main(void) {
           int tab[] = "hello";
           func(tab);
    }
    Comment pourrait-on donner la valeur correspondante à la taille du tableau à tab_sz?


    Merci,

    Sincèrement,

    Array

  11. #111
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    308
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 308
    Points : 373
    Points
    373
    Par défaut
    Relis la fonction "for each" de Theirry... Il indique clairement qu'on doit passer en argument : le tableau sous forme de pointeur sur void, la taille de chaque élément du tableau, le nombre d'élément du tableau et un pointeur sur fonction.
    Si tu exécute toujours la même fonction pas besoin d'utiliser le dernier argument, mais les 3 autres sont obligatoires...

  12. #112
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Bien que Thierry utilise ls poineturs void dans sa fonction, je ne comprend pas plus comment les utiliser [ou je ne le vois pas], c'est-à-dire que j'aimerais savoir comment utiliser un tableau en conjonction avec un pointeur "void".

    Comme je disais :

    Soit ce code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    #include <stdio.h>
    #include <stdlib.h>
     
    int funcn(void *gpln) {
    	int i = 0;
    	while (i <= 4) {
    		printf("%c\n", gpln[i]);
    		++i;
    	}
    	return 0;
    }
     
    int main(void) {
    	char tab[] = "hello";
    	funcn(tab);
    	return 0;
    }
    Le compilateur me retourne une erreur.
    Comment utiliser le tableau passé en argument? Comment faire en sorte que le code que j'ai donné en haut écrive le bon mot, soit "hello". gpln[i] semble être une erreur...


    Merci,

    Array

  13. #113
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    308
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 308
    Points : 373
    Points
    373
    Par défaut
    Je t'ai dit de relire la fonction for_each de Thierry.

    Tu vois qu'aux deux fonctions qu'il passe à son for each et qu'il utilise dans son exemple, il passe un pointeur sur void, mais à l'intérieur il fait un cast.

    Cependant, pour pouvoir fonctionner, il faut la fonction qui reçoit l'élément à afficher reçoive l'adresse exacte de l'élément, et ça tu ne peux pas faire autre que d'utiliser deux paramètres qui sont la taille du tableau et la taille de chaque élément.

  14. #114
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Array Voir le message
    Comment utiliser le tableau passé en argument? Comment faire en sorte que le code que j'ai donné en haut écrive le bon mot, soit "hello". gpln[i] semble être une erreur...
    Il suffit de définir un pointeur local du bon type (char *) qui reçoit l'adresse passée en paramètre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int funcn(void *gpln) {
    	int i = 0;
            char *p = gpln;
    	while (i <= 4) {
    		printf("%c\n", p[i]);
    		++i;
    	}
    	return 0;
    }
    Pas de Wi-Fi à la maison : CPL

  15. #115
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Ha, je te remercis!
    Et, en regardant à nouveau sa fonction, je vois la ligne qui aurait pu révéler ma réponse : unsigned char *arr = array;
    Psycho, de quel cast parlais-tu? Le (void *) ?

    Voilà cependant que deux questions surgissent de ma tête et ce, à l'instant!

    1) Dans le code que j'ai posté dans mon dernier post, je ne peux pas faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *p = &gpln[0];
    Car cela, slon GCC ainsi que ICC, déréférence le pointeur void...
    Qu'est-ce que déréférencer et pourquoi je ne peux pas faire "char *p = &gpln[0];", mais seulement "char *p = gpln"? Pourtant, ces deux ligne sont supposées être équivalentes!

    2) Dans le code qu'a envoyé Emmanuel, en haut, c'est-à-dire celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int funcn(void *gpln) {
    	int i = 0;
            char *p = gpln;
    	while (i <= 4) {
    		printf("%c\n", p[i]);
    		++i;
    	}
    	return 0;
    }
    Comment pourrais-je savoir, à l'intérieur de la fonction, si "gpln" est un tableau de "char" ou de "int" ou de "double" ou de quoi que ce soit d'autre?
    Car il faut que j'utilise la ligne si signifiante : "char *p = gpln;".
    Comment, dans cette ligne, déterminer le type de "gpln"!


    Merci,

    Array

  16. #116
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Array Voir le message
    Et, en regardant à nouveau sa fonction, je vois la ligne qui aurait pu révéler ma réponse : unsigned char *arr = array;

    Voilà cependant que deux questions surgissent de ma tête et ce, à l'instant!

    1) Dans le code que j'ai posté dans mon dernier post, je ne peux pas faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *p = &gpln[0];
    Car cela, slon GCC ainsi que ICC, déréférence le pointeur void...
    Qu'est-ce que déréférencer et pourquoi je ne peux pas faire "char *p = &gpln[0];", mais seulement "char *p = gpln"? Pourtant, ces deux ligne sont supposées être équivalentes!
    Un petit rappel sur les pointeurs s'impose...


    http://emmanuel-delahaye.developpez....age=Page5#LXXI
    http://emmanuel-delahaye.developpez....ge=Page5#LXXII

    Le type 'void' n'ayant pas de taille définie (seul l'adresse nous intéresse), le compilateur ne sait pas comment faire le déréférencement (accès à la valeur pointée). Pour ça, il faut un pointeur typé.

    2) Dans le code qu'a envoyé Emmanuel, en haut, c'est-à-dire celui-ci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    int funcn(void *gpln) {
    	int i = 0;
            char *p = gpln;
    	while (i <= 4) {
    		printf("%c\n", p[i]);
    		++i;
    	}
    	return 0;
    }
    Comment pourrais-je savoir, à l'intérieur de la fonction, si "gpln" est un tableau de "char" ou de "int" ou de "double" ou de quoi que ce soit d'autre?
    Car il faut que j'utilise la ligne si signifiante : "char *p = gpln;".
    Comment, dans cette ligne, déterminer le type de "gpln"!
    C'est le revers de la programmation générique. Il n'y a aucun moyen de la savoir. J'ai vu que tu avais passé l'adresse d'un élément de chaine, alors j'ai mis char * (j'aurais d'ailleurs du mettre char const *, passons...).

    C'est au programmeur de savoir ce qu'il fait. Chaque cas est différent, mais bien défini.

    Si il faut gérer plusieurs types, on utilise la technique bien connu de l'union avec sélecteur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    struct
    {
       enum selector = {TA, TB, TC} selector;
       union
       {
           type_a a;
           type_b b;
           type_c c;
       }
    }
    record;
    Pas de Wi-Fi à la maison : CPL

  17. #117
    Membre du Club Avatar de Array
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    210
    Détails du profil
    Informations personnelles :
    Âge : 32
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 210
    Points : 55
    Points
    55
    Par défaut
    Citation Envoyé par Emmanuel Delahaye

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
       char s[]="ab";
       p = s;
     
       :---------:---------:---------:     :---------:--------:
       : adresse : valeur  : valeur  :     : adresse : valeur :
       :         :         : pointée :     :         :        :
       :---------:---------:---------:     :---------:--------:
       : &p      : &s[0]   : 'a'     : --> : s+0     : 'a'    :
       :         : ou s+0  :         :     :---------:--------:
       :         : ou s    :         :     : s+1     : 'b'    :
       :---------:---------:---------:     :---------:--------:
                                           : s+2     : 0      :
                                           :---------:--------:

    Tu le dis toi-même sur ton site!

    Qu'ais-je dis d'incorrect dans cette affirmation? :

    "char *p = &gpln[0];" et "char *p = gpln;" équivalent la même chose...

    Merci,

    Array

  18. #118
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    308
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 308
    Points : 373
    Points
    373
    Par défaut
    Relis son message ! Il dit que le pointeur void pour le compilateur ne veut rien dire, il faut donc faire un cast !
    Caster signifie changer le type d'un objet en un autre, en C il suffit de mettre le type de destination entre parenthèse...
    Le détail important dans le code de Thierry c'est le (unsigned char *)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void fonc(void *ptr) {
        unsigned char *casted = (unsigned char *)ptr;
    }

  19. #119
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Array : Le problème, c'est que gpln[0] ne veut rien dire pour un pointeur void.

    PsychoH13 : Erreur: Le cast est implicite en C:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    void fonc(void *ptr) {
        unsigned char *casted = ptr;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  20. #120
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    308
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 308
    Points : 373
    Points
    373
    Par défaut
    C'était pour lui montrer le principe, et ce n'est pas une erreur, c'est juste pas utile dans ce cas là en tout cas, ce qui est une grosse nuance, rien ne t'empêche d'écrire le cast.

Discussions similaires

  1. Réponses: 1
    Dernier message: 23/12/2007, 19h44
  2. Entrées.. Sorties.. quelques précisions..
    Par Djef-69 dans le forum SL & STL
    Réponses: 2
    Dernier message: 28/11/2007, 23h16
  3. [Fabrique] Quelques Précisions
    Par djflex68 dans le forum Design Patterns
    Réponses: 8
    Dernier message: 20/12/2006, 13h34
  4. Quelques "précisions" sur Struts
    Par Atma_ dans le forum Struts 1
    Réponses: 19
    Dernier message: 03/11/2006, 15h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo