Quelques questions sur l'attribution de valeurs aux variables et aux tableaux en langage C

Cet article présente des zones sujettes aux erreurs lorsque j'ai appris le langage C pour la première fois, alors je l'ai enregistré.
Cela devrait être utile pour les étudiants qui sont nouveaux dans le langage C.

1. Scanf absorbe les retours chariot lors de la saisie de caractères

Commençons par la question suivante

Tri ASCII

Après avoir entré trois caractères, sortez les trois caractères dans l'ordre du code ASCII de chaque caractère de petit à grand.

Contribution

Il existe plusieurs groupes de données d'entrée, chaque groupe occupe une ligne et se compose de trois caractères sans espaces.

Production

Pour chaque groupe de données d'entrée, une ligne est sortie et les caractères sont séparés par un espace.

Exemple d'entrée

qwe
asd
zxc

Exemple de sortie

EQW
annonces
cxz

Code

#include <cstdio>
#include <algorithm>
using namespace std;

int main(void)
{
    
    
    char a[3];
    while (scanf("%c%c%c", &a[0], &a[1], &a[2]) != EOF) {
    
    
        getchar();
        sort(a, a + 3);
        printf("%c %c %c\n", a[0], a[1], a[2]);
    }
    
    return 0;
}

Lorsque vous faites ce problème, il est facile d'ignorer le getchar () sur la ligne 9, vous constaterez alors que la sortie est un peu étrange.

Explication de scanf () et getchar ()

  1. Lors de la lecture des données du clavier en langage C, il s'agit généralement d'une entrée de données avec un tampon, et vous devez appuyer sur la touche Entrée pour terminer la confirmation d'entrée des données "ligne". ① Scanf () ignorera automatiquement les caractères vierges précédents lors de la lecture des données de valeur ou des chaînes de caractères (les caractères vierges se réfèrent à: retour chariot, espace, touche TAB), c'est-à-dire qu'il recommencera la lecture à partir du premier caractère non vide et rencontrera à nouveau un espace vide Le caractère termine la saisie de ce type de données. ② Lorsque scanf () lit les données de caractères, les caractères vierges sont également lus.

  2. Dans la 8ème ligne de code, il y a trois fonctions scanf () qui lisent les caractères. Le caractère de retour chariot à la fin de l'entrée "eqw" dans la première ligne restera dans le tampon d'entrée. Par conséquent, le retour chariot sera lu lorsque la fonction d'opération "caractère" suivante (getchar (), scanf ("% c"), gets (), etc.) est exécutée.

  3. Par conséquent, la question de savoir si scanf () doit être suivi d'un getchar () pour absorber les retours chariot dépend du type de données d'entrée suivantes. S'il s'agit d'une opération de lecture de caractères, il existe de nombreuses façons de la gérer.

  4. Quant à la fonction scanf (), elle mérite notre compréhension approfondie.

2. Le '\ 0' à la fin de la chaîne

Nous commençons également à introduire à partir des sujets suivants

Conversion binaire

Entrez
un entier n, (-2 ^ 31 <n <2 ^ 31)

La sortie
convertit n en nombre binaire correspondant et génère la longueur binaire convertie et la séquence de nombres binaires

Exemple d'entrée
5

Exemple de sortie
101

Code

L'idée de base est d'utiliser une division courte pour trouver le reste de 2 à chaque fois, le stocker dans un tableau et enfin la sortie dans l'ordre inverse sous forme de nombre binaire

Code d'erreur initial

#include <stdio.h>
#include <string.h>

int main(void)
{
    
    
    int n, len, i = 0;
    char a[50];
    
    scanf("%d", &n);
    while(n != 0){
    
     
        a[i++] = n % 2 + '0';
        n /= 2;
    }
    len = strlen(a);
    printf("二进制数长度:%d\n", len);
    printf("二进制数:");
    for (i = len - 1; i >= 0; i--)
    	printf("%c", a[i]);
    puts("");
    
    return 0;
}

La sortie lors de la saisie de 5:
Insérez la description de l'image ici

Quelques explications sur strlen () et printf ("% s",)

  1. Exécutez le code ci-dessus, vous constaterez que le len de sortie est supérieur à la longueur réelle et que le nombre binaire de sortie est également brouillé.
  2. Parce que gets () ou scanf ("% s", str) ajoutera automatiquement '\ 0' à la fin de str après la fin de l'entrée, et si un seul caractère est assigné comme ci-dessus, il n'y a pas de '\ 0' à la fin de str.
  3. Le paramètre de la fonction strlen () doit être une chaîne, strlen juge la fin de la chaîne en fonction de '\ 0', donc lorsque la fin n'est pas 0, la mémoire en dehors de str sera lue pour rendre la valeur de len supérieure à la valeur réelle La valeur de la chaîne, produisant ainsi des caractères déformés.
  4. Utilisez printf ("% s \ n", str); la même chose est vraie lors de la sortie de str. Il lira caractère par caractère jusqu'à ce qu'il atteigne '\ 0', mais il n'y a pas de '\ 0 à la fin de str. ', il lira la mémoire autre que str et affichera des caractères déformés.
  5. Solution: ①Ouvrez le tableau directement en dehors de la fonction principale, le tableau sera tous initialisé à 0 ②Parce que le code ASCII de '\ 0' est 0, nous pouvons changer la 7ème ligne en char a [50] = {0} ; Cela initialisera chaque élément à 0.

Solution①

#include <stdio.h>
#include <string.h>

char a[50];

int main(void)
{
    
    
    int n, len, i = 0;
    
    scanf("%d", &n);
    while(n != 0){
    
     
        a[i++] = n % 2 + '0';
        n /= 2;
    }
    len = strlen(a);
    printf("二进制数长度:%d\n", len);
    printf("二进制数:");
    for (i = len - 1; i >= 0; i--)
    	printf("%c", a[i]);
    puts("");
    
    return 0;
}

Insérez la description de l'image ici

Solution ②

#include <stdio.h>
#include <string.h>

int main(void)
{
    
    
    int n, len, i = 0;
    char a[50] = {
    
    0};
    
    scanf("%d", &n);
    while(n != 0){
    
     
        a[i++] = n % 2 + '0';
        n /= 2;
    }
    len = strlen(a);
    printf("二进制数长度:%d\n", len);
    printf("二进制数:");
    for (i = len - 1; i >= 0; i--)
    	printf("%c", a[i]);
    puts("");
    
    return 0;
}

Insérez la description de l'image ici

Méthode d'écriture améliorée plus tard, utilisez directement len ​​comme indice pour enregistrer la longueur du tableau

#include <stdio.h>
#include <string.h>

int main(void)
{
    
    
    int n, len = 0, i;
    char a[50];
    
    scanf("%d", &n);
    while(n != 0){
    
     
        a[len++] = n % 2 + '0';
        n /= 2;
    }
    
    printf("二进制数长度:%d\n", len);
    printf("二进制数:");
    for (i = len - 1; i >= 0; i--)
    	printf("%c", a[i]);
    puts("");
    
    return 0;
}

3. L'affectation initiale du langage C au tableau comporte les dispositions suivantes

  1. Vous ne pouvez attribuer des valeurs initiales qu'à certains éléments. Lorsque le nombre de valeurs dans {} est inférieur au nombre d'éléments, seule la partie précédente des éléments est affectée. Par exemple: int a [10] = {0,1,2,3,4}; signifie que seuls 5 éléments d'un [0] ~ a ​​[4] sont attribués et que les 5 éléments suivants reçoivent automatiquement la valeur 0.
  2. Vous ne pouvez attribuer des valeurs aux éléments qu'un par un, pas à l'ensemble du tableau. Par exemple, pour attribuer 1 valeur aux dix éléments, il ne peut être écrit que: int a
    [10] = {1,1,1,1,1,1,1,1,1,1}; mais ne peut pas être écrit comme: int a [10] = 1;
  3. Si vous attribuez des valeurs à tous les éléments, le nombre d'éléments du tableau peut ne pas être indiqué dans la description du tableau. Par exemple: int a [5] =
    {1,2,3,4,5}; peut s'écrire: int a [] = {1,2,3,4,5}; l'affectation dynamique peut être en cours d'exécution du programme, Attribuez dynamiquement des
    valeurs au tableau . À ce stade, l'instruction de boucle peut être utilisée avec la fonction scanf pour affecter des valeurs aux éléments du tableau un par un.

4. Pour les tableaux non initialisés

  1. Pour les tableaux locaux:
    ① int a [100]; Cette méthode d'écriture n'est pas initialisée, donc 100 éléments sont tous des valeurs de garbage machine;
    ② int a [100] = {0, 2, 3}; Cette méthode d'écriture en premier 3 Chaque élément est initialisé à 0, 2, 3 et le reste est mis à 0;
    ③ int a [100] = {0}; Cette méthode d'écriture initialise les 100 éléments à 0.
  2. Pour les tableaux globaux ou modifiés en tant que propriétés statiques:
    s'ils sont initialisés, c'est le même que ci-dessus ②, ③; s'ils ne sont pas initialisés, tous les éléments sont automatiquement mis à 0.

5. Pour les variables qui ne sont pas initialisées

  1. Seules les variables globales et les variables statiques seront automatiquement initialisées à 0.

  2. Les variables locales ordinaires, si elles ne sont pas initialisées, sont des données aléatoires.

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43772166/article/details/88556177
conseillé
Classement