Paulo Laureano Because coding is fun!

Learn to code in the C language (2/3)




Gentle introduction to coding computers, using the C programming language, in well under 90 minutes (this is part 2 of 3).

After the first three "gentle introduction lessons", in part 1, here is a pack of the following four chapters. I will do another series of videos with an example game and more advanced subjects (graphics, sound, etc). You have to start somewhere and this first hour is really a soft way to create some sort of familiarity with what C code looks like and how to read it.

You get a link to a free MagPi magazine issue and links to the example code in the video description on Youtube.

You can see the video and then read the first three chapters of the magazine, but I recommend you do it the other way around: read the first three chapters and then see the video.

Do not be in a hurry to "read every lesson" or "watch every video"! Your time will be better spent trying to write code similar to the examples and experimenting with your new found skills. In fact, it is crucial that you take it slow, type code, make mistakes and learn with them.

Example 4 used in the video:


/* Chapter 7 of Essencials_C_v1.pdf
* Arrays & strings
*/

#include

int main(int argc, char *argv[])
{
// declaring the array of chars without initiaziling it (giving it no values)
char a_string[10];
// declaring the array of chars and initiaziling it (giving it some values for some of the letters)
char b_string[10]="world";

// arrays of int's
int some_number[3];
int more_numbers[3]={ 4, 5, 6};

// initialing the array of numbers we previously declared but did not initialize...
some_number[0]=1;
some_number[1]=2;
some_number[2]=3;

// initializing the array we previously declared but did not initialize... the hardest way possible way
// exactly like we did with numbers would look like this:
/*
a_string[0]='h';
a_string[1]='e';
a_string[2]='l';
a_string[3]='l';
a_string[4]='o';
a_string[5]=0; // strings are null terminated!
*/

// there is a function to replace this (takes less code and it is the same as the manual procedure)
// you can use it like this:
sprintf(a_string, "hello");
// a_string is a POINTER to the memory address of the first element of the string: a_string[0]

// formating code is important, take advantage of multiple lines and make it more readable.
printf("%s %s %d %d %d %d %d %d\n", a_string,
b_string,
some_number[0], some_number[1], some_number[2],
more_numbers[0], more_numbers[1], more_numbers[2]);

return(0);
}



Example 5 used in the video:


/*
* Chapter 4 of Essencials_C_v1.pdf
* "for" loops & fow control using "if" / "else if" /else
*/

#include

int main(int argc, char *argv[])
{
// the "for" loop syntax: set the starting value; end condition; change each loop step
for(int a=1; a<=10; a=a+1)
{
printf("%d", a);

// there is more than one way to do flow control: using "if / else" this time
if(a==10)
{
printf("... last value reached! have a nice day\n");
}
else if(a==1)
{
printf("... just starting... we have a long way to go...\n");
}
else
{
printf("\n");
}
}

return(0);
}



Example 6 used in the video:


/*
* Chapter 4 of Essencials_C_v1.pdf
* "for" loops & fow control using "switch"
*/

#include

int main(int argc, char *argv[])
{
// the "for" loop syntax: set the starting value; end condition; change each loop step
for(int a=1; a<=10; a++) // instead of "a=a+1" you could use "a++" or "a += 1". same thing!
{
printf("%d", a);

// there is more than one way to do flow control: using switch this time...
switch (a) {
case 10: printf("... last value reached! have a nice day\n");
break;

case 1: printf("... just starting... we have a long way to go...\n");
break;

default: printf("\n");
}
}

return(0);
}



Example 7 used in the video:


/*
* Chapter 4 of Essencials_C_v1.pdf
* Endlessloops and breaking out of them
*/

#include

int main(int argc, char *argv[])
{
int a=1;

for(;;) // the "for" loop syntax endless loop
{
printf("%d... just starting... we have a long way to go...\n", a);
a += 1; // the same as: a=a+1
break;
}

while(1) // any value other then 0 is "true", so this results is a endless loop
{
if(a==10)
{
printf("%d... last value reached! have a nice day\n", a);
break;
}
else
{
printf("%d\n", a);
}

a++; // the same as: a=a+1
}
return(0);
}



Example 8 used in the video:


/*
* Chapter 5 of Essencials_C_v1.pdf
* Pointers
*/

#include

