Résumé des questions d'entrevue en langage C intégré

Définition du pointeur

Un pointeur vers un pointeur, le pointeur vers lequel il pointe est un entier
int ** a;
un tableau de 10 pointeurs, le pointeur est un
int * a [10] qui pointe vers un entier ;
un pointeur en a 10 Un pointeur vers un tableau d'entiers
int (* a) [10]
Un pointeur vers une fonction qui a un paramètre entier et renvoie un entier
int * a (int) {}
un tableau de 10 pointeurs, Le pointeur pointe vers une fonction qui a un paramètre entier et renvoie un nombre entier
int (* a [10]) (int) // Des définitions similaires doivent être effectuées par décomposition. Définissez d'abord un pointeur de fonction unique int (* a) (int), puis un tableau de 10 pointeurs int (* a [10]) (int)

Quel est le but du mot-clé static?


1) Dans le corps de la fonction, une variable déclarée statique conserve sa valeur inchangée pendant le processus d'appel de la fonction (la variable est stockée dans la zone des variables statiques).
2) Dans le module (mais en dehors de la fonction), une variable déclarée statique est accessible par les fonctions utilisées dans le module, mais pas par d'autres fonctions extérieures au module. C'est une variable globale locale.
3) Dans un module, une fonction déclarée statique ne peut être appelée que par d'autres fonctions de ce module. Autrement dit, cette fonction est limitée à la portée locale du module où elle est déclarée

Mot-clé const


const int a; constant a
int const a; constant a
const int * a; Le contenu pointé par le pointeur ne peut pas être modifié, mais l'adresse pointée par le pointeur peut être modifiée.
int * const a; L'endroit pointé par le pointeur ne peut pas être changé, mais le contenu de l'adresse pointée peut être changé.
int const * const a; Le contenu de l'adresse pointée par le pointeur et l'adresse pointée par le pointeur ne peuvent pas être modifiés.

Le premier définit le bit 3 de a, le second efface le bit 3 d'un


a | = 1 << 3
a & = 0 << 3
或 BIC a, a, # 0x3

Numéros signés et non signés


