Termbank
  1. A
    1. Abstraction
    2. Alias
    3. Argument
    4. Array
  2. B
    1. Binary code file
    2. Binary number
    3. Bit
    4. Bitwise negation
    5. Bitwise operation
    6. Byte
  3. C
    1. C library
    2. C-function
    3. C-variable
    4. Character
    5. Code block
    6. Comment
    7. Compiler
    8. Complement
    9. Conditional statement
    10. Conditional structure
    11. Control structure
  4. D
    1. Data structure
    2. Duck typing
  5. E
    1. Error message
    2. Exception
  6. F
    1. Flag
    2. Float
  7. H
    1. Header file
    2. Headers
    3. Hexadecimal
  8. I
    1. Immutable
    2. Initialization
    3. Instruction
    4. Integer
    5. Interpreter
    6. Introduction
    7. Iteroitava
  9. K
    1. Keyword
  10. L
    1. Library
    2. Logical operation
  11. M
    1. Machine language
    2. Macro
    3. Main function
    4. Memory
    5. Method
  12. O
    1. Object
    2. Optimization
  13. P
    1. Parameter
    2. Placeholder
    3. Pointer
    4. Precompiler
    5. Precompiler directive
    6. Prototype
    7. Python console
    8. Python format
    9. Python function
    10. Python import
    11. Python list
    12. Python main program
    13. Python variable
    14. Python-for
    15. Pääfunktio
    16. printf
  14. R
    1. Resource
    2. Return value
  15. S
    1. Statement
    2. Static typing
    3. String
    4. Syntax
  16. T
    1. Terminal
    2. Type
    3. Typecast
  17. U
    1. Unsigned
  18. V
    1. Value
  19. W
    1. Warning
    2. while
Completed: / exercises

Functions in C

Learning Objectives: The student knows the structure of a C program and can use functions in a C program.
As we have already hinted in the introductory material, every C program always has at least one function, called main. This function is automatically called by the operating system (or firmware) when the program starts. In fact, the execution of a C program lasts exactly as long as the execution of the main function. But more about this in the hardware-oriented section...
In the course, we think of a C program modularly as a collection of different independent functionalities. Each functionality/task has its own inputs/parameters, functionality, and response/results. In modular programming, tasks are implemented as separate modules / subroutines, which in C are called functions. Thus, the logic of the program is based on passing the results and arguments of functions as variables from one function to another. For example, reading measurement results from a temperature sensor in an embedded system:
  1. Initialize and calibrate the temperature sensor
// Function to initialize the temperature sensor
void initialize_sensor() {
    // Code to set up I2C communication
    setup_I2C();

    // Code to configure the sensor's registers
    configure_sensor_registers();
}

// Function to set up I2C communication
void setup_I2C() {
    // Hardware-specific code to initialize I2C communication
    // Example: Set the clock speed, enable the I2C peripheral, etc.
}

// Function to configure the sensor's registers
void configure_sensor_registers() {
    // Hardware-specific code to configure the sensor
    // Example: Set the resolution, measurement mode, etc.
}


  1. Request the measurement result from the sensor
// Function to read the temperature from the sensor
float read_temperature() {
    // Send command to the sensor to start a measurement
    send_measurement_command();

    // Read the data from the sensor's output register
    int raw_data = read_sensor_data();

    // Convert the raw data to a temperature value
    float temperature = convert_to_temperature(raw_data);

    return temperature;
}

// Function to send a measurement command to the sensor
void send_measurement_command() {
    // Hardware-specific code to send a command to the sensor
    // Example: Write to a specific register address via I2C
}

// Function to read data from the sensor
int read_sensor_data() {
    // Hardware-specific code to read data from the sensor's output register
    // Example: Read bytes from a specific register address via I2C
    int data = 0;  // Placeholder for actual data read
    return data;
}

// Function to convert raw sensor data to a temperature value
float convert_to_temperature(int raw_data) {
    // Code to convert the raw data to a human-readable temperature value
    // Example: Apply the sensor-specific formula
    float temperature = raw_data * 0.01;  // Example conversion factor
    return temperature;
}



  1. Display the measurement result on the screen