int main(int argc, char *argv[])
{
int myvalue=5;
int othervalue=10;

// declaring with an "*" before the name means "it is a pointer"
// placing an "&" before a variable means "pointer to the variable"
int *ptr_myvalue = &myvalue;
int *ptr_othervalue = &othervalue;

// an "*" before the variable name means "value of content stored in pointer"
printf("At memory location %p we have stored the value %d\n", &myvalue, *ptr_myvalue);
printf("At memory location %p we have stored the value %d\n\n", &othervalue, *ptr_othervalue);

// so, *******think******* and... figure these out! Really, understand the results, do not skip ahead!
// Programming is hard and you are not dumb. So use that amazing brain of yours!
myvalue = *ptr_othervalue * 3;
printf("%d\n", myvalue);

myvalue = *ptr_othervalue + othervalue;
printf("%d\n", myvalue);

myvalue = *ptr_myvalue + *ptr_othervalue;
printf("%d\n", myvalue);

// that is not all you need to learn about pointers, but these are important concepts...
// more pointer talk comming, when we learn about arrays...

return(0);
}



Example 9 used in the video:


/* Chapter 6 of Essencials_C_v1.pdf
* Functions... reuse code in smaller, smarter and easier to read/manage blocks
*/

#include

void show_address_and_content(int *a) // passing a pointer to a function that returns no value
{
printf("At memory location %p we have stored the value %d\n", a, *a);
}

int multiply(int a, int b) // passing two integers to a
{
printf("%d\n", a * b);
return(a * b);
}

int sum(int a, int b)
{
printf("%d\n", a + b);
return(a + b);
}

int main(int argc, char *argv[])
{
int myvalue=5;
int othervalue=10;
int *ptr_myvalue = &myvalue;
int *ptr_othervalue = &othervalue;

show_address_and_content(ptr_myvalue);
show_address_and_content(ptr_othervalue);
myvalue = multiply(*ptr_othervalue, 3);
myvalue = sum(*ptr_othervalue, othervalue);
myvalue = sum(*ptr_myvalue, *ptr_othervalue);

return(0);
}


Example 10 used in the video:


/* Chapter 7 of Essencials_C_v1.pdf
* Arrays & strings
*/

#include

int main(int argc, char *argv[])
{
// declaring the array of chars without initiaziling it (giving it no values)
char a_string[10];
// declaring the array of chars and initiaziling it (giving it some values for some of the letters)
char b_string[10]="world";

// arrays of int's
int some_number[3];
int more_numbers[3]={ 4, 5, 6};

// initialing the array of numbers we previously declared but did not initialize...
some_number[0]=1;
some_number[1]=2;
some_number[2]=3;

// initializing the array we previously declared but did not initialize... the hardest way possible way
// exactly like we did with numbers would look like this:
/*
a_string[0]='h';
a_string[1]='e';
a_string[2]='l';
a_string[3]='l';
a_string[4]='o';
a_string[5]=0; // strings are null terminated!
*/

// there is a function to replace this (takes less code and it is the same as the manual procedure)
// you can use it like this:
sprintf(a_string, "hello");
// a_string is a POINTER to the memory address of the first element of the string: a_string[0]

// formating code is important, take advantage of multiple lines and make it more readable.
printf("%s %s %d %d %d %d %d %d\n", a_string,
b_string,
some_number[0], some_number[1], some_number[2],
more_numbers[0], more_numbers[1], more_numbers[2]);

return(0);
}


Learn to code in the C language (1/3)




Gentle introduction to coding computers, using the C programming language, in well under 90 minutes (this is part 1 of 3).

After the first three "gentle introduction lessons" I will do another series of videos with an example game and more advanced subjects (graphics, sound, etc). You have to start somewhere and this first hour is really a soft way to create some sort of familiarity with what C code looks like and how to read it.

You get a link to a free MagPi magazine issue and links to the example code in the video description on Youtube.

You can see the video and then read the first three chapters of the magazine, but I recommend you do it the other way around: read the first three chapters and then see the video.

Do not be in a hurry to "read every lesson" or "watch every video"! Your time will be better spent trying to write code similar to the examples and experimenting with your new found skills. In fact, it is crucial that you take it slow, type code, make mistakes and learn with them.

Do it in the morning, after a good night sleep (trust me, you will learn faster, caffeine is not a replacement for a good night sleeping). Programming is hard and you are not dumb. If you have questions please leave a comment in the video, I will try to answer as many of those as possible.

Suggestions after the first three lessons:

1 - Write a program that counts up from 0 to 10 (hey, its a reversion of the "ten little Indians" example, how hard can it be?).

2 - how about a program that prints all the numbers that are multiples of 3 (examples 6, 9, 12, etc) bellow 30?

3 - Can you make the previous exercise without declaring floating point numbers (using only type casting, that is explained in this video)?

Have fun! Because learning is meant to be a fun experience. Go for it!




Example 1 used in the video:


/*
* This is a comment... :-)
* A multi-line example
*/
#include