8. Quelle est la sortie du code suivant et pourquoi?
void foo (void)
{ unsigned int a = 6; int b = -20; (a + b> 6)? met ("> 6"): met ("<= 6"); } est supérieur à 6. Un nombre signé est converti en un nombre non signé. Nombre non signé: il n'y a pas de différence entre le positif et le négatif, tous les bits sont utilisés pour représenter le nombre lui-même. Nombre signé: le bit le plus élevé est utilisé pour indiquer le positif et le négatif du nombre, le bit le plus élevé est 1 pour indiquer un nombre négatif et le bit le plus élevé est 0 pour indiquer un nombre positif. 1. Convertissez un nombre non signé en nombre signé: voyez si le bit le plus élevé du nombre non signé est 1, s'il n'est pas 1 (c'est-à-dire 0), le nombre signé est directement égal au nombre non signé; 2. Si le nombre non signé est Le bit le plus significatif est 1, le nombre non signé est complété et le nombre obtenu est un nombre signé. 3. Convertissez un nombre signé en un nombre non signé: pour voir si le bit le plus élevé du nombre signé est 1, s'il n'est pas 1 (c'est-à-dire 0), le nombre non signé est directement égal au nombre signé; 4. S'il y a un nombre signé Le bit le plus élevé de est 1, puis le nombre signé sera complété et le nombre obtenu est un nombre non signé, donc 6-20 = -14, car le résultat a débordé en tant que nombre non signé, donc 65536 est ajouté et le résultat devient un Un nombre positif est 65522-5 correspond à un nombre positif 5 (00000101) → tous les bits sont inversés (11111010) → plus 1 (11111011)












\ 0Question

void test1 ()
{ char string [10]; char * str1 = "0123456789"; strcpy (string, str1); } // Débordement et \ 0




void test2 ()
{ char string [10], str1 [10]; int i; for (i = 0; i <10; i ++) { str1 [i] = 'a'; } strcpy (string, str1); } str1 n'a pas de terminateur \ 0 et le programme plante.








void test3 (char * str1)
{ char string [10]; if (strlen (str1) <= 10) { strcpy (string, str1); } } est changé en strlen (str1) <10 Cette méthode ne rapportera pas d'erreur, mais Cela provoquera de graves bogues cachés et modifiera les données de la mémoire.





Veuillez calculer la valeur de sizeof et la valeur de strlen.


void func (char * str)
{ sizeof (str) =? } char str [10] = "bonjour"; strlen (str); 10 和 5




Problème de définition de macro

#include "stdafx.h"
#define SQR (X) X * X
int main (int argc, char * argv [])
{     int a = 10;     int k = 2;     int m = 1;     a / = SQR (k + m) / SQR (k + m);     printf ("% d \ n", a);     return 0; } a = a / (k + m * k + m / k + m * k + m)







Comment juger si un système d'exploitation est 16 bits ou 32 bits lors de l'écriture d'un programme en C? La fonction sizeof () ne peut pas être utilisée.


int a = ~ 0; // 把 位数 全部 设为 1
if (a> 65536)  
{   cout << "32 bits" << endl; } else {   cout << "16 bits" << endl; }





Sans utiliser de paramètres tiers, échangez les valeurs des deux paramètres.


a = a + b;
b = ab;
a = ab;
quelqu'un
a = a ^ b;
b = a ^ b;
a = a ^ b;

Fonctionnement du pointeur

tableau court non signé [] = {1,2,3,4,5,6,7};
int i = 3;
* (tableau + i) =? Le
résultat est 4.

main ()
{ int a [5] = {1,2,3,4,5}; int * ptr = (int *) (& a + 1); // (& a + 1) pointe vers le tableau unidimensionnel suivant printf ("% d,% d", * (a + 1), * (ptr-1)); } Solution: int * ptr = (int *) (& a + 1); & un moyen d'obtenir la première zone de stockage du tableau a Adresse, plus 1 pour indiquer l'adresse de la zone de stockage du tableau a, ce qui fait pointer le pointeur ptr sur l'adresse de l'unité de stockage après le dernier élément du tableau, et une fois ptr soustrait de 1, l'accès aux données est effectué et l'accès est ptr La valeur de l'unité de stockage précédente du pointeur, toute la réponse finale est 2, 5 (int *) (& a + 1) Conversion obligatoire du type de pointeur.







Quelle est la différence entre #include <filename.h> et #include "filename.h"?


<> ira directement au système à traverser
"" parcourra d' abord le fichier d'en-tête dans le projet courant, s'il n'existe pas, ira au cheminement système.
<> peut être changé en "", mais "" ne doit pas être changé en <>

Les types de paramètres qui ne peuvent pas être utilisés pour switch () sont:


Seuls les entiers peuvent être utilisés comme paramètres

Les variables locales peuvent-elles avoir le même nom que les variables globales?


Peut avoir le même nom. Les noms de variables locales remplaceront les noms de variables globales. C ++ peut utiliser la portée pour distinguer.
Les variables globales peuvent-elles être définies dans des fichiers d'en-tête qui peuvent être inclus par plusieurs fichiers .C? Pourquoi?
Non! Mais cela peut être déclaré. Cela implique le problème des symboles forts et des symboles faibles. Pour plus de détails, veuillez consulter le blog suivant.
En langage C, les fonctions et les variables globales initialisées (y compris l'initialisation à 0) sont des symboles forts, et les variables globales non initialisées sont des symboles faibles.
Pour eux, les trois règles suivantes sont utilisées:
① Il ne peut y avoir qu'un seul symbole fort avec le même nom, sinon le compilateur rapportera une erreur de "définition en double".
② Un symbole fort et plusieurs symboles faibles sont autorisés, mais la définition sélectionnera le symbole fort.
③ Lorsqu'il existe plusieurs symboles faibles identiques, l'éditeur de liens choisit celui qui occupe le plus grand espace mémoire.

Une phrase réalise le jugement de savoir si x est une puissance de 2.


if (x & (x-1) == 0)
    printf ("est une puissance de 2");
  else printf ("n'est pas une puissance de 2");

pow (x, y), calculer la puissance y de
x sqrt (x), trouver la racine carrée du nombre à virgule flottante x
fabs (x), trouver la valeur absolue du nombre à virgule flottante x

char * s = "AAA";
printf ("% s", s);
s [0] = 'B';
printf ("% s", s);
Quel est le problème?


La zone constante ne permet pas de modifier le contenu, le résultat reste inchangé. AAA

#define MAX 256
int main ()
{caractère non signé A [MAX], i; pour (i = 0; i <MAX; i ++) A [i] = i; }




Char est un octet, huit bits et le plus grand entier qui peut être représenté est 255, il y a donc une boucle sans fin ici.

35.struct name1
{ char str; court x; int num; } struct name2 { char str; int num; court x; } typedef struct  {     int a;     char b [3];     court d;     int c;  } node; sizeof (struct name1) = 8 sizeof (struct name2) = 12 sizeof (node) = 16




















Alignement d'octets

int main ()
{ char a; char * str = & a; strcpy (str, "bonjour"); printf (str); return 0; }






Aucune mémoire n'est allouée pour a et a est une variable de caractère. La mémoire est hors limites.

Opérations d'adresse et de taille variable

unsigned char * p1;
unsigned long * p2;
p1 = (unsigned char *) 0x801000;
p2 = (unsigned long *) 0x810000; puis-
je demander p1 + 5 = 0x801005; p2 + 5 = 0x810014;
la valeur de p1 + 5 est 801005 , Parce que le caractère de valeur pointé par la variable de pointeur, plus un signifie que le pointeur se déplace vers l'arrière d'un octet, puis ajouter 5 signifie se déplacer vers l'arrière de 5 octets, donc
la valeur de l' entrée 801005 p5 + 5 est 801016, car la variable de pointeur pointe vers le long entier Oui, ajouter un signifie que le pointeur recule de 4 octets, puis ajouter 5 signifie reculer de 20 octets, donc entrez 810014, (en hexadécimal en sortie), ce serait 810020 en décimal 

Il existe une définition de tableau int a [2] [2] = { {1}, {2,3}}; alors la valeur de a [0] [1] est 0. // Pour
int (* ptr) (), ptr est le nom d'un tableau à une dimension. // Pointeur de fonction Le
pointeur peut effectuer des opérations>, <,> =, <=, == en toutes circonstances. // Inconnu, donc
c dans l'instruction switch (c) peut être de type int, long, char, float, unsigned int. //faux. Ne peut être qu'un entier, sans virgule flottante.
Sans utiliser les fonctions de la bibliothèque, écrivez la fonction int strcmp (char * source, char * dest) qui renvoie 0 s'il est égal, et renvoie -1 si ce n'est pas le cas;
écrivez une fonction int fun (char * p) pour juger si une chaîne est un palindrome, et renvoyez 1 s'il s'agit d'un palindrome , Au lieu de renvoyer 0, renvoie -1 en cas d'erreur

Fonctionnement variable statique

#include <stdio.h>
int somme (int a)
{ int c = 0; statique int b = 3; // 静态c + = 1; b + = 2; retour (a + b + c); } int main () { int I; int a = 2; pour (I = 0; I <5; I ++) { printf ("% d,", somme (a)); } retourne 0; } 8,10,12,14,16,
















Celui qui doit pouvoir imprimer "bonjour" est 134 et l'erreur est 2


char * GetHellostr (void);
int main (void)
{ char * ps; ps = GetHellostr (); if (ps! = NULL) { printf (ps); } retourne 0; } (1) char * GetHellostr (void) { char * ps = "bonjour"; return ps; } (2) char * GetHellostr (void) { char a [] = "bonjour"; return (char *) a; 内存 已经 被 释放 了} (3) char * GetHellostr (void) { static char a [] = "hello"; return (char *) a; } (4) char * GetHellostr (void) { char * ps; ps = malloc (10);































if (NULL == ps) renvoie NULL;
strcpy (ps, "bonjour");
return ps;
}

Fonction de chaîne

char * strcpy (char * strDest, const char * strSrc)
{     assert (strDest! = NULL && strSrc! = NULL);     char * strTmp = strDest;     while (* strSrc! = '\ 0')     {         * strDest ++ = * strSrc ++;     }     strDest = '\ 0';     return strTmp; }








int strlen (const char * strSrc)
{     assert (strSrc! = NULL);     int len ​​= 0;     while ((* strSrc ++)! = '\ 0')         ++ len;     return len; }





char * strcat (char * strDest, const char * strSrc)
{     assert ((strDest! = NULL) && (strSrc! = NULL));     char * strTmp = strDest;     while (* strDest! = '\ 0')         ++ strDest;     while (* strDest ++ = * strSrc ++);     * strDest ++ = '\ 0';     return strDest; }







Pointeurs doubles et références de pointeur

void foo (char ** p) // 双 指针
{     * p = "après"; } int main () {     int * p = "avant";     toto (& p);     cout << p << endl; // 输出 的 为 après le     retour 0; }








void foo (char * & p) // référence du pointeur
{     p = "after"; } int main () {     int * p = "befor";     foo (p);     cout << p << endl; // sortie Pour après     retour 0; }








Raisons d'utiliser le langage d'assemblage:


Premièrement: la vitesse d'exécution du langage assembleur est supérieure à celle du langage c.
Deuxièmement: le code de démarrage, lors de l'écriture du chargeur de démarrage et du noyau, il est principalement utilisé lors de l'initialisation du processeur et de la mémoire. Comme il n'y a toujours pas d'environnement écrit en langage C (la pile n'a pas été établie) pour le moment, le langage C ne peut pas être utilisé.

#ifndef X
#define X
...
#endif


Empêchez les fichiers d'en-tête d'être inclus et compilés à plusieurs reprises.

La différence entre le pointeur et le tableau.


Le premier tableau différent de méthodes de stockage est le contenu du membre stocké lui-même. Le pointeur stocke la première adresse.
Le second est la différence des méthodes de calcul. Le nom du tableau est une constante et ne peut pas être incrémenté ou décrémenté, tandis que le pointeur est une variable, qui peut être incrémentée et décrémentée.
Le troisième est l'opération de l'opération d'affectation. Le tableau peut être initialisé, mais l'affectation globale ne peut pas être effectuée via l'instruction d'affectation et le pointeur peut pointer vers une autre instruction.

Pourquoi strcpy retourne char *


La valeur renvoyée par la fonction strcpy peut être utilisée comme paramètre réel d'une autre fonction pour réaliser l'opération en chaîne.

Introduction à l'IIC:


Signal de démarrage: lorsque SCL est haut, SDA saute de haut en bas et commence à transmettre des données.
Signal de fin: lorsque SCL est de niveau haut, SDA passe du niveau bas au niveau haut, mettant fin à la transmission de données.
Signal de réponse: après avoir reçu les données 8 bits, le CI recevant les données envoie une impulsion de bas niveau spécifique au CI envoyant les données pour
indiquer que les données ont été reçues. Après avoir envoyé un signal à l'unité contrôlée, l'unité centrale attend que l'unité contrôlée envoie un signal de réponse.
Après avoir reçu le signal de réponse , l'unité centrale détermine s'il faut continuer à transmettre le signal en fonction de la situation réelle. Si aucun signal de réponse n'est reçu, il est jugé que l'
unité contrôlée est défectueuse.

// IIC envoie un octet
// retourne si l'esclave
a une réponse // 1, a une réponse
// 0, pas de réponse
void IIC_Send_Byte (u8 txd)
{ u8 t; SDA_OUT (); IIC_SCL = 0; // Baisser l'horloge Démarrer la transmission des données pour (t = 0; t <8; t ++) { IIC_SDA = (txd & 0x80) >> 7; txd << = 1; delay_us (2); // Pour TEA5767, ces trois retards sont nécessaires IIC_SCL = 1; delay_us (2); IIC_SCL = 0; delay_us (2); } } // Lire 1 octet, quand ack = 1, envoyer ACK, ack = 0, envoyer nACK u8 IIC_Read_Byte (unsigned char ack) { unsigned char i, receive = 0; SDA_IN (); // SDA est défini comme entrée pour (i = 0; i <8; i ++) { IIC_SCL = 0; delay_us (2); IIC_SCL = 1; receive << = 1; if (READ_SDA) reçoivent ++;























delay_us (1);
}
if (! ack) IIC_NAck (); // Send nACK
else IIC_Ack (); // Send ACK
return receive;
}

Je suppose que tu aimes

Origine blog.csdn.net/qq_38531460/article/details/103326672
conseillé
Classement