// Function to display the temperature on the screen
void display_temperature(float temperature) {
    // Code to format and send the temperature value to the display
    // Example: Send data to an LCD or a serial terminal
    printf("Current Temperature: %.2f°C\n", temperature);
}

The main function usually acts as an entry point of the C program, but the implementation of the different functionality is done in other functions that are called from main.
int main() {
    // Initialize the temperature sensor
    initialize_sensor();

    // Read the temperature
    float temperature = read_temperature();

    // Display the temperature
    display_temperature(temperature);

    return 0;
}

Note! In Python the equivalent to main would be:
def main():
    # Main program logic goes here
    print("This is the main function.")

if __name__ == "__main__":
    main()
Note! All C programming exercises in the course will involve implementing different functions.
This way of programming offers multiple advantages, among them:

First C Program

Let's first take a general look at the structure of a C program. At this point, you don't need to know everything that happens in the code below, but rather to grasp the four essential parts of a C program's structure.
/**************************************
 * First C program                         
 **************************************/

/*
 * Preprocessor directives
 */
// Include the stdio library in the program
#include <stdio.h> 

// Define the constant PI
#define PI 3.14159 

/*
 * Declaration of internal functions and variables in the program
 */

// Declare a custom function calculate_area using a prototype
float calculate_area(float radius);  

/*
 * Implementation of the main function 
 */
int main() { 

   // Declaration (and initialization) of internal variables in the main program
   float circle_area = 0.0, circle_radius = 0.0;

   // Main program functionality
   printf("Enter the circle's radius: "); 
   scanf("%f", &circle_radius);  
   circle_area = calculate_area(circle_radius);
   printf("The area of the circle is: %.2f\n", circle_area);

   // Return value of the main program (function)
   return 0;  
}  

/*
 * Function: calculate_area, calculates the area of a circle given its radius
 * Arguments: radius, the circle's radius
 */
float calculate_area(float radius)  {

	//Declaration (and initialization) of internal variables in the function
   float area = 0.0;

   // Functionality of the function
   area = PI * radius * radius;

   // Return value of the function
   return area;  
}
Let's examine the components that make up a C program:
1. Preprocessor directives guide the compilation process of the program and serve various purposes. At this stage, you need to know:
2. Declaration of internal functions and variables in the program using prototypes. The prototype tells the program what functions are available.
3. Implementation of the main function main.
4. The functionality of the internal functions declared in the program.

Function Prototype

In C programming, a function is introduced through its prototype. A prototype generally takes the following form:
  1. return_type, the type of value that the function returns at the end of its execution.
  2. function_name, the name by which the function is called in the program.
  3. ( variable_type1 variable1, variable_type2 variable2, ...), these definitions indicate what types of parameters the function accepts and by what variable names they can be handled within the function.
Example. A function named calculate_area returns a floating-point number of type float and takes a floating-point number as input (in the variable radius).
// Declare a custom function calculate_area using a prototype
float calculate_area(float radius);  

Why a Prototype?

Okay, but why do we need a prototype? Without delving too deep into the world of compilers, let's just say that in C, a prototype allows a function to be used in a program before its code has been compiled. In the example, the main function can already use the calculate_area function before its code has been encountered by the compiler as it processes the C source file.
The compiler thus trusts the programmer's promise that an implementation of the function matching the prototype will appear at some point during the compilation process. Upon finding the prototype, the compiler only checks the syntax of the function call, ensuring that the function is called correctly in terms of name and parameters.
From now on in this course, when we create functions, we will always first declare a prototype! If the implementation is not found in the program's source files or included libraries, the compilation will end with an error message. Well-behaved compilers will even halt the entire compilation process and warn you if the prototype is missing from the program.
In the code example above:
// The prototype promises that such a function exists
float calculate_area(float radius);  

// With the prototype, the function can be used
int main() { 
   circle_area = calculate_area(circle_radius);
}

// The actual function implementation
float calculate_area(float radius)  {

   float area = 0.0;
   area = PI * radius * radius;

   return area;  
}
Let's revisit the preprocessor directives briefly: in fact, the command #include <stdio.h> fetches the prototypes for the scanf and printf functions that we use in our program. This function is in stdio.h. This allows us to bring ready-made library functions into our program via their prototypes.
Note! C programming exercises also require a prototype in the task solution.

Function Parameters

