Week 2
: Deeper look about C
Lecture Contents
1. Compiling
-Encryption : the act of hiding plain text from prying eyes (암호화)
-Decrypting : the act of taking an encrypted piece of text and returning it to a human-readable form (해독)
We learned about a compiler last week:
source code | -> compiler -> | machine code |
- VS Code utilizes a compiler called clang or c language
Ex) If you were to type make hello, it runs a command that executes clang
#include <cs50.h>
#include <stdio.h>
int main(void)
{
string name = get_string("What's your name?: ");
printf("hello, $s\n, name);
}
In the terminal window, type :
clang -o hello hello.c -lcs50
=> Enables the compiler to access cs50 library.
Major steps of compiling :
ⓐ preprocessing
: where the header files (#) in your code are effectively copied and pasted into your file.
The code from cs50.h is copied into your program. This step can be visualized as follows:
string get_string(string prompt);
int printf(string format, ...);
int main(void)
{
string name = get_string("What's your name?" );
printf("hello, %s\n, name);
}
ⓑ compiling
: where your program is converted into assembly code. This step can be visualized as follows:

ⓒ assembling
: where the compiler converts your assembly code into machine code. This step can be visualized as follows:

ⓓ linking
: where code from your included libraries are concerted also into machine code and combined with your code.
This step can be visualized as follows:

2. Debugging
: to address the bugs
Let's purposely insert a bug within your code:
#include <stdio.h>
int main(void)
{
for(int i =0; i <= 3; i++)
{
printf("#\n");
}
}
=> 4 bricks appear instead of the intended 3.
#
#
#
#
ⓐ printf : a very useful way of debugging your code.
#include <stdio.h>
int main(void)
{
for(int i = 0; i <=3; i++)
{
printf("i is %i\n, i);
printf("#\n");
}
}
=> i is 0, i is 1, i is 2, i is 3
You might realize that your code needs to be corrected as follows: (<= is replaced with <)
for(int i = 0; i < 3; i++)
This code can be further improved as follows:
#include <cs50.h>
#include <stdio.h>
void print_column(int height);
int main(void)
{
int h = get_int("Height: ");
print_column(h);
}
void print_column(int height)
{
for (int i = 0; i <= height; i++)
{
printf("#\n");
}
}
=> This sill results in a bug. (n+1 bricks instead of the intended n)
ⓑ debugger : a software tool created by programmers to help track down bugs in code.
▷ First, set a breakpoint by clicking to the left of a line of your code, just to the left of the line number.
When clicked, you will see a red dot appearing.
▷ Second, run debug50 ./buggy(the name of your file). It will seem like this:

=> Click the step over button and notice how the value of h increases.
It will show how your code is running step by step.
ⓒ Rubber duck debugging
3. Arrays
Each data type requires a certain amount of system resources:
◎ bool : 1 byte
◎ int : 4 bytes
◎ long : 8 bytes
◎ float : 4 bytes
◎ double : 8 bytes
◎ char : 1 byte
◎ string : ? bytes
#include <stdio.h>
int main(void)
{
int score1 = 72;
int score2 = 73;
int score3 = 33;
printf("Average: %f\n", (score1+score2+score3) / 3.0);
}
=> Notice of using %f and 3.0 so that the cauculation is rendered as a floating point value in the end.
These variables are stored in memory like:

* 1 block = 1 digit
Using Arrays
▶ int scores[3] : a way of telling the compiler to provide you 3 back-to-back places in memory of size int to store 3 scores.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
//Get scores
int scores[3];
scores[0] = get_int("Score: ");
scores[1] = get_int("Score: ");
scores[2] = get_int("Score: ");
//Print average
printf("Average: %f\n", (scores[0] + scores[1] + scores[2]) / 3.0);
}
-> We can still improve this code as follows:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int scores[3];
for (int i = 0; i < 3; i++)
{
scores[i] = get_int("Score: ");
}
printf("Average: %f\n", (scores[0] + scores[1] + scores[2]) / 3.0);
}
-> We can simplify or abstract away the calculation of the average as follows:
#include <cs50.h>
#include <stdio.h>
const int N =3;
float average(int length, int array[]);
int main(void)
{
//Get scores
int scores[N];
for (int i = 0; i < N; i++)
{
scores[i] = get_int("Score: ");
}
printf("Average: %f\n", average(N, scores));
float average(int length, int array[])
{
//Calculate average
int sum = 0;
for (int i = 0; i < length; i++)
{
sum += array[i];
}
return sum / (float) length;
- A new function called 'average' is declared.
- Const (constant value) of N is declared.
- 'Average' function takes int array[] : the compiler passes an array to this function.
4. Strings
A string is an array or characters (char).
-Begins with the first character and ends with a special character called a NUL character:

In decimal :

▶ Hi!
#include <stdio.h>
int main(void)
{
char c1 = 'H';
char c2 = 'I';
char c3 = '!';
printf("%c%c%c\n", c1, c2, c3);
}
-> When we replace %c with %i :
printf("%i%i%i\n", c1, c2, c3);
=> 72 73 33
Using arrays
#include <cs50.h>
#include <stdio.h>
int main(void)
{
string s = "HI!";
printf("%i %i %i %i\n", s[0], s[1], s[2], s[3]);
}
=> 72 73 33 0(NUL)
▶ Hi! BYE!
#include <cs50.h>
#include <stdio.h>
int main (void)
{
string s = "HI!";
string t = "BYE!";
printf("%s\n", s);
printf("%s\n", t);
}

=> We can improve this code as follows using array:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
string words[2];
words[0] = "HI!";
words[1] = "BYE!";
printf("%s\n", words[0]);
printf("%s\n", words[1]);
}
5. String Length
: How do we discover the length of an array?
#include <cs50.h>
#include <stdio.h>
int main(void)
{
//Prompt for user's name
string name = get_string("Name: ");
//Count number of characters up until '\0' (aka NUL)
int n = 0;
while (name[n] != '\0')
{
n++;
}
printf("%i\n", n);
}
=> This can be improved as follows:
#include <cs50.h>
#include <stdio.h>
int string_length(string s);
int main(void)
{
//Prompt for user's name
string name = get_string("Name: ");
int length = string_length(name);
printf("%i\n", length);
}
int string_length(string s)
{
//Count number of characters up until '\0'
int n = 0;
while (s[n] != '\0')
{
n++;
}
return n;
}
Other programmers have created code in the string.h library to find the length of a string.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
string name = get_string("Name: ");
int length = strlen(name);
printf("%i\n", length);
}
→ Notice that it uses a function strlen.
: How do we convert all lowercase characters to uppercase ones?
#include <stdio.h>
#include <cs50.h>
#include <string.h>
int main(void)
{
string s = get_string("Before: ");
printf("After: ");
for(int i = 0, n = strlen(s); i < n; i++)
{
if(s[i] >= 'a' && s[i] <= 'z')
{
printf("%c", s[i] - 32);
}
else
{
printf("%c" , s[i]);
}
}
printf("\n");
}
→ If the character is lowercase, it subtracts the value 32 from it to convert it to uppercase, according to this:

Now, we can use ctype.h library :
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
string s = get_string("Before: ");
printf("After: ");
for (int i = 0, n = strlen(s); i < n; i++)
{
if(islower(s[i]))
{
printf("%c", toupper(s[i]));
}
else
{
printf("%c", s[i]);
}
}
printf("\n");
}
→ toupper function is used to convert each character to uppercase.
Because the toupper function automatically knows to uppercase only lowercase characters, your code can be simplified as follows:
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
string s = get_string("Before: ");
printf("After: ");
for (int i = 0, n = strlen(s); i < n; i++)
{
printf("%c", toupper(s[i]));
}
printf("\n");
}
6. Command-Line Arguments
-Command-line arguments are those arguments that are passed to your program at the command line.
Ex) All those statements you typed after clang = command-line arguments
greet.c
#include <stdio.h>
#include <cs50.h>
int main(void)
{
string answer = get_string("What's your name?: ");
printf("hello, %s\n", answer);
}
→ It says 'hello' to the user. However, it would be nice to be able to take arguments before the program even runs.
#include <stdio.h>
#include <cs50.h>
int main(int argc, string argv[])
{
if (argc == 2)
{
printf("hello, %s\n", argv[1]);
}
else
{
printf("hello, world\n");
}
}

☆ Notice that this program knows
1) argc : the number of command line arguments
2) argv[] : the array of the characters passed as arguments at the command line
☆ argc == 2 / argv[1]
: './greet Jeeyoon \0'
0 1 2
argv[0] argv[1] argv[2]
7. Exit Status
When a program ends, a special exit code is provided to the computer.
When exits without error: a status code of 0
When an error occurs: a status code of 1
status.c
#include <stdio.h>
#include <cs50.h>
int main(int argc, string argv[])
{
if (argc != 2)
{
printf("Missing command-line argument\n");
return 1;
}
printf("hello, %s\n", argv[1]);
return 0;
}
8. Cryptography (암호화)
-Cryptography : the art of ciphering and deciphering a message

*key : a special argument passed to the cipher along with the plaintext
점점 밀리고 있는 스케쥴... 정신 차리고 다시 스케쥴 맞춰 따라가기!!! 아자아자뵹
이렇게 2주차 강의도 끄읕! 😁
'CS50' 카테고리의 다른 글
[CS50] Pset 2 : Scrabble, Readability, Caesar (1) | 2024.09.29 |
---|---|
[CS50] Week 2 Section (0) | 2024.09.24 |
[CS50] Week 1 Section + Pset 1 : Mario-more (0) | 2024.09.15 |
[CS50] Pset 1 : Credit (1) | 2024.09.13 |
[CS50] Week 1 Review (1) | 2024.09.10 |