[Points clés du langage C (4)] « Essai en huit parties » intégré (1)

1. Allocation de mémoire du programme

  • ① Pile : gérée par le compilateur, automatiquement allouée et libérée, et stocke
    divers paramètres, variables locales, valeurs de retour et adresses de retour de fonction lors des appels de fonction.

  • ② Tas : utilisé par le programme pour demander dynamiquement l'allocation et la libération d'espace (malloc et free).
    L'espace appliqué par le programmeur doit être libéré après utilisation et le programme le récupérera automatiquement.
    ✔ 如何记忆?自己申请的东西不要了就丢垃圾堆,垃圾堆需要自己收拾;客栈的东西出钱了由老板收拾,不需要自己动手。(嘿嘿嘿,生动形象吧!!!)

  • ③Segment de données : stocke principalement les variables globales et les variables statiques. divisé en parties suivantes

  • Segment.data de données initialisées : variables globales initialisées et variables statiques

  • Section de données non initialisées.bss : variables globales non initialisées et variables statiques

  • Segment de données en lecture seule.rodata : constante en lecture seule
    ✔ 这里可能有误,百度的各种说明中,个人感觉很多分类得不是很清晰,比较容易混淆,这里给出的是整理之后比较清晰的版本,如有错误,敬请读者批评指正。详细见下图。

  • ⑤Segment de code : stocke le code binaire du programme.
    Insérer la description de l'image ici

[Questions d'entretien réelles 2024·Une entreprise 100-499 à Guangzhou]
Insérer la description de l'image ici

2. Quelle est la cause du débordement de pile ?

(递归层次深、动态申请内存未释放、数组越界、指针非法访问)
Réponse : ① Le niveau d'appels de fonctions récursifs est trop profond et les variables locales de chaque appel récursif doivent être enregistrées dans la pile. Lorsque le niveau d'appels récursifs est trop profond, cela entraînera un débordement de pile ; ② Les variables appliquées dynamiquement
sont enregistré dans le tas et doit être ajouté manuellement une fois l'appel terminé. Relâchez, sinon cela provoquera également un débordement du tas; ③L'indice du tableau
est hors limites;
④Le pointeur accède à une adresse mémoire illégale.

3. Quelle est la compréhension du mot-clé const ?

Réponse : Fonction : Limiter ou restreindre les variables et les constantes en lecture seule. Les constantes doivent être initialisées en même temps lorsqu'elles sont définies.
Utilisez et comprenez comme suit :

#include <stdio.h>
int main(){
    
    
    int val = 100;
    int valNew = 200;

    int *p1 = &val;
    int const *p2 = &val;   //p2的值只读(*p2),不能修改
    int *const p3 = &val;   //p3只读,不能修改
    int const *const p4 = &val;   //p4和*p4只读,不能修改
    printf("p1=%d,p2=%d,p3=%d\n",*p1,*p2,*p3);

    /** p1的值和指向可以被修改 **/
     p1 = &valNew;      /* OK */
    *p1 = 300;          /* OK */
    /** p2的值只读不能修改,指针指向可以修改 **/
     p2 = &valNew;      /* OK */
    *p2 = 300;          /* ERROR */
    /** p3只读不能修改,p3的值(*p3)可以修改 **/
     p3 = &valNew;      /* ERROR */
    *p3 = 300;          /* OK */
    /** p4的的值和指向均只读不能修改 **/
     p4 = &valNew;      /* ERROR */
    *p4 = 300;          /* ERROR */
    printf("p1=%d,p2=%d,p3=%d\n",*p1,*p2,*p3);
    return 0;
}

4. Quelle est la fonction du mot clé static ?

Réponse : ① Modification statique des variables globales : initialiser une seule fois et empêcher la variable d'être référencée dans d'autres fichiers. À ce stade, la portée de la variable globale est le fichier actuel ;
Modification statique des variables locales : des variables locales ordinaires sont utilisées une fois la fonction exécutée, sera détruit et l'espace mémoire des variables locales modifié avec static existera jusqu'à la fin du programme. Cela signifie qu'à chaque fois que la fonction est appelée, la valeur de la variable ne sera ni écrasée ni réinitialisée et la persistance de la valeur de la variable peut être obtenue.
Fonction statique modifiée : indique que la portée de la fonction est dans le fichier de déclaration actuel.

5. Quelle est la fonction du mot clé externe ?

Réponse : Déclarez une variable définie dans un fichier externe (importé). Si extern déclare une variable globale, le compilateur introduira automatiquement la variable dans d'autres fichiers sources .c du projet ; extern peut également introduire des fonctions définies en externe, ce qui équivaut à inclure le fichier d'en-tête correspondant . (Présentation des variables externes et des fonctions externes)

6. Quelle est la différence entre sizeof et strlen ?

  • sizeof est un mot-clé en langage C, utilisé pour calculer le nombre d'octets de mémoire occupés par un type de données ou une variable.
  • strlen est une fonction en langage C, utilisée pour calculer la longueur d'une chaîne, c'est-à-dire le nombre de caractères valides.
  • Lors du calcul de la taille d'une chaîne, sizeof contient le caractère de fin '\0' de la chaîne et strlen ne contient pas '\0'.
  • L'opérateur sizeof est complété au moment de la compilation et renvoie une expression constante, dont le résultat est déterminé au moment de la compilation ; la fonction strlen calcule dynamiquement la longueur de la chaîne entrante au moment de l'exécution et renvoie les caractères valides du nombre.

7. "Pièges" de strlen("\0") et sizeof("\0")

Écrivez le résultat du programme suivant :

a = 0,b = 2,a1段错误,b1 = 4
Insérer la description de l'image ici

8. Qu'est-ce que la précompilation et quand est-elle nécessaire ?

Réponse : ① Traitez les instructions commençant par # avant la compilation, par exemple : #include le compilateur copiera le code du fichier d'en-tête inclus ; #define le remplacement de la définition de macro ; et le traitement des conditions #ifndef . Les directives de précompilation peuvent être placées n'importe où dans le programme.
② Pour les codes volumineux qui sont souvent utilisés mais peu modifiés, le programme se compose de plusieurs modules et tous les modules utilisent les mêmes options de compilation. Dans ce cas, le fichier d'inclusion peut être précompilé dans un en-tête précompilé.

9. Quelle est la différence entre les opérateurs précompilés # et ## en langage C ?

  • # (opérateur de stringification) :
  • Utilisé pour convertir les paramètres de macro en constantes de chaîne.
  • Exemple : Supposons qu'il existe une définition de macro #define STR(x) #x, lorsque cette macro est utilisée, STR(test) sera étendu à la constante de chaîne "test".
  • ## (opérateur de concaténation) :
  • Utilisé pour joindre deux logos ensemble pour former un nouveau logo.
  • Exemple : Supposons qu'il existe une définition de macro #define CONCAT(x, y) x##y, lorsque cette macro est utilisée, CONCAT(a, b) sera remplacée par l'identifiant ab.
  • Tel que le code suivant :
#include <stdio.h>

#define TEST1(S)        (#S)
#define TEST2(S1,S2)    (S1 ## S2)

int main(){
    
    
    char *ab = "HelloWorld";
    printf("%s\n",TEST1(1));
    printf("%s\n", TEST2(a,b));
    return 0;
}

Insérer la description de l'image ici

10. Comment éviter que les fichiers d'en-tête soient inclus à plusieurs reprises ?

  • Utilisez #ifndef, #define et #endif

11. Les variables locales et toutes les variables peuvent-elles avoir le même nom ?

Réponse : Oui, les variables locales protégeront les variables globales . Lorsqu'une variable locale et une variable globale portent le même nom et que la variable est référencée dans une fonction, la variable locale du même nom sera utilisée à la place de la variable globale. (En C++, vous pouvez utiliser l'opérateur de résolution de portée : pour définir la distinction)