Function parameters, written between parenthesis, defines which values should receive a function. A parameter, and the value passed to the function, i.e., the argument, is a way to pass information to the function from the calling code and to return information from the function to the calling code.
In the example code above, the function is declared to take a single floating-point argument.
float calculate_area(float radius);  
If a function does not take arguments or does not return a value, the reserved word void is used in its declaration for clarity.
void not_returning_anything(uint8_t x, uint8_t y);
int32_t no_arguments_needed(void);
void leave_me_alone(void);
Technically, the word void is not mandatory in such function declarations, but without void, the compiler might assume certain things about the function... for example, without void, the compiler might assume the function returns an int type integer, which could lead to warnings or error messages. For clarity, it is always advisable to use the word void when necessary.
Note! In the example, the main function is implemented in the program without parameter definitions. In some development environments, you will encounter main functions with defined parameters. These parameters include command line arguments provided when launching the program. This is common on workstations but not typically used in embedded systems, which is why you won't see it in course examples.

Function Implementation

The function implementation is done modularly within its own code block, which in C is marked and enclosed with curly braces as a separate functional unit. (In Python, curly braces are replaced by indentation.)
/*
 * Function: calculate_area, calculates the area of a circle given its radius
 * Arguments: radius, the circle's radius
 */
float calculate_area(float radius)  {

   // Declaration (and initialization) of internal variables in the function
   float area = 0.0;

   // Function functionality
   area = PI * radius * radius;

   // Function return value
   return area;  
}
The function implementation is also divided into three parts:
  1. Functions usually declare internal, i.e., local, variables.
    • Local variables exist only within the function during its execution and disappear when the execution ends.
    • In the example above, the variable area is a local variable.
    • The current C standard does allow for variable declarations in the middle of the code, but it is still clearest for a beginner to declare variables collectively at the beginning of the function implementation.
  2. The function implementation consists of C language statements, which end with a semicolon.
  3. The function return value is set.
    • In the example, the value of the local variable area is returned.

Function Return Value

In C, a function can return only one value using the return statement, which is typically the result of the function or information about the success of the function's execution. The return value can be of any C variable type, except for arrays (we will come back to this). Note that the return value can be something complex like a struct.
In the example above, the function calculate_area returns the value of the internal variable area, which is stored in the internal variable circle_area in the main function.
int main() { 

   float circle_area = 0.0;
   circle_area = calculate_area(circle_radius);
}
In C, the main function is a special case because it is called by the operating system or firmware, and once it finishes, the execution of the program also ends. Therefore, its return value can be used to convey information to the operating system about what happened during the program's execution, for example, whether everything went smoothly or if an error occurred.
For this reason, main functions typically return a numeric value as their last command. By convention, zero indicates that the program executed successfully without errors, and other return values indicate some error occurred during execution, which may not have necessarily crashed the program. Such error codes are defined by the operating system or firmware, and we will not delve deeper into them in this course.
int main() { 
   ...
   // everything is ok
   return 0;  
}  

Function Call

In C syntax, a function is called, as in other languages, by its name and by providing the values of the parameters.
int main() { 
  float circle_radius = 2.45;
  circle_area = calculate_area(circle_radius);
}  
In C, you need to be more precise in a function call than in some other languages.
Additionally, in a C function call, you could, for example, use another function call in place of a variable, with the return value of that function being passed as an argument to the called function. This means that functions can be chained in C.
   call_me(call_a_friend(hey_return_something(you_return_this())));
int add(int a, int b) {
    return a + b;
}

int multiply(int x, int y) {
    return x * y;
}

int result = multiply(add(2, 3), 4);  // First adds 2 and 3, then multiplies the result by 4

Embedded Functions

