5 trucs de C++ per a programadors de C

Durant els darrers anys, C++ s’ha convertit en un llenguatge més popular per utilitzar en sistemes incrustats que el C. No m’equivoquis, C continuarà sent un llenguatge dominant durant els propers anys, però C++ ofereix als desenvolupadors eines modernes per aprofitar-ho quan dissenyant codi més reutilitzable, escalable i portàtil. Els equips no només abandonen C, sinó que, quan comencen el desenvolupament de nous productes, adopten C++. El llenguatge ha anat evolucionant amb els temps i ofereix moltes millores respecte a C. En aquesta publicació, examinem cinc trucs senzills de C++ que els programadors de C apreciaran immediatament.

Truc #1: compilació condicional utilitzant Constexpr

El mal de moltes bases de codi incrustat escrits en C és el gran nombre de directives del preprocessador #if / #elif / #else. Les directives del preprocessador s’utilitzen sovint per compilar codi condicionalment dins i fora de la imatge. Per exemple, si tenim tres versions diferents de maquinari, sovint crearem una macro que s’utilitza i després es comprovarà en funció de la configuració de compilació per determinar les assignacions de pins i així successivament. El problema de les compilacions condicionals que utilitzen el preprocessador és que el codi es fa desordenat i de vegades és bastant difícil de seguir.

A partir de C++17, el llenguatge va introduir la capacitat per als desenvolupadors de compilar codi condicionalment mitjançant constexpr. Els desenvolupadors poden aprofitar aquesta funció del compilador per optimitzar el codi basat en plantilles i fins i tot per eliminar les directives del preprocessador que utilitzen blocs #ifdef. Per exemple, si tinguéssim una base de codi que tingués tres configuracions de maquinari diferents, podríem trobar que el nostre codi per inicialitzar GPIO s’assembla a això:

void Gpio_Init()

{

#ifdef __HARDWARE_REV1__

// Inicialitzar el conjunt de pins #1

#elif __HARDWARE_REV2__

// Inicialitzar el conjunt de pins #2

#elif __HARDWARE_REV_3__

// Inicialitzar el conjunt de pins #3

#endif

}

El codi anterior és configurable, però és bastant desagradable de mirar. Sí, un IDE modern ombrejarà algunes de les opcions, però simplement no és una solució molt elegant i condueix a un codi desordenat. En C++, podem aprofitar l’optimització del temps de compilació constexpr i escriure codi com el següent:

constexpr Hardware_t HardwareRev = Maquinari::Rev1

void Gpio_Init()

{

if constexpr(HardwareRev == Maquinari::Rev1)

{

// Inicialitzar el conjunt de pins #1

}

else if constexpr(HardwareRev == Maquinari::Rev2)

{

// Inicialitzar el conjunt de pins #2

}

else if constexpr(HardwareRev == Maquinari::Rev3)

{

// Inicialitzar el conjunt de pins #3

}

}

Quan compilem el codi anterior per a Rev2, només el codi de “Inicialitza el conjunt de pins #2” el converteix en el nostre executable. Si compilem per a Rev1, només el codi per a “Inicialitza el conjunt de pins #1” el converteix en l’executable, i així successivament.

Truc núm. 2: a distància per bucles

Un mecanisme fonamental de control de flux en C i C++ és el bucle for. El bucle C for s’ha quedat encallat a l’edat fosca per no tenir una opció simplificada basada en el rang. Per exemple, llenguatges com Python permeten a un programador iterar sobre un interval mitjançant una sintaxi com:

per a x dins l’interval (1, 5)

imprimir (x)

En C, hem d’escriure (depenent de l’estàndard C utilitzat, per descomptat):

for(int x = 1; x <= 5; x++)

{

printf(“%drn”, x);

}

A partir de C++ 11, es va afegir una versió addicional del bucle for que facilita el treball amb valors amb rang. Per exemple, si un volgués escriure els exemples de codi anteriors en C++, ara el podríem escriure com:

int MyNums[] = {1, 2, 3, 4, 5};

for(int i: MyNums)

{

std::cout << I << std::endl;

}

Al principi, per a un desenvolupador C això pot semblar incòmode; Tanmateix, tenint en compte la freqüència amb què volem treballar sobre un rang en una enumeració o objecte, la sintaxi és més neta i més fàcil de llegir.

Truc núm. 3: utilitzeu automàtic

Per als desenvolupadors de C, auto és una paraula clau d’idioma que va quedar obsoleta fa molt de temps. Els desenvolupadors solien utilitzar auto per especificar una variable que es limitava a l’abast actual. Auto és un especificador de classe d’emmagatzematge com static, només especifica que l’emmagatzematge és local i que la variable s’hauria de destruir automàticament un cop estigui l’abast, a diferència de static que permet que la variable persisteixi.

