We present another set of concepts in the computer science series as they relate to Arduino.
Previously on "Adventures in Science," I covered Arduino programming syntax. Now, we take a look at how to store numbers and characters in "containers" known as variables and how to access that data.
Before digging into literals and variables, we have to understand data types. A data type is a classification of information that tells the compiler how the programmer intends to use the information. In C, there are only three fundamental data types: integer (
int), floating point (
float) and character (
char). However, you will also sometimes see
void to indicate "nothing" or "no type."
Arduino supports more data types, such as
long int, which is an integer stored in 4 bytes, and
unsigned int to mean an integer that's only positive or 0.
Literals are fixed values that do not change throughout the program. For example, if you write the number
500 in your program, that's a literal. Literals for characters can be expressed between single quotes as any ASCII-encoded character, such as
Variables work like containers with labels. You can store information with the specified data type in a variable and then refer to the label later in the code when you need to retrieve or change the data. This can be extremely handy for manipulating data later in the code (with, for example, arithmetic operators) or setting a constant value once in the code (e.g., setting
led = 13; and then using
led instead of writing
13 several times).
Like your tutorials in written form? Here are a couple of guides that go over the basics of data types in Arduino and the American Standard Code for Information Interchange (ASCII):
Question for all you programmer types out there: Which do you prefer --- strongly typed languages or weakly typed languages? Why? Please respond in the comments below.
Programming for 8, 32, and 64 bit systems, I personally prefer to use names such as "uint8_t", "int64_t", etc. so that it's clear if it's signed or unsigned, and the number of bits is consistent regardless of the CPU/compiler. Not all compilers support this naming scheme, but most C/C++ compilers seem to support it.
Good call. I usually forget to do this (unless I'm working with uint8_t), since I'm so used to "int," but specifically calling out the byte size is super helpful.
I'm not sure if I spotted an error, or if I learned something wrong. I could have sworn that the 'char' datatype was signed. The table in the video shows it as unsigned. (Otherwise, what is the point of 'unsigned char' or 'byte', and what would be a signed 8-bit variable?)
According to Arduino's reference page, char is signed (-128 to 127), so you are correct in that it is in error on the table in the video. Thanks!
char is implementation defined. It can be signed or unsigned by default based on the compiler writers' whims. That's why it's always safest to specify the option you want.
Right, but in the context of that table it is the Arduino platform. I'm not sure if the Arduino pre-processing stuff defines it as int8_t or if it is the gpp compiler (the actual compiler used in the Arduino environment). Shawn has already weighed in though.
I'll ferit away into my memory that char is truly implementation specific, especially when I eventually move to a different implementation. I keep going back and forth in my mind weather it is best to use the low level int##_t and uint##_t data types or the higher level byte, int, long. Especially since for me I want to write code that works on both an 8-bit AVR Arduino through to a 32-bit ARM M0 Arduino, and all the points in between, with very little changes needed. I feel I should use the higher level datatypes for portability, but I really want to conserve memory on my little UNO... Having lots of #ifdef clauses for different platforms starts making code look really ugly and hard to actually read and figure out what the intent is.
Or do I have it completely backwards and int##_t and uint##_t datatypes are actually higher level?
Some more FYI, the processor instruction set size (8-bit, 16-bit, 32-bit, 64-bit) determines the initial datatype size.
This means that some things which are larger (float, double) would have reduced size from what they typical are (float = 32-bit, double = 64-bit), so if floating point resolution is a major desire, keep that in mind.
I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well. In fact your creative writing abilities has inspired me to start my own Blog Engine blog now. Really the blogging is spreading its wings rapidly. Your article is a fine example.