void main(void)
{
// another type of comment... single line
printf("You can do it, programming is hard, and you are not dumb.\n So persevere and you will get it!\n\n");
}


Example 2 used in the video:


/*
* lets learn aboutariables and arithmetic :-)
*/
#include

void main(void)
{
int apples=10;
int persons=3;
float portion;

portion = apples / persons;

printf("%d apples, divided by %d people means you will each one eat %f apples!\n\n", apples, persons, portion);

// opsss... hey, "3" is not the correct answer! This is our first ever computer bug!



// now lets tell the compiler this is an operation that requires the "int" values to be considered "float"
portion = (float) apples / (float) persons;

printf("%d apples, divided by %d people means you will each one eat %f apples!\n\n", apples, persons, portion);

}


Example 3 used in the video:


/*
* lets learn aboutariables and arithmetic :-)
*/
#include

void main(void)
{
float apples=10;
float persons=3;
float portion;

portion = apples + persons;

printf("%f apples, divided by %f people means you will each one eat %f apples!\n\n", apples, persons, portion);
}



Example 4 used in the video:


/*
* Lets learn about conditions and comparisons, and meet the "While" loop :-)
*/
#include

void main(void)
{
int indians=10;

while(indians>0)
{
if(indians==10)
{
printf("Ten little indians gathered in an island\n");
}
else
{
printf("%d little indians left...\n", indians);
}

// the misterious murderer kills another little indian here...
indians = indians - 1;
printf("One little indian died...\n");
}



printf("... and then, there were none...\n\n");
}


Example "drawing sprites & collision" in Python