When programming embedded systems, we need to know a bit more about the inner workings of functions to be efficient programmers.
A feature of C is that the compiler creates a function's arguments as an internal variable in the function, where the value of the argument is copied. This presents a significant pitfall because embedded devices often have limited memory. This makes it (unfortunately) easy to run out of memory during program execution, typically causing the program to crash due to a memory access violation. In desktop programming, this issue is not as critical because memory is available in gigabytes versus a few kilobytes in an embedded device.
Let's examine this with an example. Below, in the main function, we have a variable circle_radius, which is passed to the calculate_area function as a parameter to the local variable radius. Thus, the value of the argument is copied and stored in two different variables during the program's execution.
int main() { 
  ...
  float circle_radius = 2.45;
  circle_area = calculate_area(circle_radius);
  ...
}  
float calculate_area(float radius)  {
...
}
But let's dramatize the situation by introducing a function send_message, which takes a struct that contains an array of 4 bytes destination_address and a string message of 2-kilobytes as an argument.
// Define a struct for the message
typedef struct {
    char destination_address[4];  // 4-byte address
    char message[2048];           // 2-kilobyte message
} Message;

// Function prototype
void send_message(Message message_home); 
...
// Declare a message struct and fill it with data
Message message_home = {"ABCD", "This is the message content..."};
...
// Call the function with the struct as an argument
send_message(message_home);
...
Now, in the send_message function, a copy of the entire 2048-character message would be made along with the 4-byte address to a local struct of the same size, consuming additional memory temporarily every time the function is called. The danger lies here: at some point during the program's execution, there may be enough memory available, but as the program progresses, memory might no longer be sufficient elsewhere. Such a silent error is difficult because the cause is not obvious to the user (or the programmer).
Ouch... so how can we pass large data structures or arrays to functions? We'll return to this shortly when we introduce new variable types, and later in the material, we'll become familiar with pointer variables.

New Variable Types

It was noted above that local variables defined within a function exist only within the function where they are declared and only for the duration of its execution. This applies even to the main function, despite its otherwise special nature.
We just learned that variables can be passed between functions via arguments and return values, but in addition to this, in C, we can define global and static variables.

Global Variable

A global variable is defined outside of all function definitions, making it accessible in all functions within the code module/file, just like the local variables in functions, except that a global variable does not need to be declared at the beginning of the function implementation.
An example of using a global variable:
/*
 * Declaration of internal variables and functions in the program
 */
float oh_yes_i_am_global = 3.14; 

/*
 * Implementation of the main function 
 */
int main() {
    
   float i_am_local_to_main = 3.14;    
   printf("Print the global variable in main: %f\n", oh_yes_i_am_global );
   oh_yes_i_am_global = 2.71828; 
   print_variables(i_am_local_to_main); 
   
   return 0;
}

/*
 * Function: print_variables
 */
void print_variables(float i_am_argument) {
    float i_am_local = 3.14;

   printf("Print the argument in the function: %f\n", i_am_argument);
   printf("Print the local variable in the function: %f\n", i_am_local );    
   printf("Print the global variable in the function: %f\n", oh_yes_i_am_global );
}
Note! If a global variable is redefined within a function implementation, it actually overrides the global variable declaration within the function and creates a new local variable with the same name... oops.
There are two reasons for using global variables:
  1. They are alive throughout the program's execution and have a broader scope in the program code, i.e., all functions in the module.
  2. They can be used instead of function parameters and return values to save memory. In embedded programming, it is convenient to pass information between different functions in the program without continuously creating copies of the arguments.
    • This is one way to handle structs in embedded C programming: by making them global, you don't need to pass them as function parameters.
However, as a result, tracking down errors in the program can become more difficult because, well... they are accessible everywhere in the program, making bug tracking more challenging. Global variables also create dependencies between functionalities (functions), potentially compromising the program's modularity and leading to hard-to-understand bugs.
Finally, note that global variables can also be passed between code modules in larger C programs, but this involves significant pitfalls, so we won't cover that in detail...

Static Variable

A static variable is also useful in some cases. The idea is that the variable is initialized once and retains its value between function calls. In this case, the variable is declared with the static keyword.
As an example, consider using a function's local variable as a counter.
void counter(void) {

   static uint64_t count = 0;
   count++;
}
In the function, the value of the count variable starts from the initialization value of zero and increases by one each time the function is called. Although the variable retains its value, it is still only a local variable and not accessible outside the function.
For your information, the static keyword has other uses, but we won't cover them in this course.

Conclusion

