C - lecture 2

Debugging

Whenever you want to find logical flows in the code, use always printf as a debugging tool to check how the code behaves.

Compiling

make is a command that compiles the source code into machine code, but make is not the compiler.
The actual compiler is called clang, so instead of using make hello , we use:

#include <stdio.h>

int main(void)
{
	printf('hello')
}

and run:

cs50/c/lec2/ $ clang name.c
cs50/c/lec2/ $ ls
a.out*  name*  name.c

This outputs a assembly.output file

with #include <cs50.h> library clang will return error:

cs50/c/lec2/ $ clang name.c
/usr/bin/ld: /tmp/name-3c3e1b.o: in function `main':
name.c:(.text+0x16): undefined reference to `get_string'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

This is mainly because we think clang knows where to find the CS50 library , but that's not a standard library frequently used. It's being used for the time being , because we are fairly new to C.

When source code get processed into machine code, it goes though:

C data types:

When we store value in memory all we are doing is memory in the hardware like this:
Attachments/Pasted image 20260515164311.png
so for the code :

#include <stdio.h>
#include <cs50.h>
int main(void)
{
	int score1 = 72;
	int score2 = 73;
	int score3 = 33;
}

we would use 4 byte of each integer , so 12 bytes in total:
Attachments/Pasted image 20260515170103.png


Arrays

We can use arrays, which are a chucks of contiguous memory. (Back to back)
Attachments/Pasted image 20260515170613.png

In C we have to declare the block of memory we want to declare our variables in:

int scores[3]; // Declare array

scores[0] = 1; // Set element at each indices
scores[1] = 2;
scores[2] = 3;
Ask user's input
#include <stdio.h>
#include <cs50.h>
int main(void)
{
	int scores[2];
	
	scores[0] = get_int("Number 1: \n");
	scores[1] = get_int("Number 2: \n");
	
	printf("%f\n", scores[0] + scores[1]);
}
Functions

When we create a function in C, that takes an array as input:

#include <stdio.h>
#include <cs50.h>

float average(int lenght, int numbers[])
{
	for (int i; i < lenght; i++)
	{
		scores[i]
	}
}

Char , String

#include <stdio.h>
#include <cs50.h>
int main(void)
{
	char c1 = 'H';
	char c2 = 'i';
	char c3 = '!';
	
	printf("%i % i %i\n", c1 ,c2,c3);
}

The format code %i for integers casts automatically the c1. c2. c3 values and allocates in memory such as (ASCII):
Attachments/Pasted image 20260528205716.png
equal to binary:
Attachments/Pasted image 20260528205748.png

String
#include <stdio.h>
#include <cs50.h>
int main(void)
{
	string s = "Hi!";
	printf("%s\n", s);
}

Hi! is 3 bytes of memory
Attachments/Pasted image 20260528211226.png
or an array of char
Attachments/Pasted image 20260528211447.png

If we want to check the value for each element of the string, we can change the format
from %s string to %i integer.

#include <stdio.h>
#include <cs50.h>
int main(void)
{
	string s = "Hi!";
	printf("%i %i %i\n", s[0], s[1], s[2]);
}

A string of length 3 takes exactly 4 bytes., with the last being a NUL byte which tells printf the string has finished
Attachments/Pasted image 20260530131759.png
Any extra %i no corresponding to a value will take a 0 byte space in memory.

NUL character

Is just a byte of 0 bit, it represents the end of a string.
ASCII TABLE:
Attachments/Pasted image 20260530131601.png

an extra variable like string t = "BYE!" would take 5 bytes in total.
Attachments/Pasted image 20260530132014.png

We can also create an array containing words and access both elements and sub elements:

#include <stdio.h>
#include <cs50.h>
int main(void)
{
	string s = "HI!";
	string t = "BYE!";
	string words [2];
	
	printf("%i %i %i\n", s[0], s[1], s[2]);
	printf("%s\n" , t);
	
	words[0] = "Hi!";
	words[1] = "Bye!";
	printf("%s %s\n", words[0], words[1]);
	
	// Access sub-index of an index
	printf("%c\n", words[0][1]);
}

And it would be like:
Attachments/Pasted image 20260530133223.png

Length of an array:

!VERY MECHANICAL

#include <stdio.h>
#include <cs50.h>
int main(void)
{
	string name = get_string("What is your name? \n");
	int n = 0;
	while (name[n] != '\0')
	{
	n++;
	}
	printf("%i\n", n);
	
}
Alternative
Uppercase

The #include <ctype.h> header allows to convert char to upper or lowercase automatically.
This is not like a Python function that takes the whole string and converts it, but I have to run a for loop that converts character per character.

#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>

int main(void){

	string s = get_string("What is the string: ");
	int n = strlen(s);
	for (int i = 0; i < n; i++)
	
	{
		printf("%c", toupper(s[i]));
	}
	printf("\n");
}
Powered by Forestry.md