Jag lärde mig att programmera för en tom hinderrobot men när jag tittade på kod Jag såg två datatyper långa och int.
Int är datatyper som innehåller -2,147,483,648 till 2,147,483,647. Långa är också datatyper som rymmer -2,147,483,648 till 2,147,483,647.
Int och lång är likadana men jag kom fram till koden där två typer av datatyp används enligt nedan:
int trigPin = 2; int echoPin = 4; long duration, cm, inches;
Men hur kan du veta när vilken datatyp ska användas? Jag sökte mycket på nätet men förstod inte så kan någon förklara för mig det.
Kommentarer
- " Int är datatyper som innehåller -2,147,483,648 till 2,147,483,647 " Var hörde du det?
Svar
På Arduino (AVR-modeller) är int
16 bitar, inte 32 bitar. Således går det från -32768 till +32767.
Det är annorlunda från long
vilket är 32 bitar.
Kommentarer
- Vilka är bredderna på
int
ochlong
på 32-bitars ARM Arduinos som Due? - Jag tror på grund att en
int
är 32 bitar, samma along
. Se till exempel här .
Svar
int
i AVR GCC är 16 bitar , inte 32.
Svar
Enligt C-språkspecifikationen , int
måste vara minst 16 bitar eller längre och long
måste vara minst 32 bitar eller längre.
Det är OK för en kompilator att implementera int
som 32 bitar eller till och med 64 bitar. Det är OK för en kompilator att implementera long
som 64 bitar eller längre. Men det är inte tillåtet för en kompilator att implementera long
som 16 bitar.
Så när ska man använda vilken typ?
Om värdena du kommer att arbeta med kan representeras inom 16 bitar så är det OK att använda int
. Om du behöver mer än 16 bitar använder du long
. Om du behöver mer än 32 bitar, använd long long
.
Fånga dig inte med kompilator- och / eller CPU-specifikationer. Som nämnts av andra, även inom samma produktsortiment, Arduinos, det finns 16 och 32-bitars processorer tillgängliga. Lita bara på vad standarden garanterar.
Den fullständiga specifikationen för typerna i C är:
-
char
måste vara minst 8 bitar -
int
måste vara minst 16 bitar -
long
måste vara minst 32 bitar -
long long
måste vara minst 64 bitar
Obs! Det är helt lagligt för kompilatorer att implementera char, int, long och long long som 64 bitar. Detta är faktiskt inte ovanligt bland DSP: er.
Kommentarer
- Också: Läs din kompilatordokumentation
- Och:
sizeof(char) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
enligt standard. Så omint
är 64 bitar, måstelong
också vara minst 64 bitar.
Svar
Det är samma resonemang som i C: storleken på typen int
förväntas att vara den naturliga ordstorlek som ditt system hanterar mest effektivt . Det måste också vara minst 16 bitar brett, inte mindre än en short
och inte större än en long
.
Så en int
kan vara 16-, 32- eller 64-bitars oavsett vad ditt system hanterar bäst, och så är det troligt att det är 16 bitar brett på en 8- eller 16-bitars CPU, 32 på en 32-bitars CPU etc.
Jag använder int
när jag vill ha bästa prestanda, samtidigt som jag tar hand om att skydda när jag behöver mer räckvidd än 16 bitar. I dessa dagar brukar du veta när du skriver applikationskod för 16-bitars system, även om det inte är så sant för ”bibliotek” -kod där bärbarhet kan vara av större oro.
I ditt exempel, förutsatt att författaren hade valt sina typer noggrant, kräver int
förmodligen ett litet intervall och kan ha råd att vara ordstorlek vilket leder till potentiellt kortare eller snabbare kod (eller båda). long
antog antagligen mer än 16-bitars intervall (de garanteras vara minst 32 bitar breda). På processorn som du valt som ett kompileringsmål, ser det ut som att int
och long
båda implementerades som 32-bitars. vara annorlunda (eller ska vara) om du valde en 16-bitars mål-CPU.
Svar
Jag gillar att använda typer från stdint.h
.
Även om de har mindre nackdelar är fördelen de ger att du vet exakt vilken storlek du hanterar, även när du sammanställer andra arkitekturer.
#include <stdint.h> uint8_t my_byte = 0xf0; int16_t trig_pin = 2; int16_t echo_pin = 4; uint32_t duration, cm , blah; uint64_t big_int; // etc.
Men självklart vill du inte flytta runt en massa int32_t när dina data bara behöver int16_t.
Kommentarer
- Så du använder inte maskinord storlek påverkar inte prestanda på AVR?
- @Ren é – I allmänhet kan inte ordstorlek påverka prestanda på de flesta processorer. Men traditionellt har AVR-processorer 8bit-register & ackumulatorer med några 16-bitars instruktioner för pekareoperationer. Så när jag programmerar får jag koden att gå först och optimerar sedan för hastighet om den ' är för långsamt.
- @Ren é – Men om du verkligen vill vara pedantisk om det kan du använda
word
som din datatyp. Detta är 16 bitar på Arduino Uno och 32 bitar på Arduino Due & Noll. Men detta kommer tillbaka till problemet att egentligen bara känna till minsta storlek på din datatyp. Säg att du använderword
på någon Due-kod, men sedan vill backa till Uno ?! Att använda uint32_t istället skulle lösa detta problem innan det startar, men ja det kommer att vara ordstorlek suboptimalt på Uno. Vad sägs om framtida Arduino-kort … vilken ordstorlek kommer de att ha? 32? 64? 128 !? - OK. Så jag skulle använda maskinens ordstorlek (int? WORD verkar vara en obselett Windows-definition) om den nedre gränsen är tillräcklig, jag bryr mig inte om minnesstorlek och behöver hastigheten, * _t om jag bryr mig om storlek?
- skrot som … gnu.org/software/libc/manual/html_node/Integers.html säger
*fast*_t
verkar vara vägen att gå …