Regarding coding style, it's important to keep the function size (in terms of the number of program statements) reasonable. As a rule of thumb, if the function's line count doesn't fit on the screen at once, consider splitting the function into smaller functions. This will ultimately pay off in terms of debugging, maintainability, and readability of the code.
Playing with functions really kicks off when you start exploring C's standard and peripheral libraries and working on your own programs!
?
Abstraction is a process through which raw machine language instructions are "hidden" underneath the statements of a higher level programming language. Abstraction level determines how extensive the hiding is - the higher the abstraction level, the more difficult it is to exactly say how a complex statement will be turned into machine language instructions. For instance, the abstraction level of Python is much higher than that of C (in fact, Python has been made with C).
Alias is a directive for the precompiler that substitus a string with another string whenever encountered. In it's basic form it's comparable to the replace operation in a text editor. Aliases are define with the #define directeve, e.g. #define PI 3.1416
Argument is the name for values that are given to functions when they are called. Arguments are stored into parameters when inside the function, although in C both sides are often called just arguments. For example in printf("%c", character); there are two arguments: "%c" format template and the contents of the character variable.
Array is a common structure in programming languages that contains multiple values of (usually) the same type. Arrays in C are static - their size must be defined when they are introduced and it cannot change. C arrays can only contain values of one type (also defined when introduced).
Binary code file is a file that contains machine language instructions in binary format. They are meant to be read only by machines. Typically if you attempt to open a binary file in a text editor, you'll see just a mess of random characters as the editor is attempting to decode the bits into characters. Most editors will also warn that the file is binary.
Binary number is a number made of bits, i.e. digits 0 and 1. This makes it a base 2 number system.
A bit is the smallest unit of information. It can have exactly two values: 0 and 1. Inside the computer everything happens with bits. Typically the memory contains bitstrings that are made of multiple bits.
Bitwise negation is an operation where each bit of a binary number is negated so that zeros become ones and vice versa. The operator is ~.
Bitwise operations are a class of operations with the common feature that they manipulate individual bits. For example bitwise negation reverses each bit. Some operations take place between two binary values so that bits in the same position affect each other. These operations include and (&), or (|) and xor (^). There's also shift operations (<< and >>) where the bits of one binary number are shifted to the left or right N steps.
Byte is the size of one memory slot - typically 8 bits. It is the smallest unit of information that can be addressed from the computer's memory. The sizes of variable types are defined as bytes.
External code in C is placed in libraries from which they can be taken to use with the #include directive. C has its own standard libraries, and other libraries can also be included. However any non-standard libraries must be declared to the compiler. Typically a library is made of its source code file (.c) and header file (.h) which includes function prototypes etc.
Functions in C are more static than their Python counterparts. A function in C can only have ne return value and its type must be predefined. Likewise the types of all parameers must be defined. When a function is called, the values of arguments are copied into memory reserved for the function parameters. Therefore functions always handle values that are separate from the values handled by the coe that called them.
C variables are statically typed, which means their type is defined as the variable is introduced. In addition, C variables are tied to their memory area. The type of a variable cannot be changed.
Character is a single character, referred in C as char. It can be interpreted as an ASCII character but can also be used as an integer as it is the smallest integer that can be stored in memory. It's exactly 1 byte. A character is marked with single quotes, e.g. 'c'.
Code block is a group of code lines that are in the same context. For instance, in a conditional structure each condtion contains its own code block. Likewise the contents of a function are in their own code block. Code blocks can contain other code blocks. Python uses indentation to separate code blocks from each other. C uses curly braces to mark the beginning and end of a code block.
Comments are text in code files that are not part of the program. Each language has its own way of marking comments. Python uses the # character, C the more standard //. In C it's also possible to mark multiple lines as comments by placing them between /* and */.
A compiler is a program that transforms C source code into a binary file containing machine language instructions that can be executed by the computer's processor. The compiler also examines the source code and informs the user about any errors or potential issues in the code (warnings). The compiler's behavior can be altered with numerous flags.
Complement is a way to represent negative numbers, used typically in computers. The sign of a number is changed by flipping all its bits. In two's complement which is used in this course, 1 is added to the result after flipping.
Conditional statement is (usually) a line of code that defined a single condition, followed by a code block delimited by curly braces that is entered if the condition evaluates as true. Conditional statements are if statements that can also be present with the else keyword as else if. A set of conditional statements linked together by else keywords are called conditional structures.
Conditional structure is a control structure consisting of one or more conditional statements. Most contrl structures contain at least two branches: if and else. Between these two there can also be any number of else if statements. It is however also possible to have just a single if statement. Each branch in a conditional structure cotains executable code enclosed within a block. Only one branch of the structure is ever entered - with overlapping conditions the first one that matches is selected.
Control structures are code structures that somehow alter the program's control flow. Conditional structures and loops belong to this category. Exception handling can also be considered as a form of control structure.
Data structure is a comman name for collection that contain multiple values. In Python these include lists, tuples and dictionaries. In C the most common data structures are arrays and structs.
Python's way of treating variable values is called dynamic typing aka duck typing. The latter comes from the saying "if it swims like a duck, walks like a duck and quacks like a duck, it is a duck". In other words, the validity of a value is determined by its properties in a case-by-case fashion rather than its type.
An error message is given by the computer when something goes wrong while running or compiling a program. Typically it contains information about the problem that was encountered and its location in the source code.
An exception is what happens when a program encounters an error. Exceptions have type (e.g. TypeError) that can be used in exception handling within the program, and also as information when debugging. Typically exceptions also include textual description of the problem.
Flags are used when executing programs from the command line interface. Flags are options that define how the program behaves. Usually a flag is a single character prefixed with a single dash (e.g. -o) or a word (or multiple words connected with dashes) prefixed with two dashes (e.g. --system. Some flags are Boolean flags which means they are either on (if present) or off (if not present). Other flags take a parameter which is typically put after the flag separated either by a space or = character (e.g. -o hemulen.exe.
Floating point numbers are an approximation of decimal numbers that are used by computers. Due to their archicture computers aren't able to process real decimal numbers, so they use floats instead. Sometimes the imprecision of floats can cause rounding errors - this is good to keep in mind. In C there are two kinds of floating point numbers: float and double, where the latter has twice the number of bits.
Header files use the .h extension, and they contain the headers (function prototypes, type definitions etc.) for a .c file with the same name.
Headers in C are used to indicate what is in the code file. This includes things like function prototypes. Other typical content for headers are definition of types (structs etc.) and constants. Headers can be at the beginning of the code file, but more often - especially for libraries - they are in placed in a separate header (.h) file.
Hexadecimal numbers are base 16 numbers that are used particularly to represent memory addresses and the binary contents of memory. A hexadecimal number is typically prefixed with 0x. They use the letters A-F to represent digits 10 to 15. Hexadecimals are used because each digit represents exactly 4 bits which makes transformation to binary and back easy.
In Python objects were categorized into mutable and immutable values. An immutable value cannot have its contents changed - any operations that seemingly alter the object actually create an altered copy in a new memory location. For instance strings are immutable in Python. In C this categorization is not needed because the relationship of variables and memory is tighter - the same variable addresses the same area of memory for the duration of its existence.
When a variable is given its initial value in code, the process is called initialization. A typical example is the initialization of a number to zero. Initialization can be done alongside with introduction: int counter = 0; or separately. If a variable has not been initialized, its content is whatever was left there by the previous owner of the memory area.
Instruction set defines what instructions the processor is capable of. These instructions form the machine language of the processor architecture.
Integers themselves are probably familiar at this point. However in C there's many kinds of integers. Integer types are distinguished by their size in bits and whether they are signed or not. As a given number of bits can represent up to (2 ^ n) different integers, the maximum value for a signed integer is (2 * (n - 1))
Python interpreter is a program that transforms Python code into machine language instructions at runtime.
The moment a variable's existence is announed for the first is called introduction. When introduced, a variable's type and name must be defined, e.g. int number;. When a variable is introduced, memory is reserved for it even though nothing is written there yet - whatever was in the memory previously is still there. For this reason it's often a good idea to initialize variables when introducing them.
Iteroitava objekti on sellainen, jonka voi antaa silmukalle läpikäytäväksi (Pythonissa for-silmukalle). Tähän joukkoon kuuluvat yleisimpinä listat, merkkijonot ja generaattorit. C:ssä ei ole silmukkaa, joka vastaisi Pythonin for-silmukan toimintaa, joten taulukoiden yms. läpikäynti tehdään indeksiä kasvattavilla silmukoilla.
Keywords are words in programming languages that have been reserved. Good text editors generally use a different formatting for keywords (e.g. bold). Usually keywords are protected and their names cannot be used for variables. Typical keywords include if and else that are used in control structures. In a way keywords are part of the programming language's grammar.
A library is typically a toolbox of functions around a single purpose. Libraries are taken to use with the include directive. If a library is not part of the C standard library, its use must also be told to the compiler.
Logical operation refers to Boole's algebra, dealing with truth values. Typical logical operations are not, and, or which are often used in conditional statements. C also uses bitwise logical operations that work in the same way but affect each bit separately.
Machine language is made of instructions understood by the processor. Machine language is often called Assembly and it is the lowest level where it's reasonable for humans to give instructions to computers. Machine language is used at the latter part of this course - students taking the introduction part do not need to learn it.
Macro is an alias that defines a certain keyword to be replaced by a piece of code. When used well, macros can create more readable code. However, often the opposite is true. Using macros is not recommended in this course, you should just be able to recognize one when you see it.
In C the main function is the starting point when the program is run. The command line arguments of the program are passed on to the main function (although they do not have to be received), and its return value type is int. At its shortest a main function can defined as int main().
When programs are run, all their data is stored in the computer's memory. The memory consists of memory slots with an address and contents. All slots are of equal size - if an instance of data is larger, a continuous area of multiple memory slots is reserved.
Method is a function that belongs to an object, often used by the object to manipulate itself. When calling a method, the object is put before the method: values.sort().
Object is common terminology in Python. Everything in Python is treated as objects - this means that everything can be referenced by a variable (e.g. you can use a variable to refer to a function). Objects are typically used in object-oriented languages. C is not one.
Optimization means improving the performance of code, typically by reducing the time it takes to run the code or its memory usage. The most important thing to understand about opimization is that it should not be done unless it's needed. Optimization should only be considered once the code is running too slowly or doesn't fit into memory. Optimization should also not be done blindly. It's important to profile the code and only optimize the parts that are most wasteful.
A parameter is a variable defined alongside with a function. Parameters receive the values of the function's arguments when it's called. This differentation between parameters and arguments is not always used, sometimes both ends of the value transfer are called arguments.
Placeholders are used in string formatting to mark a place where a value from e.g. a variable will be placed. In Python we used curly braces to mark formatting placeholders. In C the % character is used which is followed by definitions, where the type of the value is mandatory. For instance "%c" can only receive a char type variable.
Pointers in C are special variables. A pointer contains a memory address of the memory location where the actual data value is located. In a sense they work like Python variables. A variable can be defined as a pointer by postfixing its type with * when it's being introduced, e.g. int* value_ptr; creates a pointer to an integer. The contents of the memory address can be fetched by prefixing the variable name with * (e.g. *value_ptr. On the other hand, the address of a memory adress can be fetched by prefixing a variable name with &, (e.g. &value.
The C precompiler is an apparatus that goes through all the precompiler directives in the code before the program is actually compiled. These directives include statements which add the source code of the included libraries into the program, and define directives that can define constant values (aliases) and macros.
Directives are instructions that are addressed at the precompiler. They are executed and removed from the code before the actual compilation. Directives start with the # character. The most common one is include which takes a library into use. Another common one is define, which is used e.g. to create constant values.
Prototype defines a function's signature - the type of its return value, its name and all the arguments. A prototype is separate from the actual function definition. It's just a promise that the function that matches the prototype will be found in the code file. Prototypes are introduced at the beginning of the file or in a separate header file. In common cases the prototype definition is the same as the line that actually starts the function introduction.
Interactive interpreter or Python console is a program where users can write Python code lines. It's called interactive because each code line is executed after its been fully written, and the interpreter shows the return value (if any).
The format method of string in Python is a powerful way to include variable values into printable text. The string can use placeholders to indicate where the format method's arguments are placed.
Python functions can have optional parameters that have a given default value. In Python the values of arguments in a function call are transferred to function parameters through reference, which means that the values are the same even though they may have different names. Python functions can have multiple return values.
In Python the import statement is used for bringing in modules/libraries - either built-in ones, thrid party modules or other parts of the same application. In Python the names from the imported module's namespace are accessible through the module name (e.g. math.sin). In C libraries are taken to use with include, and unlike Python import it brings the library's namespace into the program's global namespace.
Python lists were discovered to be extremely effective tools in Elementary Programming. A Python list is an ordered collection of values. Its size is dynamic (i.e. can be changed during execution) and it can include any values - even mixed types. Lists can also include other lists etc.
In Python main program is the part of code that is executed when the program is started. Usually the main program is at the end of the code file and most of the time under if __name__ == "__main__": if statement. In C there is no main program as such, code execution starts with the main function instead.
In Python a variable is a reference to a value, a connection between the variable's name in code and the actual data in memory. In Python variables have no type but their values do. The validity of a value is tested case by case when code is executed. In these ways they are different from C variables, and in truth Python variables are closer to C pointers.
Pythonin for-silmukka vastaa toiminnaltaan useimmissa kielissä olevaa foreach-silmukkaa. Se käy läpi sekvenssin -esim. listan - jäsen kerrallaan, ottaen kulloinkin käsittelyssä olevan jäsenen talteen silmukkamuuttujaan. Silmukka loppuu, kun iteroitava sekvenssi päättyy.
Pääfunktio on C:ssä ohjelman aloituspiste ja se korvaa Pythonista tutun pääohjelman. Oletuksena pääfunktion nimi on main ja se määritellään yksinkertaisimmillaan int main().
Resource referes to the processing power, memory, peripheral devices etc. that are availlable in the device. It includes all the limitations within which programs can be executed and therefore defines what is possible with program code. On a desktop PC resources are - for a programmer student - almost limitless, but on embedded devices resources are much more scarce.
Return value is what a function returns when its execution ends. In C functions can only have one return value, while in Python there can be multiple. When reading code, return value can be understood as something that replaces the function call after the function has been executed.
A statement is a generic name for a single executable set of instructions - usually one line of code.
C uses static typing This means that the type of variables is defined as they are created, and values of different types cannot be assigned to them. The validity of a value is determined by its type (usually done by the compiler). Python on the other hand uses dynamic typing aka.duck typing.
In Python all text is handled as strings and it has no type for single characters. However in C there are no strings at all - there's only character arrays. A character array can be defined like a string however, e.g. char animal[7] = "donkey"; where the number is the size of the array + 1. The +1 is neede because the string must have space for the null terminator '\0' which is automatically added to the end of the "string".
Syntax is the grammar of a programming language. If a text file does not follow the syntax of code, it cannot be executed as code, or in the case of C, it cannot be compiled.
Terminal, command line interface, command line prompt etc. are different names to the text-based interface of the operating system. In Windows you can start the command line prompt by typing md to the Run... window (Win+R). Command line is used to give text-based commands to the operating system.
The data in a computer's memory is just bits, but variables have type. Type defines how the bits in memory should be interpreted. It also defines how many bits are required to store a value of the type. Types are for instance int, float and char.
Typecast is an operation where a variable is transformed to another type. In the elementary course this was primarily done with int and float functions. In C typecast is marked a bit differently: floating = (float) integer}. It's also noteworthy that the result must be stored in a variable that is the proper type. it is not possible to change the type of an existing variable.
Unsigned integer is a an integer type where all values are interpreted as positive. Since sign bit is not needed, unsigned integers can represent twice as large numbers as signed integers of the same size. An integer can be introduced as unsigned by using the unsigend keyword, e.g. unsigned int counter;.
In the elementary programming course we used the term value to refer to all kinds of values handled by programs be it variables, statement results or anything. In short, a value is data in the computer's memory that can be referenced by variables. In C the relationship between a variable and its value is tighter as variables are strictly tied to the memory area where its value is stored.
A warning is a notification that while executing or - in this course particularly - compiling it, something suspicious was encountered. The program may still work, but parts of it may exhibit incorrect behavior. In general all warnings should be fixed to make the program stable.
One way to print stuff in C is the printf function, which closely resembles Python's print function. It is given a printable string along with values that will be formatted into the string if placeholders are used. Unlike Python, C's printf doesn't automatically add a newline at the end. Therefore adding \n at the end is usually needed.
Out of loops, while is based on repetition through checking a condition - the code block inside the loop is repeated until the loop's condition is false. The condition is defined similarly to conditional statements, e.g. while (sum < 21).