Mengapa orang menggunakan variabel untuk menentukan nomor pin ketika pin tidak mungkin berubah sepanjang pelaksanaan kode?
Banyak kali saya melihat int
makhluk yang digunakan untuk definisi pin,
int led = 13;
saat penggunaan a const int
const int led = 13;
#define LED 13
jauh lebih masuk akal.
Bahkan dalam tutorial di situs Arduino, misalnya, tutorial pertama yang dijalankan kebanyakan orang, Blink .
Saya membaca suatu tempat yang const int
lebih disukai #define
. Mengapa ini tidak dianjurkan sejak awal, daripada membiarkan orang untuk mengembangkan kebiasaan buruk, sejak awal? Saya memperhatikannya beberapa waktu lalu, tetapi baru-baru ini mulai membuat saya jengkel, karena itu pertanyaannya.
Memory / pengolahan / komputasi bijaksana adalah const int
, enum
, atau dalam hal ini #define
, lebih baik dari polos int
, yaitu menempati kurang memori, disimpan dalam memori yang berbeda (Flash, EEPROM, SRAM), lebih cepat eksekusi, lebih cepat untuk mengkompilasi?
Ini mungkin merupakan duplikat dari Apakah lebih baik menggunakan #define atau konst? Int untuk konstanta? , tapi saya menjawab pertanyaan mengapa orang menggunakan variabel, dan bagaimana kinerja meningkat ketika mereka tidak, daripada jenis konstanta yang lebih baik.
sumber
Jawaban:
Itu adalah metode yang benar. Atau bahkan:
Berapa pin yang Anda miliki?
Beberapa tutorial tidak cukup melalui kontrol kualitas sebanyak mungkin.
Performa akan lebih baik digunakan
const byte
, dibandingkan denganint
namun kompiler mungkin cukup pintar untuk menyadari apa yang Anda lakukan.Yang dapat Anda lakukan adalah dengan lembut mendorong orang untuk menggunakan teknik yang lebih efisien dengan menggunakannya dalam kode Anda sendiri.
Tanggapan terhadap komentar
Seorang komentator telah menyarankan bahwa
byte
ini bukan standar C. Ini benar, namun ini adalah situs Arduino StackExchange, dan saya percaya menggunakan tipe standar yang disediakan oleh Arduino IDE dapat diterima.Di Arduino.h ada baris ini:
Perhatikan bahwa ini tidak persis sama dengan
unsigned char
. Lihat uint8_t vs unsigned char dan When is uint8_t ≠ unsigned char? .Komentator lain menyarankan bahwa menggunakan byte tidak selalu meningkatkan kinerja, karena angka yang lebih kecil dari yang
int
akan dipromosikanint
(lihat Aturan Promosi Integer jika Anda menginginkan lebih banyak tentang ini).Namun dalam konteks pengidentifikasi const , kompiler akan menghasilkan kode yang efisien dalam hal apa pun. Misalnya, membongkar "blink" memberikan ini dalam bentuk aslinya:
Bahkan ia menghasilkan kode yang sama apakah
13
:#define
const int
const byte
Kompiler tahu kapan ia bisa memasukkan nomor ke dalam satu register dan kapan tidak. Namun itu praktik yang baik untuk menggunakan pengkodean yang menunjukkan niat Anda . Memperjelas
const
bahwa angkanya tidak akan berubah, dan membuatnyabyte
(atauuint8_t
) menjelaskan bahwa Anda mengharapkan sejumlah kecil.Pesan kesalahan yang membingungkan
Alasan utama lain yang harus dihindari
#define
adalah pesan kesalahan yang Anda dapatkan jika Anda melakukan kesalahan. Pertimbangkan sketsa "blink" yang memiliki kesalahan:Di permukaan terlihat OK, tetapi menghasilkan pesan kesalahan ini:
Anda melihat garis yang disorot pertama (baris 4) dan bahkan tidak melihat simbol "=". Plus, garis terlihat baik-baik saja. Sekarang sudah cukup jelas apa masalahnya di sini (
= 13
sedang digantiLED
), tetapi ketika garis 400 baris lebih jauh dalam kode, tidak jelas masalahnya dengan cara LED didefinisikan.Saya telah melihat orang jatuh untuk ini berkali-kali (termasuk saya).
sumber
int
yang berlebihan ... yaitu, sampai Arduino akhirnya keluar dengan papan Tera ... :-)byte
tipe . Maksudmuunsigned char
.byte
daripadaint
, karena dalam sebagian besar konteks, nilai integer dengan tipe yang lebih kecil daripadaint
yang dipromosikanint
.C doesn't have a byte type. You mean unsigned char.
- Jawaban saya adalah dalam konteks Arduino, yang memiliki initypedef uint8_t byte;
. Jadi untuk Arduino, menggunakanbyte
tidak apa-apa.Performance won't necessarily be better with byte instead of int
- lihat pos yang diamandemen.Seperti yang dinyatakan Ignacio dengan benar, pada dasarnya karena mereka tidak tahu yang lebih baik. Dan mereka tidak tahu yang lebih baik karena orang-orang yang mengajar mereka (atau sumber daya yang mereka gunakan saat belajar) tidak tahu yang lebih baik.
Sebagian besar kode dan tutorial Arduino ditulis oleh orang-orang yang tidak pernah memiliki pelatihan dalam pemrograman dan sangat "belajar sendiri" dari sumber daya oleh orang-orang yang sendiri banyak belajar sendiri tanpa pelatihan yang tepat dalam pemrograman.
Banyak cuplikan kode tutorial yang saya lihat di sekitar tempat (dan terutama yang hanya tersedia dalam video YouTube --- urgh) akan menjadi tanda gagal jika saya menandai mereka dalam ujian.
Ya, a
const
lebih disukai daripada non-const, dan bahkan lebih dari a#define
, karena:const
(seperti a#define
, tidak seperti non-const) tidak mengalokasikan RAM apa punconst
(seperti non-const, tetapi tidak seperti a#define
) memberikan nilai tipe eksplisitPoin kedua ada minat khusus. Kecuali jika secara khusus diceritakan sebaliknya dengan embedded type-casting (
(long)3
) atau tipe suffix (3L
) atau adanya titik desimal (3.0
),#define
suatu bilangan akan selalu berupa bilangan bulat dan semua matematika yang dilakukan pada nilai tersebut akan seolah-olah merupakan bilangan bulat. Sebagian besar waktu itu bukan masalah, tetapi Anda bisa mengalami skenario menarik ketika Anda mencoba untuk#define
nilai yang lebih besar dari yang bisa disimpan oleh integer, seperti#define COUNT 70000
kemudian melakukan operasi matematika denganint
nilai - nilai lain di dalamnya. Dengan menggunakanconst
Anda bisa memberi tahu kompiler "Nilai ini harus diperlakukan sebagai tipe variabel ini" - jadi Anda akan menggunakan:const long count = 70000;
dan semua akan bekerja seperti yang diharapkan.Ini juga memiliki efek knock-on yang memeriksa jenis ketika melewati nilai di sekitar tempat itu. Cobalah meneruskan
const long
ke fungsi yang mengharapkanint
dan akan mengeluh tentang mempersempit rentang variabel (atau bahkan gagal untuk dikompilasi tergantung pada skenario). Lakukan itu dengan#define
dan itu hanya akan terus memberikan hasil yang salah dan membuat Anda menggaruk kepala selama berjam-jam.sumber
const
variabel mungkin memerlukan RAM, tergantung pada konteksnya, misalnya jika itu diinisialisasi menggunakan nilai kembali dari fungsi non-constexpr.const int foo = 13; bar(&foo);
pasti akan membutuhkan kompiler untuk mengalokasikan memori yang sebenarnyafoo
.int
dengan kompiler memperlakukan nilai memiliki tipe terkecil di mana ia akan cocok (modulo aturan tentang ditandatangani vs. tidak ditandatangani). Jika Anda menggunakan sistem denganint
16 bit,#define count 70000
akan menghasilkancount
tampilan sepertilong
, seperti jika telah didefinisikan sebagaiconst long count = 70000;
. Lebih lanjut, jika Anda melewatkan salah satu versi tersebutcount
ke fungsi yang diharapkanint
, kompiler yang waras akan memperlakukannya sama.#define COUNT 70000
tidak memotong ke int, tetapi kompilator memperlakukannya sebagai tipe yang cukup besar untuk menampung nomor itu. Memang benar bahwa itu mungkin tidak jelas ketika Anda menggunakanCOUNT
itu bukan int, tetapi Anda bisa mengatakan hal yang sama tentang suatu caraconst long
.COUNT
dalam contoh Anda diganti sebelum kompilasi dengan ekspresi70000
, yang memiliki tipe yang didefinisikan oleh aturan literal, seperti2
atau13L
atau4.0
didefinisikan oleh aturan literal. Fakta bahwa Anda menggunakan#define
alias untuk ekspresi itu tidak relevan. Anda dapat menggunakan#define
alias potongan kode C yang sewenang-wenang, jika diinginkan.Sebagai pendatang baru 2 minggu di Arduino, saya memahami gagasan umum tentang Arduino yang diduduki oleh bukan pemrogram. Sebagian besar sketsa yang telah saya periksa, termasuk yang ada di situs Arduino, menunjukkan kurangnya pesanan, dengan sketsa yang tidak berfungsi & hampir tidak ada komentar yang masuk akal. Bagan alur tidak ada, dan "Perpustakaan" adalah campuran yang tidak dimoderasi.
sumber
Jawaban saya adalah ... mereka melakukannya karena berhasil. Saya mengalami kesulitan untuk tidak mengajukan pertanyaan dalam jawaban saya seperti "mengapa itu harus 'salah'?"
sumber