En C++, auto pot ser una paraula clau molt útil que indica al compilador que assigni automàticament el tipus de dades per al desenvolupador. Per exemple, al truc #2, teníem el següent codi de bucle for:

int MyNums[] = {1, 2, 3, 4, 5};

for(int i: MyNums)

{

std::cout << I << std::endl;

}

MyNums ja està definit com a int, així que puc deixar que el compilador decideixi el tipus que s’ha d’utilitzar per a i de la següent manera:

for(auto i: MyNums)

{

std::cout << I << std::endl;

}

Al principi, això pot semblar descuidat. Com a desenvolupador, no hauria de controlar quins són els meus tipus de variables? La resposta és sí, però hauríem de permetre al compilador gestionar els tipus on ens podria estalviar temps o on no ens importa especificar manualment. Ens importa si i, per exemple, és uint8_t, uint16_t, uint32_t i així successivament? Probablement no. Només volem alguna cosa que pugui iterar entre un i cinc i el compilador és més que capaç de decidir. Auto també pot ajudar quan canviem un tipus de dades. Podem canviar-lo en un sol lloc sense haver de preocupar-nos de canviar qualsevol cosa aigües avall que l’utilitzi o hi interaccioni.

Truc #4: l’operador de la nau espacial

De vegades pot resultar molest quan necessiteu escriure una declaració condicional que comprove si un valor és menor, major que o igual a un altre valor. Fa poc, C++20 va afegir un operador de comparació de tres vies que pot simplificar la llegibilitat i el codi. Aquest operador <=>, sovint s’anomena operador “nau espacial” perquè sembla una nau espacial.

Utilitzar l’operador de la nau espacial és senzill. Per exemple, si tenim dues variables i volem una comparació de tres direccions, podríem escriure codi com el següent:

int Var1 = Valor1;

int Var2 = Valor2;

Auto Resultat = Var1 <=> Var2;

Si Var1 < Var2, aleshores el resultat serà menor que 0. Si Var1 > Var2, el resultat serà superior a 0. Si Var 1 és igual a Var2, aleshores el resultat serà 0.

Truc núm. 5: obtenir la mida d’una corda

Les cadenes en C no són més que una matriu de caràcters amb ‘’ com a darrera entrada de matriu. Molts errors han donat lloc a aplicacions de com tracta C amb les cadenes. No és estrany oblidar el terminador de cadena en una cadena, dimensionar incorrectament la matriu o utilitzar funcions de cadena que poden provocar desbordaments de memòria intermèdia, etc.

En C++, les cadenes es poden gestionar amb molta més seguretat. No entraré en tots els detalls interessants d’aquesta publicació, això depèn del lector, però només vull assenyalar com de simples poden ser les coses en C++. Per exemple, si un desenvolupador necessita obtenir la longitud d’una cadena, simplement pot utilitzar el mètode length() associat a la cadena. Un exemple de codi senzill podria ser on permetem a l’usuari introduir una cadena i després verificar-ne la longitud abans d’utilitzar-la:

Entrada de cadena;

getline(cin, entrada);

if(Longitud.entrada() < 50)

{

std::out << "Processament de la cadena..." << std::endl;

}

altra cosa

{

std::out << "Cadena molt llarga! Torna-ho a provar” << std::endl;

}

És un exemple senzill, però animo molt al lector a investigar les biblioteques de cadenes que es proporcionen en C++. Us sorprendrà el segur i fàcil que és utilitzar cordes!

Descobriments

C++ està guanyant força en moltes aplicacions incrustades, especialment aquelles que es desenvolupen des de zero i que no depenen de grans quantitats de codi heretat. A primera vista, C++ pot semblar intimidatori per als programadors de C; Tanmateix, els programadors de C trobaran que C++ és una extensió natural de C a un llenguatge de programació més modern. Els patrons i tècniques de disseny que serien gairebé impossibles en C són fàcils en C++. En aquesta publicació, hem explorat alguns trucs senzills de C++ que crec que interessaran als desenvolupadors de C. Amb prou feines hem començat a rascar la superfície, però si sou un programador de C, crec que trobareu que C++ té molt a oferir a les aplicacions incrustades.

Jacob Beningo és un consultor de programari integrat que treballa amb clients de més d’una dotzena de països per transformar dràsticament els seus negocis millorant la qualitat, el cost i el temps de comercialització del producte. Ha publicat massa blocs per comptar amb l’arquitectura de programari incrustat, els processos i les tècniques de desenvolupament, és un conferenciant i formador tècnic molt sol·licitat i té tres títols, inclòs un màster en enginyeria de la Universitat de Michigan. Podeu contactar amb Jacob a [email protected] i inscriu-te al seu mensual Butlletí de bytes incrustats.

Leave a Comment

Your email address will not be published. Required fields are marked *