Skip to content
Snippets Groups Projects
Commit 4de03d3d authored by Erik Strand's avatar Erik Strand
Browse files

Add a demo of basic types

parent 4162053f
Branches
No related tags found
No related merge requests found
loops control_structures
functions functions
basic_types
...@@ -5,18 +5,21 @@ CXX = g++ ...@@ -5,18 +5,21 @@ CXX = g++
CFLAGS = -Wall -O3 CFLAGS = -Wall -O3
.PHONY: all .PHONY: all
all: loops functions all: control_structures functions basic_types
# Here I'm using some of Make's built in variables: $@ and $<. The former gets substituted with the # Here I'm using some of Make's built in variables: $@ and $<. The former gets substituted with the
# name of the target. In this case, that's "loops". The latter gets substituted with the first # name of the target. In this case, that's "loops". The latter gets substituted with the first
# prerequisite. In this case, that's "loops.c". These are hard to remember, but can save you some # prerequisite. In this case, that's "loops.c". These are hard to remember, but can save you some
# typing if you decide to rename things. # typing if you decide to rename things.
loops: loops.c control_structures: control_structures.c
$(CC) $(CFLAGS) -o $@ $< $(CC) $(CFLAGS) -o $@ $<
functions: functions.c functions: functions.c
$(CC) $(CFLAGS) -o $@ $< $(CC) $(CFLAGS) -o $@ $<
basic_types: basic_types.c
$(CC) $(CFLAGS) -o $@ $<
.PHONY: clean .PHONY: clean
clean: clean:
rm -f loops functions rm -f control_structures functions basic_types
#include <stdio.h>
#include <limits.h>
#include <float.h>
int main() {
// First up are integers. We've seen these already.
printf("Signed Integers\n");
printf("min: %i\n", INT_MIN);
printf("max: %i\n", INT_MAX);
int test_int = 5;
// Integers can be negative. After this line test_int should be -5.
test_int -= 10;
printf("5 - 10 = %i\n", test_int);
putchar('\n');
// Unsigned integers can't be negative. Instead they wrap around to the largest value, usually
// 2^32 - 1. Though on some microcontrollers unsigned ints have less than 32 bits.
// Note that to print them, we use the format string "%u" instead of "%i".
printf("Unsigned Integers\n");
printf("min: %u\n", 0);
printf("max: %u\n", UINT_MAX);
unsigned test_uint = 5;
test_uint -= 10;
printf("5 - 10 = %u\n", test_uint);
putchar('\n');
// For rational or real numbers, floating point can be a good approximation.
// You can format them as "%f" or "%e" (scientific notation).
printf("Floating Point\n");
printf("min: %e\n", -FLT_MAX);
printf("smallest positive (normalized): %e\n", FLT_MIN);
printf("max: %e\n", FLT_MAX);
// Floating point numbers are convenient and fast, but they have some strange properties that
// can bite you if you aren't careful.
// They can't exactly represent all numbers.
float f1 = 1.2;
// The "%.10f" tells printf to print 10 characters after the decimal point (for a float).
printf("closest float to 1.2: %.10f\n", f1);
printf("1.2 - 0.2: %.10f\n", f1 - 0.2);
// Unlike integers, they aren't exactly associative.
float f2 = (1e-3f + 1.0f) - 1.0f;
float f3 = 1e-3f + (1.0f - 1e0f);
// The "%.*f" tells printf that I'm going to give it the number of decimal places to print as an
// extra argument. In this case, I'm using FLT_DECIMAL_DIG, which is the number of decimal
// places you have to print if you want to be able to read it back again and not have the value
// changed.
printf("(0.001 + 1.0) - 1.0 = %.*f\n", FLT_DECIMAL_DIG, f2);
printf("0.001 + (1.0 - 1.0) = %.*f\n", FLT_DECIMAL_DIG, f3);
// Unfortunately this is just the tip of the iceberg. There's basically a whole field dedicated
// to working around float's limitations (numeric analysis).
putchar('\n');
// If you need more precision, use doubles. They use twice the number of bits as floats. This
// can give you more room before you notice numeric issues (note that 1.2 - 1.0 below "works"),
// but it doesn't make them go away.
printf("Double Precision Floating Point\n");
printf("min: %e\n", -DBL_MAX);
printf("smallest positive (normalized): %e\n", DBL_MIN);
printf("max: %e\n", DBL_MAX);
double d1 = 1.2;
printf("closest double to 1.2: %.*f\n", DBL_DECIMAL_DIG, d1);
printf("1.2 - 0.2: %.*f\n", DBL_DECIMAL_DIG, d1 - 0.2);
double d2 = (1e-6l + 1.0l) - 1.0l;
double d3 = 1e-6l + (1.0l - 1e0l);
printf("(1e-6 + 1.0) - 1.0 = %.21f\n", d2);
printf("1e-6 + (1.0 - 1.0) = %.21f\n", d3);
putchar('\n');
// A single ASCII character is represented as a char. You can also think of these as 8-bit
// unsigned integers.
printf("Character\n");
// Characters are enclosed in single quotes.
char c1 = 'a';
// All the alphabet is fair game (lower and upper case), as are single numeric digits and basic
// symbols. These are all fine.
c1 = '1';
putchar(c1);
c1 = '$';
putchar(c1);
c1 = '\n'; // this is the newline character
putchar(c1);
// Note that literal numbers are not equal to their ASCII counterparts. You can see which
// numbers represent which characters by looking up the ASCII table.
// https://en.wikipedia.org/wiki/ASCII
c1 = 0;
printf("numeric 0 (won't show up as anything): %c\n", c1);
c1 = '0';
printf("ASCII 0: %c\n", c1);
putchar('\n');
// For more than one character of text, we'll use strings. These aren't actually their own type.
// They're represented as an array of chars, which we access through something called a pointer.
// Strings are enclosed in double quotes.
printf("Strings\n");
// "char*" means a pointer to a character. The assumption that C makes about strings is that the
// pointer identifies the first character, and the rest follow right after (with no gaps), and
// are followed by a 0 (the numeric value 0, not the ASCII '0' character).
char* test_string = "hello\n";
printf("%s", test_string);
}
File moved
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment