pts_demo
- pts_demo#Recreating Math Equations: added a note about PEMDAS
- Removed practice problems and solutions > unfinished
- pts_demo#What happens when you use different datatypes?: updated table
- pts_demo#Regarding loss of precision: added
Agenda/TOC (only covering highlighted)
- Variables: Where is your data going to go?
- Datatypes
- Primitive Datatypes
- Constant Variables
- Assignment Statements: Giving your variables data
- Declaration
- Assignment
- Initialization
- Multiple Variables at a time
- Operators: Doing operations on our data
- What happens when you use different datatypes?
- Operator Precedence and Associativity
- Recreating Math Equations
- Functions: Organizing your code
- The main Function
- Making Your Own Functions
- Segue: Running Your Code on VsCode
- Libraries and Input/Output
- stdio.h: printf() and scanf()
- stdio.h: scanf() and the address-of operator
- Conditional Statements: What ifs and Decision-Making
- If Statements
- What are conditions/conditionals?
- If-else Statements
- Nested If-else Statements
- Switch Statements
- Iterative Statements: Loops
- For Loop
- While Loop
- Do-while Loop
- Creating Art with Loops
- Practice Problems and Solutions
Practice and Solutions are available at the bottom!
Variables
When we program something, we're working with data. If we want to handle that data we store them in variables.
Entities that can store a value that can change during execution of a program/when it runs.
Datatypes
Variables are stored within the memory of your computer and the size depends on what kind of variable it is, or its datatype.
Dictates what kind of data the variable is holding. A variable declared as a certain datatype will only stay that way for the entire program.
Syntax:
<datatype> <identifier or variable name>;
Primitive Datatypes
There are a number of datatypes allowable in C but the most commonly used ones are what we call primitive data types. They're called that because they're the simplest or the most basic ones.
Data/Return Type | Prefix (Hungarian Notation) | Valid Example | For what? |
---|---|---|---|
int | n | int nAge |
integer or decimal numbers |
long | l (lowercase L) | long lLarge |
larger integers when int is too small |
float | f | float fTotal |
floating point numbers or fractional values (real numbers) |
double | d | double dAmount |
if you need more precision that float doesn't have (real numbers) |
char | c | char cJoke |
single characters |
void | returning nothing |
Example:
int nMyInt;
long lMyLong;
float fFraction;
double dAmount;
char cCharacter;
Constant Variables
If regular variables can have values that change, there's a notion of constant variables.
Geeks4Geeks: Constants in C
Entities that can store a value. The value cannot change during the execution of the program.
Syntax:
#define <constant identifier> <value>
Examples
#define PI 3.14159265358979323846264338327950
#define DLSU "De la Salle University"
#define TOKEN "213213666772aasffsa7887f"
the #define
is a preprocessor directive used to define macros. That means its an instruction that's executed before the program is compiled. A macro is used to give a name to a block of code or value.
Using a define directive puts it in the memory before the program is compiled so that means when you use it later in your code, additional memory isn't needed. Regardless of what you use you can't change the values during runtime.
There are different ways to make constant variables, either using a preprocessor directive or putting "const" for constant when you declare your variables.
Example:
const int nMY_INT;
const long lMY_LONG;
const float fFRACTION;
const double dAMOUNT;
const char cCHARACTER;
Assignment Statements
Think of the variables as like labeled boxes, and now you're going to put something in those boxes. → We do that in C through assignment statements.
Declaration
When we were making the variables earlier, that process is called declaration → When you declare that your variable exists. Since we didn't assign it any value yet, what's contained in the space is called garbage value. It's garbage because it has no meaning.
Assignment
Once you have declared the variable, you use an equals sign and put the value to its right. That's called assignment.
Syntax:
<data type> <identifier or variable name>; // declaration
<identifier or variable name> = <value>; // assignment follows after
Example:
int nMyInt;
char cCharacter;
nMyInt = 5;
cCharacter = 'd';
The value you can store in a variable depends on the datatype.
TutorialKart: C Data Types
Geeks4Geeks: C Float and Double
- Sometimes C would give you a warning when using float so it's best to put the suffix f at the end of the value so it explicitly knows we're giving it a float.
Data Type | Prefix | Valid Example | For what? | Valid Values |
---|---|---|---|---|
int | n | int nAge |
decimal numbers | 10, -50, 1000, 22767, -12718 |
long | l (lowercase L) | long lLarge | larger integers when int is too small | 100000, -500000, 2147483647, -2147483648 |
float | f | float fTotal |
floating point numbers or fractional values | 3.14f, -0.005f, 12345.6789f, -987.65f |
double | d | double dAmount |
if you need more precision that float doesn't have | 3.14, -0.0005, 12345.6789, -987654.321 |
char | c | char cJoke |
single characters (use single quotes!) | 'A', 'z', '9', '#', ' ' |
void | ||||
Example: |
int nMyInt;
long lMyLong;
float fFraction;
double dAmount;
char cCharacter;
nMyInt = 5;
lMyLong = -500000;
fFraction = 1.5;
dAmount = 3.14;
cCharacter = '?';
Initialization
There's also another way you can assign values to variables and that's called initialization. Think of it as declaration and assignment all in one line.
Syntax:
<data type> <identifier or variable name> = <value>;
Example:
int nSomething = 2;
Multiple Variables At A Time
Finally, you can save more time by initializing multiple variables at one time. This works for declaration as well if you're not ready to give them values yet. When you're initializing multiple variables, all of them have to be the same datatype if it's in one line.
Example:
int nMyInt, nYourInt, nTheirInt; //declaration
// assignment
nMyInt = 25;
nYourInt = 420;
nTheirInt = 69;
// or you can initialize
int nHerInt = 25, nHisInt = 420, nNotMyInt = 69;
You can also assign or initialize variables by using other variables as the reference.
Let's say we have three character variables. If I wanted to assign the value of cB to cA, I would do it like so:
char cA = 'a', cB = 'b', cC = 'c';
cA = cB;
What's happening here is that the value of cB is being copied over to cA. cA's original value of the character 'a' is rewritten. cB's value doesn't change.
If we wanted to swap their values, we could declare a temporary variable or use cC for that. First we store the variable of a in a temporary variable cC. cC would lose it's original value of the character c. Then we store the value of cB in cA. Then we can store whatever's in our temporary variable in cB.
char cA = 'a', cB = 'b', cC = 'c';
cC = cA; // store it temporarily so cC = 'a'
cA = cB; // cA = 'b'
cB = cC; // cB = 'a'
Now the value of cA and cB are switched.
Regarding loss of precision
We use floats if we want more "precision" with decimals. For curious minds, when you store a float
in an int
variable, it causes truncation. Truncation is when the decimal part is cut off or "truncated." It takes the "floor" of that value.
- This is a "narrowing conversion," which results in loss of precision. In this case, it converts a value to a type that cannot store even approximations of all the values of the original type.
Meanwhile, storing an int
in a float
variable adds decimal zeros but preserves the value. This is a "widening conversion." It's more safe than truncation because it converts a value to a type that can include at least approximations of all the values of the original type.
- 2.000000 is more precise than just 2
Example:
int a = 4.75;
float b = 2;
printf("%d\n", a); // output would be truncated to 4
printf("%f", b); // output would be converted to 2.000000
Operators
Operators let you do arithmetic on variables and values. These are called expressions or mathematical expressions. Variables can also have expressions in their assignment statement.
Symbols used to perform certain operations on values or variables.
Operator | Function |
---|---|
* |
multiplication |
/ |
division |
% |
modulo/remainder |
+ |
addition |
- |
subtraction |
Example: |
// Declare 3 integer variables
int nMyInt, nYourInt, nTheirInt;
// Assignment
nMyInt = 5;
nYourInt = nMyInt; // also be 5
// Still assignment
nTheirInt = nMyInt + nYourInt; // should be 10, you can replace + with any other operator
int nAnotherEquation = 1 - 5;
What happens when you use different datatypes?
Whatever is the "larger" datatype that can hold the result becomes the overall or resulting datatype.
Addition and Subtraction
Expression | Output | Example |
---|---|---|
int + int | int | 5 + 2 = 7 |
int + float | float | 5 + 2.0 = 7.0 |
float + int | float | 5.0 + 2 = 7.0 |
float + float | float | 5.0 + 2.0 = 7.0 |
Multiplication and Division |
Expression | Output | Examples |
---|---|---|
int * int | int | 5 * 2 = 10 |
int * float | float | 5 * 2.0 = 10.0 |
float * int | float | 5.0 * 2 = 10.0 |
float * float | float | 5.0 * 2.0 = 10.0 |
Modulo |
Expression | Output | Example |
---|---|---|
int % int | int | 4 % 2 = 0 |
int % float | n/a | error: invalid operands to binary % (have 'int' and 'float') |
float % int | n/a | error: invalid operands to binary % (have 'float' and 'int') |
float % float | n/a | error: invalid operands to binary % (have 'float' and 'float') |
You can't do modulo on floats directly, you'll have to use a library such as math.h. |
Operator Precedence and Associativity
In natural language such as English, we read things left to right. Computers process things differently because the compiler converts the program into a language that computers can understand. This brings us to precedence and associativity.
Precedence tells us which operators are evaluated first and associativity tells us which direction an expression is evaluated if they are of the same precedence.
Operator | Description | Precedence | Associativity |
---|---|---|---|
() |
Parenthesis | 1 - Highest | Left-to-Right |
unary +/- |
Positive or negative sign | 2 | Right-to-Left |
* / % |
Multiplication Division Remainder/Modulo |
3 | Left-to-Right |
+ - |
Addition Subtraction |
4 - Lowest | Left-to-Right |
Recreating Math Equations
Computers don't have a concept of what PEMDAS is, it will only do what you tell it. So to mitigate the problem, we use parentheses so we know for sure which part of the expression is evaluated first.
The default precedence just follows the table above. → This doesn't guarantee that it's evaluated the way we would think.
Using the example below, in the statement float eq1 = a + b * b / c - 4 * a * d;
, this is the order it would be evaluated in. Note that the computer would evaluate each part in pairs. feel free to open the image in another tab to see it better
cppreference: C Operator Precedence
Let's try recreating some math equations. The answers are on the right. Feel free to do this on your own first.
Answer:
#include <stdio.h>
int main()
{
float a = 2.0f, b = 3.0f, c = 4.0f, d = 5.0f;
float eq1 = a + b * b / c - 4 * a * d; // without parentheses
float eq1fixed = (a + b * b) / (c - 4 * a * d);
printf("eq1: %f\n", eq1);
printf("eq1fixed: %f\n", eq1fixed);
float eq2 = 1 / 1 + a * a; // without parentheses
float eq2fixed = 1 / (1 + a * a);
printf("eq2: %f\n", eq2);
printf("eq2fixed: %f\n", eq2fixed);
return 0;
}
Functions
When you're writing a program, sometimes the problem you're trying to solve requires a bunch of code that does similar things. To avoid copy pasting forever, we have functions. Functions are a group of statements called to perform a specific task. They're also called subprograms.
They let us modularize our program by breaking it down into several modules (that can be subdivided into different processes that the program will take.) It also makes reading and tracing the code easier.
Syntax:
<return type> <name_of_function>(<parameters>) {
// your other code here
return <value if return_type not void>; // return statement
}
The return type
is the datatype of the value that the function will return.
- We return something when we want to get something out of calling the function.
- As an analogy lets say, you want to craft a torch in Minecraft. The crafting table is your function. The parameters of your function would be a stick and a piece of coal. By using the crafting table, you get a torch out of it. So it's something like that.
void
, when you put it as the return type, means your function won't be returning anything, like if all you wanna do in that function is print text.
The name
of the function can be anything as long as its a valid identifier or it's not been used for a variable.
Parameters
are kind of like temporary variables. They hold the value that you "pass" into the function when you call it. They're only available within the function's scope.
- Scope means where a variable is accessible. So if it's within this function, other functions can't use it. Same thing when you declare a new variable inside the function.
The main function
The main
function is special because it's the starting point of all your C code. This is what the compiler looks for and what executes first when you run your program.
int main() {
return 0;
}
The reason why its return type
is int is because we return 0 at the end. Returning 0 ends or closes the program when its done.
- If your program has a problem, crashes, runs, or hangs and you have to force quit it, the return value would not be 0. That's one sign that you should take a look at your code and remove bugs.
Making Your Own Functions
Example:
#include <stdio.h>
int addTwoNumbers(int whatever1, int whatever2) {
int whatever3 = whatever1 + whatever2;
return whatever3;
}
int main()
{
int a = 2, b = 3;
int c = addTwoNumbers(a, b);
printf("The sum of %d and %d is %d\n", a, b, c);
}
Segue: Running Your Code on VsCode
VsCode will have a "play" button on the upper right. You can select that and click run.
Or, you could do ctrl+shift+b
which opens up a menu on the top.
Select GCC for C/C++ and it will begin compiling.
To run your program in the terminal just type ./main
or ./<your file name>
Libraries and Input/Output
Think of libraries as like pre-made functions that other people made and are built-in or available when you install C on your device. All you have to do is use a preprocessor directive, similar to earlier with define.
Syntax:
#include <name>
#include <stdio.h>
<stdio.h>
is the Standard Input/Output library. The .h
stands for Header file.
- Header files contain function declarations but doesn't run any of them. If you have a lot of functions and want to organize your code you can make a .h file and put all your functions there.
stdio.h: printf() and scanf()
The most commonly used functions you can get from this library are printf()
and scanf()
.
Printf()
lets you print strings or variables, while scanf()
lets you get input from the console. The f part in the name means formatted.
If you're going to print a string and nothing else, your printf statement would look like this. Notice how we used double quotes. That's because it's a string or sentence.
printf("Hello world!");
On the other hand, if you're going to use printf()
to print variables, you would need a format specifier.
A format specifier tells the printf statement what kind of datatype the variable you're trying to print is.
Data Type | Prefix | Format Specifier | Valid Example | For what? | Valid Values |
---|---|---|---|---|---|
int | n | %d or %i | int nAge |
decimal numbers | 10, -50, 1000, 22767, -12718 |
long | l (lowercase L) | %f | long lLarge | larger integers when int is too small | 100000, -500000, 2147483647, -2147483648 |
float | f | %lf | float fTotal |
floating point numbers or fractional values | 3.14f, -0.005f, 12345.6789f, -987.65f |
double | d | %c | double dAmount |
if you need more precision that float doesn't have | 3.14, -0.0005, 12345.6789, -987654.321 |
char | c | %ld | char cJoke |
single characters | 'A', 'z', '9', '#', ' ' |
void | n/a | n/a | n/a | nothing | n/a |
The format specifier is added to the part with double quotes. Then you add a comma then the name of the variable. |
Example:
int nMyInt = 5;
printf("%d", nMyInt);
If you want to print more variables in one printf()
statement, you just add the number of format specifiers in the double quotes portion.
int nMyInt = 5, nYourInt = 6;
printf("%d %d", nMyInt, nYourInt);
If you want to print multiple lines and not have them print one after another, you can put an escape code. For this lesson, we'll just use the newline escape character. The backslash lets the compiler know that it's an escape code.
int nMyInt = 5, nYourInt = 6;
printf("%d\n", nMyInt);
printf("%d", nYourInt);
stdio.h: scanf() and the Address-of Operator
scanf("%<format specifier>", <variable>);
scanf("%d", &var1);
The ampersand or "and" sign in-front of var1 is called an address-of operator. Recall that when variables are made, they're reserved a specific space in the memory. Where they're exactly located is called their address.
- So when we do
scanf()
, for example, you can imagine you're a shopee delivery guy. Think of it as like you're getting the item, and now you're shipping it to the address of your variable.
Remember the ampersand or "and" means memory address. You'll be needing this later on in CCPROG1.
If you want to scan for multiple inputs, the process is similar to printf()
:
int var1, var2;
scanf("%d%d", &var1, &var2);
If some variables are different datatypes, you just have to use another format specifier.
int var1;
float var2;
scanf("%d%f", &var1, &var2)
Handling multiple scanf()
's at a time: Geeks4Geeks: fflushstdin
You can try to run this code:
#include <stdio.h>
int main()
{
int var1;
float var2;
scanf("%d%f", &var1, &var2);
printf("You entered: %d and %f\n", var1, var2);
}
There's a pause in the terminal, because it's waiting for the user to put something into the terminal and press enter.
So it's best to add a printf()
statement before you call scanf()
, so the user will be prompted to put something or be guided on what to put.
#include <stdio.h>
int main()
{
int var1;
float var2;
printf("Enter an integer and a float: \n");
scanf("%d%f", &var1, &var2);
printf("You entered: %d and %f\n", var1, var2);
}
Conditional Statements
Coming soon!
If Statements
What are conditions or conditionals?
If-else Statements
Nested If-else Statements
Switch Statements
Iterative Statements
Coming soon!
For Loop
While Loop
Do-while Loop
Creating Art with Loops
Practice Problems and Solutions
Coming soon!