1
votes

Le compilateur avertit que ma fonction ne s'exécutera jamais

J'ai défini une fonction appelée checkrow, qui lit un élément donné d'un tableau char (alimenté par un pointeur vers char) et détermine s'il est égal à certains caractères. Lorsque je compile mon programme global, le compilateur me dit que la ligne 67, qui est (if (* pInput == ('' || '\ t' || '\ n'))) sera ne jamais exécuter. Pourquoi? La logique me semble logique. Ci-dessous le code.

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

int checkRow(char *pArray);

int main (void){

    char c = 0;
    int high = 0;
    int low = 9;
    int checksum = 0;
    char input[3000];
    char *pInput = input;
    FILE *pFile = NULL;

    pFile = fopen("foo.txt", "r");
    if (pFile == NULL){
        printf("failed to open file\n");
        return (-1);
    }

    while((c = fgetc(pFile)) != EOF){
        *pInput = c;
        ++pInput;
    }

    fclose(pFile);
    pFile = NULL;
    pInput = input; //point pInput back to the address of the first element of input
    //printf("the checksum is %d\n", checksum(pInput));
    while(*pInput){

        if(checkRow(pInput) == 0){
            checksum += (high - low);
            ++pInput;
            continue;
        }
        else{
            if((*pInput - '0') > high && (*pInput - '0') < low){
            high = *pInput - '0';
            low = *pInput - '0';
            ++pInput;
            continue;
            }
            else if (*pInput - '0' > high){
            high = *pInput - '0';
            ++pInput;
            continue;
            }
            else if(*pInput - '0' < low){
            low = *pInput - '0';
            ++pInput;
            }
        }

    }

    printf("this is the checksum %d\n", checksum);
    getchar();
    return 0;
}

int checkRow(char *pInput){

    int in = 0;

    if(*pInput == (' ' || '\t' || '\n'))
        in = 0;
    else
        in = 1;
    return in;
}

c

11 commentaires

* pInput == ('' || '\ t' || '\ n') ne fait pas du tout ce que vous pensez. Vous devriez rechercher ce que font ces opérateurs.


|| passe entre des expressions logiques, pas entre des constantes auxquelles vous voulez comparer.


@EugeneSh C'est vrai, mais comment se fait-il que la ligne ne soit jamais exécutée? Le compilateur sait que le pointeur ne peut jamais être (probablement) 1? Cela empêcherait l'exécution de la ligne next ...


La bonne façon de faire est de if ((* pInput == '') || (* Input == '\ t') || (* Input == '\')) {..}


@Yunnosch Je pense que l'OP a en quelque sorte déformé l'avertissement d'origine.


@EugeneSh. Possible.


Quel compilateur utilisez-vous et comment compilez-vous? Je ne reçois pas d'avertissement tel qu'il est écrit. (Bien que d'autres aient raison concernant l ' intention de la déclaration est écrite de manière incorrecte).


On dirait que la fonction isspace () dans vous serait utile


OT: pour faciliter la lisibilité et la compréhension: 1) veuillez indenter systématiquement le code. Retrait après chaque accolade ouvrante '{'. Annuler l'indentation avant chaque accolade fermante '}'. Suggérer que chaque niveau de retrait comporte 4 espaces. 2) blocs de code séparés: pour si else tandis que faire ... pendant switch case default via une seule ligne vierge. 3) séparer les fonctions par 2 ou 3 lignes vides (être cohérent)


concernant: while ((c = fgetc (pFile))! = EOF) { la fonction: fgetc () renvoie un int et EOF est un int . donc la variable c doit être déclarée comme un int , pas comme un char . Lors de la compilation, activez toujours les avertissements, puis corrigez ces avertissements. (pour gcc , utilisez au minimum: -Wall -Wextra -Wconversion -pedantic -std = gnu11 ) Remarque: d'autres compilateurs utilisent des options différentes pour produire la même chose


OT: concernant: printf ("failed to open file \ n"); les messages d'erreur doivent être envoyés à stderr , pas à stdout et lorsque le L'erreur provient d'une fonction de bibliothèque C, alors doit également afficher (dans stderr ) le texte de la raison pour laquelle le système pense que l'erreur s'est produite. La fonction: perror () gère correctement les deux opérations ci-dessus


3 Réponses :


4
votes

Cela ne veut pas dire que l'instruction ne sera pas exécutée, juste des expressions spécifiques qu'elle contient. Le message d'avertissement ressemble à ceci:

testcompare.c:67:35: warning: code will never be executed [-Wunreachable-code]
    if(*pInput == (' ' || '\t' || '\n'))
                                  ^~~~
testcompare.c:67:27: warning: code will never be executed [-Wunreachable-code]
    if(*pInput == (' ' || '\t' || '\n'))
                          ^~~~

Remarquez les flèches pointant vers '\ n' et '\ t' , voilà ce que il dit ne sera jamais exécuté.

L'opérateur || est un opérateur de court-circuit, il n'exécute l'opérande droit que si l'opérande gauche est faux.

Dans ce cas, puisque le '' est une constante, et il est connu pour être véridique (tout char autre que '\ 0' est la vérité), les deux autres opérandes n'ont pas besoin d'être exécutés pour déterminer le résultat.


0 commentaires

1
votes

Vous devrez réécrire l'expression:

if ( strchr(" \t\n" , *pInput) != NULL)

comme

if(*pInput ==' ' || *pInput =='\t' || *pInput =='\n'))

ou

if(*pInput == (' ' || '\t' || '\n'))


0 commentaires

0
votes

L'opérateur || évalue son deuxième opérande uniquement si le premier opérande vaut 0.

Donc dans '' || '\ t' || '\ n' le dernier opérande n'est jamais évalué car '' || '\ t' est différent de zéro.

D'un autre côté, vous voulez écrire quelque chose comme

while((c = fgetc(pFile)) != EOF){
    *pInput = c;
    ++pInput;
}

fclose(pFile);
pFile = NULL;
*pInput = 0;       /* THIS IS IMPORTANT */
pInput = input;  

while(*pInput)

Autre erreur que vous avez faite , vous avez oublié d'insérer le 0 final dans la chaîne input

(*pInput == ' ') || (*pInput == '\t') || (*pInput == '\n')


0 commentaires