salut;
je cherche la fonction qui donne le numero d'un caractére dans une chaine de caractéres. je la connais en pascal, c'est "ord" je la veux en c++ svp.
j'attend vos réponces et merci d'avance.
Version imprimable
salut;
je cherche la fonction qui donne le numero d'un caractére dans une chaine de caractéres. je la connais en pascal, c'est "ord" je la veux en c++ svp.
j'attend vos réponces et merci d'avance.
Un caractère en C/C++ peut être considéré comme un entier.
je ne sais pas si cela répond à ton besoin.
Code:
1
2
3
4
5
6
7
8
9
10 #include <iostream> #include <cstdlib> int main(void) { for (char c='a' ; c < 'z' ; c++) { std::cout << "caractere " << c << " --> " << int(c) << std::endl; } return EXIT_SUCCESS; }
C'est du CCode:int(c)
C'est du C++Code:static_cast<int>(c)
Par miracle, c'est aussi du C++ :)
Et c'est pas très beau :)
Pour le coup, utiliser static_cast<>() est certes plus sûr, mais vu la complexité du code original, c'est vraiment exagéré. Il faut quand même se rappeler qu'en tant que programmeurs, on a l'obligation de programmer à destination des autres programmeurs, et non pas à destination de la machine, pour lui faire plaisir. Et au vu de la différence de lisibilité, le clou int(C) n'a pas besoin d'être déchiqueté par l'arme atomique static_cast<>() :)
Sinon, il y a :
Il n'y a pas besoin de cast, grâce aux règles de promotion vers les entiers.Code:
1
2
3 char c = '$'; int ic = c;
Tout comme les macros et autres héritages du C, c'est pas pour ça qu'il est recommandé de les utilisés.Citation:
Par miracle, c'est aussi du C++
Certains designer outre atlantique ne dirais pas la même choses :mrgreen:Citation:
Et c'est pas très beau
Je trouve justement (personnellement) que le "cast à la C++" est plus lisible qu'un cast C, dans un contexte simple et plus complexe. En posant les yeux sur le code, on observe directement qu'il y a un transtypage sans même lire en détail.Citation:
Il faut quand même se rappeler qu'en tant que programmeurs, on a l'obligation de programmer à destination des autres programmeurs, et non pas à destination de la machine, pour lui faire plaisir
C'est juste une habitude, ça ne mange pas de pain, tout est fait à la compilation.Citation:
Et au vu de la différence de lisibilité, le clou int(C) n'a pas besoin d'être déchiqueté par l'arme atomique static_cast<>()
Dans un petit programme comme celui là d'accord, mais si le code venais à évoluer dans un programme plus conséquent et complexe? Mais il vaut mieux prendre de bonne habitude plutôt que d'apprendre à utilisé des restes d'évolutions. Connaitre leurs existences et leurs utilisations oui, savoir pourquoi il existe et leurs limites encore mieux.
Tu as raison.
En C le cast aurait été écrit (int) c.
La notation fonctionnelle int(c) pour le cast est du c++, pas du c.
D'ailleurs il font bien la différence entre les deux cast (functional et c-like) dans
http://www.cplusplus.com/doc/tutorial/typecasting/
pour s'en convaincre un peu plusCitation:
Explicit conversion
C++ is a strong-typed language. Many conversions, specially those that imply a different interpretation of the value, require an explicit conversion. We have already seen two notations for explicit type conversion: functional and c-like casting:
Code:
1
2
3
4 short a=2000; int b; b = (int) a; // c-like cast notation b = int (a); // functional notation
Ne compile tout simplement pas avec gcc (compilateur C), la ligne 10 correspond au cast fonctionnel.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <stdio.h> #include <stdlib.h> int main(int argc, char * argv[]) { char a = 'c'; int b = a; int c; c = (int) a; int d; d = int(a); printf("%c %d %d %d\n",a,b,c,d); return EXIT_SUCCESS; }
Par contre avec g++ (compilateur C++), ça passe comme une lettre à la poste.Citation:
test.c: In function ‘main’:
test.c:10: error: expected expression before ‘int’
C'est moi ou c'est une ressemblance, voir exactement, une construction par copie du int? Où bien c'est une choses différente au vu du compilateur?Code:b = int(a);
Cela voudrais dire, création de int puis affectation. Dans le cas d'un cast C++ static_cast<int> qu'elle aurait été la différence?
Edit: En répondant par avance à ma question, le code machine n'a aucune différence, donc ne serais-ce que juste un différence syntaxique? Sans parler des check à la compilation.
Code:
1
2
3
4
5
6
7
8
9 b = (int) a; // c-like cast notation 01011034 movsx ecx,word ptr [a] 01011038 mov dword ptr [b],ecx b = int (a); // functional notation 0101103B movsx edx,word ptr [a] 0101103F mov dword ptr [b],edx c = static_cast<int>(a); 01011042 movsx eax,word ptr [a] 01011046 mov dword ptr [c],eax
C'est toi. Une construction par copie d'un int, c'est
Code:
1
2 int b(a);
Citation:
Dans le cas d'un cast C++ static_cast<int> qu'elle aurait été la différence?
Edit: En répondant par avance à ma question, le code machine n'a aucune différence, donc ne serais-ce que juste un différence syntaxique? Sans parler des check à la compilation.
Code:
1
2
3
4
5
6
7
8
9 b = (int) a; // c-like cast notation 01011034 movsx ecx,word ptr [a] 01011038 mov dword ptr [b],ecx b = int (a); // functional notation 0101103B movsx edx,word ptr [a] 0101103F mov dword ptr [b],edx c = static_cast<int>(a); 01011042 movsx eax,word ptr [a] 01011046 mov dword ptr [c],eax
est simplement une autre expression syntaxique deCode:b = int(a);
et cette derniere forme est la premiere valide(*) d'une serie d'interpretations exprimables avec les casts C++ -- const_cast, static_cast, const_cast(static_cast), reinterpret_cast, const_cast (reinterpret_cast) -- dans le cas present, c'est un static_cast. Pas etonnant donc qu'au final tu te retrouves avec exactement le meme code.Code:b = (int)a;
(*) Pour etre complet, il y a aussi des choses qui sont possibles avec cette forme qui ne le sont pas avec les casts C++.
Personnellement, j'aurais tendance à penser qu'on appelle explicitement un constructeur par copie pour créer un int temporaire, qui est affecté à b ; ensuite, cet int temporaire est automatiquement détruit.
Donc, en résumé, nous avons :
- une construction par copie ;
- une affectation ;
- une destruction.
merci bcp pour vos aides:)
Salut,
Le fait est que les cast explicites de C++ ont, justement, l'énorme avantage... d'être explicite...
Si tu sais que tu transtype la variable a, une recherche du texte sur le_cast_adapté<int>(a), même si elle s'effectue sur l'ensemble des fichiers d'un projet, te permettra de retrouver directement uniquement les transtypages recherchés, alors qu'une recherche sur (int) ou sur (a) rajoutera au résultat
- les déclaration de fonction prenant un int en argument (dans le cas de (int) )
- les appels de fonctions auxquelles on passe une variable a (dans le cas de (a) )
Nous avons donc un double avantage pour les casts explicites: ils ne laissent planer aucun doute sur l'objectif poursuivi à la lecture ET il permettent d'obtenir un résultat plus correct lors de la recherche, le tout sans que cela ne prenne plus de temps à l'exécution (du moins pour static_cast et reinterpret_cast).
Je ne peux pas nier que c'est l'impression "naïve" qui peut ressortir de premier abord, mais il faut aussi prendre en compte le (N)RVO qui a de grandes chances d'entrer en jeu et de supprimer les créations / affectations surnuméraires par rapport au moyen le plus efficace de le faire.
De plus, nous sommes beaucoup plus près d'un opérateur de conversion (template <typename T> int operator()(T t) ) que d'un (pesudo) constructeur qui serait utilisé sous la forme de int b(a).
Enfin, si l'on retient l'idée qu'il s'agit d'un pseudo constructeur, et bien que je les utilise régulièrement dans mes listes d'initialisation, je dois reconnaitre que le pseudo constructeur est une possibilité de C++ certes très utile pour éviter la zéro initialisation mais qui me semble, de mon seul (et unique :question:) avis personnel conceptuellement absolument pas naturelle :aie:
Autant je n'ai aucun problème à envisager l'idée de constructeur pour les trois sortes de types définis par l'utilisateur que sont les unions, les structures et les classes, autant j'ai vraiment énormément de mal à l'envisager pour les type primitifs, qui ne sont même pas à ranger dans le rayon des types définis par l'utilisateur :aie:
Reprenons. Par définition le constructeur de copie est un constructeur qui prend en premier paramètre une référence (éventuellement qualifiée) vers objet de même type que celui construit et qui a des valeurs par défaut pour les éventuels autres arguments.
La notation T(x) est généralement utilisée quand le type de x n'est pas le type de T, donc en général elle ne peut pas être considérée comme un appel au constructeur de copie. Et la norme défini cette notation comme étant l'équivalent de (T)x et non d'un appel à un constructeur, qu'il soit de copie ou non. (La norme défini T(x, y, z) comme étant la construction d'un objet temporaire). Si on poursuit la chaîne de définition plus en avant, dans certains cas (T)x est bien défini en fonction du constructeur de T prenant un objet du type de x en paramètre, mais d'autres cas sont possibles. Dans l'exemple suivant, les constructeurs de copie n'interviennent nulle part.
Le fait qu'il soit parfois possible d'élider des constructeurs de copie (que ce soit avec la (N)RVO ou pour d'autres raisons) n'intervient pas.Code:
1
2
3
4
5
6
7 struct Y {}; struct X { operator Y() const; }; ... X x; Y y; y = Y(x);