This example uses python 3 with a Raylib (https://www.raylib.com) wrapper (https://pypi.org/project/raylib/) that uses CFFI API static bindings (this is the fastest approach, and keeps the code as close as possible to the original C, which I feel is the best approach when using a C library).

Create a folder called "resources" (in the same directory as your code) and place the two images (provided bellow) there.

hero_shipufo1


Here is the Python sample code…



from raylib.static import *
from ctypes import *

screenWidth = 800
screenHeight = 600

InitWindow(screenWidth, screenHeight, b"sprites & collision example")

SetTargetFPS(60)

# hero ship
speed = 4.0
ship_size_width = 50
ship_size_height = 75

ship_position={'x': screenWidth/2.0, 'y': screenHeight-ship_size_height}
ship_rectangle = { 'x': ship_position["x"], 'y': ship_position["y"],'width': ship_size_width, 'height': ship_size_height }
image_hero_ship = LoadImage(b"resources/hero_ship.png")

ImageResize(ffi.addressof(image_hero_ship), ship_size_width, ship_size_height)

hero_ship=LoadTextureFromImage(image_hero_ship)


#bad dude ship
baddude_speed = 4.0
baddude_ship_size_width = 100
baddude_ship_size_height = 50

baddude_ship_position={'x': screenWidth/2.0, 'y': 0}
baddude_ship_rectangle = { 'x': baddude_ship_position["x"], 'y': baddude_ship_position["y"], 'width': baddude_ship_size_width, 'height': baddude_ship_size_height }
image_baddude_ship = LoadImage(b"resources/ufo1.png")

ImageResize(ffi.addressof(image_baddude_ship), baddude_ship_size_width, baddude_ship_size_height)

baddude_ship=LoadTextureFromImage(image_baddude_ship)



# detect collision
def my_check_collision_recs(rec1,rec2):
if rec1["x"] < rec2["x"] + rec2["width"] and rec1["x"] + rec1["width"] > rec2["x"] and rec1["y"] < rec2["y"] + rec2["height"] and rec1["y"] + rec1["height"] > rec2["y"]:
return 1
else:
return 0



while not WindowShouldClose():

# control the heroship
if IsKeyDown(KEY_RIGHT):
ship_position["x"] += 2.0
ship_rectangle["x"] += 2.0
if IsKeyDown(KEY_LEFT):
ship_position["x"] -= 2.0
ship_rectangle["x"] -= 2.0
if IsKeyDown(KEY_UP):
ship_position["y"] -= 2.0
ship_rectangle["y"] -= 2.0
if IsKeyDown(KEY_DOWN):
ship_position["y"] += 2.0
ship_rectangle["y"] += 2.0

BeginDrawing()

ClearBackground(RAYWHITE)
DrawTexture(baddude_ship, int(baddude_ship_position["x"]), int(baddude_ship_position["y"]), LIGHTGRAY)
DrawTexture(hero_ship, int(ship_position["x"]), int(ship_position["y"]), LIGHTGRAY)


if my_check_collision_recs(ship_rectangle, baddude_ship_rectangle):
DrawText(b"BOOM", 10, 10, 20, LIGHTGRAY)


EndDrawing()
CloseWindow()


Example "mouse wheel input" in Python

This example uses python 3 with a Raylib (https://www.raylib.com) wrapper (https://pypi.org/project/raylib/) that uses CFFI API static bindings (this is the fastest approach, and keeps the code as close as possible to the original C, which I feel is the best approach when using a C library).

https://www.raylib.com/examples/web/core/loader.html?name=core_input_mouse_wheel

The original C example, edited for easier comparison:


#include "raylib.h"

int main(void)
{
const int screenWidth = 800;
const int screenHeight = 450;

InitWindow(screenWidth, screenHeight, "raylib [core] example - input mouse wheel");

int boxPositionY = screenHeight/2 - 40;
int scrollSpeed = 4; // Scrolling speed in pixels

SetTargetFPS(60); // Set our game to run at 60 frames-per-second

while (!WindowShouldClose()) // Detect window close button or ESC key
{
boxPositionY -= (GetMouseWheelMove()*scrollSpeed);

BeginDrawing();

ClearBackground(RAYWHITE);

DrawRectangle(screenWidth/2 - 40, boxPositionY, 80, 80, MAROON);

DrawText("Use mouse wheel to move the cube up and down!", 10, 10, 20, GRAY);
DrawText(FormatText("Box position Y: %03i", boxPositionY), 10, 40, 20, LIGHTGRAY);

EndDrawing();
}

CloseWindow(); // Close window and OpenGL context

return 0;
}



The Python version:



from raylib.static import *

screenWidth = 800
screenHeight = 450

InitWindow(screenWidth, screenHeight, b"raylib [core] example - input mouse wheel")

boxPositionX = screenWidth/2 - 40
boxPositionY = screenHeight/2 - 40
scrollSpeed = 4


SetTargetFPS(60)


while not WindowShouldClose():
boxPositionY -= GetMouseWheelMove()*scrollSpeed

BeginDrawing()
ClearBackground(RAYWHITE)
DrawRectangle(int(boxPositionX), int(boxPositionY), 80, 80, MAROON)

DrawText(b"Use mouse wheel to move the cube up and down!", 10, 10, 20, LIGHTGRAY)

yCoord="Box position Y: {}".format(int(boxPositionY))
DrawText(yCoord.encode('ascii'), 10, 40, 20, LIGHTGRAY)

EndDrawing()
CloseWindow()

Example "mouse input" in Python

This example uses python 3 with a Raylib (https://www.raylib.com) wrapper (https://pypi.org/project/raylib/) that uses CFFI API static bindings (this is the fastest approach, and keeps the code as close as possible to the original C, which I feel is the best approach when using a C library).

https://www.raylib.com/examples/web/core/loader.html?name=core_input_mouse

The original C example, edited for easier comparison:


#include "raylib.h"

int main(void)
{
const int screenWidth = 800;
const int screenHeight = 450;

InitWindow(screenWidth, screenHeight, "raylib [core] example - mouse input");

Vector2 ballPosition = { -100.0f, -100.0f };
Color ballColor = DARKBLUE;

SetTargetFPS(60); // Set our game to run at 60 frames-per-second

while (!WindowShouldClose()) // Detect window close button or ESC key
{
ballPosition = GetMousePosition();

if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) ballColor = MAROON;
else if (IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON)) ballColor = LIME;
else if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) ballColor = DARKBLUE;

BeginDrawing();

ClearBackground(RAYWHITE);

DrawCircleV(ballPosition, 40, ballColor);

DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY);

EndDrawing();
}

// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context

return 0;
}



The Python version:



from raylib.static import *

screenWidth = 800
screenHeight = 450

InitWindow(screenWidth, screenHeight, b"raylib [core] example - mouse input")

# Vector2 may be list or tuple or dict or struct-cdata...going with dictionary for ballPosition
ballPosition = {'x': -100, 'y': -100}
ballColor = DARKBLUE


SetTargetFPS(60)


while not WindowShouldClose():
ballPosition = GetMousePosition()

if IsMouseButtonPressed(MOUSE_LEFT_BUTTON):
ballColor = MAROON
elif IsMouseButtonPressed(MOUSE_MIDDLE_BUTTON):
ballColor = LIME
elif IsMouseButtonPressed(MOUSE_RIGHT_BUTTON):
ballColor = DARKBLUE

BeginDrawing()
ClearBackground(RAYWHITE)
DrawText(b"move ball with mouse and click mouse button to change color", 10, 10, 20, LIGHTGRAY)
DrawCircleV(ballPosition, 50, ballColor)
EndDrawing()
CloseWindow()