12. Combien d'octets un pointeur occupe-t-il en mémoire ?

Réponse : Le nombre d'octets occupés par le pointeur est lié au nombre de bits dans le bus d'adresses. Un pointeur de bus d'adresses de 32 bits occupe 4 octets ; un pointeur de bus d'adresses de 64 bits occupe 8 octets.

13. Veuillez écrire une macro standard MIN pour transmettre deux paramètres et renvoyer le plus petit.

  • #définir MIN(A,B) ((A) <= (B) ? (A) : (B))

14. Donnez les définitions des variables suivantes

定义一个整型数 int a;
定义一个指向整型数的指针 int *a;
定义一个指向指针的指针,它指向的指针指向一个整型数 int **a;
定义一个有10个整型数的数组 int a[10];
定义一个有10个指针的数组,每个指针指向一个整型数 int *p[10];
定义一个指向有10个整型数的数组的指针 int (*p)[10];
定义一个指向指针的指针,被指向的指针指向一个有10个整型数的数组 int *(*p)[10];() / int (**a)[10];(对)
定义一个指向数组的指针,数组中有10个整型指针 int *((*p1)[10]);(我的答案) / int *(*p2)[10];(参考答案)
定义一个指向函数的指针,该函数只有一个整型参数且返回一个整型数 int (*p)(int);
定义一个有10个指针的数组,每个数组指向一个函数,该函数只有一个整型参数且返回一个整型数 int (*p[10])(int);
定义一个函数指针,指向的函数有两个整型参数且返回一个函数指针,返回的函数指针指向有一个整型参数且返回整型数的函数 int(* (*p)(int,int))(int)

15. Alignement des octets de la structure

  • La première adresse de la variable de structure est un multiple entier de la variable membre la plus longue
  • L'espace d'adressage de chaque variable membre doit être aligné
    Insérer la description de l'image ici

Insérer la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/weixin_54429787/article/details/131533881
conseillé
Classement