#Include : (Printf ("Hello, World/n") )
#Include : (Printf ("Hello, World/n") )
C
hello, world
Compilers
String
Scratch blocks in C
Types, formats, operators
More examples
Screens
Memory, imprecision, and overflow
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
}
Though the words are new, the ideas are exactly as same as the
“when green flag clicked” and “say (hello, world)” blocks in Scratch:
Though cryptic, don’t forget that 2/3 of CS50 students have never
taken CS before, so don’t be daunted! And though at first, to borrow
a phrase from MIT, trying to absorb all these new concepts may feel
like drinking from a fire hose, be assured that by the end of the
semester we’ll be empowered by and experienced at learning and
applying these concepts.
We can compare a lot of the constructs in C, to blocks we’ve already
seen and used in Scratch. The syntax is far less important than the
principles, which we’ve already been introduced to.
The “when green flag clicked” block in Scratch starts the main
program; clicking the green flag causes the right set of blocks
underneath to start. In C, the first line for the same is int
main(void), which we’ll learn more about over the coming weeks,
followed by an open curly brace {, and a closed curly brace },
wrapping everything that should be in our program.
The “say (hello, world)” block is a function, and maps to
printf("hello, world");. In C, the function to print something to
the screen is printf, where f stands for “format”, meaning we can
format the printed string in different ways. Then, we use
parentheses to pass in what we want to print. We have to use
double quotes to surround our text so it’s understood as text, and
finally, we add a semicolon ; to end this line of code.
To make our program work, we also need another line at the top, a
header line #include <stdio.h> that defines the printf function
that we want to use. Somewhere there is a file on our computer,
stdio.h, that includes the code that allows us to access the printf
function, and the #include line tells the computer to include that file
with our program.
To write our first program in Scratch, we opened Scratch’s website.
Similarly, we’ll use the CS50 Sandbox to start writing and running
code the same way. The CS50 Sandbox is a virtual, cloud-based
environment with the libraries and tools already installed for writing
programs in various languages. At the top, there is a simple code
editor, where we can type text. Below, we have a terminal window,
into which we can type commands:
We’ll type our code from earlier into the top, after using the + sign to
create a new file called hello.c:
We end our program’s file with .c by convention, to indicate that it’s
intended as a C program. Notice that our code is colorized, so that
certain things are more visible.
Once we save the code that we wrote, which is called source code,
we need to convert it to machine code, binary instructions that the
computer understands directly.
We use a program called a compiler to compile our source code
into machine code.
To do this, we use the Terminal panel, which has a command
prompt. The $ at the left is a prompt, after which we can type
commands.
We type clang hello.c (where clang stands for “C languages”, a
compiler written by a group of people). But before we press enter,
we click the folder icon on the top left of CS50 Sandbox. We see our
file, hello.c. So we press enter in the terminal window, and see that
we have another file now, called a.out (short for “assembly
output”). Inside that file is the code for our program, in binary. Now,
we can type ./a.out in the terminal prompt to run the program
a.out in our current folder. We just wrote, compiled, and ran our first
program!
But after we run our program, we see hello, world$, with the new
prompt on the same line as our output. It turns out that we need to
specify precisely that we need a new line after our program, so we
can update our code to include a special newline character, \n:
#include <stdio.h>
int main(void)
{
printf("hello, world\n");
}
$ ls
a.out* hello* hello.c
The asterisk, *, indicates that those files are executable, or that they
can be run by our computer.
We can use the rm (remove) command to delete a file:
$ rm a.out
rm: remove regular file 'a.out'?
We can type y or yes to confirm, and use ls again to see that it’s
indeed gone forever.
Now, let’s try to get input from the user, as we did in Scratch when
we wanted to say “hello, David”:
The first line of the error tells us to look at hello.c, line 5, column
26, where the compiler expected a closing parentheses, instead of a
backslash.
To simplify things (at least for the beginning), we’ll include a library,
or set of code, from CS50. The library provides us with the string
variable type, the get_string function, and more. We just have to
write a line at the top to include the file cs50.h:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
string name = get_string("What's your name?\n");
printf("hello, name\n");
}
#include <stdio.h>
int main(void)
{
string name = get_string("What's your name?\n");
printf("hello, %s\n", name);
}
#include <cs50.h>
#include <stdio.h>
int main(void)
{
string name = get_string("What's your name?\n");
printf("hello, %s\n", name);
}
Now, when we try to compile our program, we have just one error:
It turns out that we also have to tell our compiler to add our special
CS50 library file, with clang -o string string.c -lcs50, with -l for
“link”.
We can even abstract this away and just type make string. We see
that, by default in the CS50 Sandbox, make uses clang to compile
our code from string.c into string, with all the necessary
arguments, or flags, passed in.
The “set [counter] to (0)” block is creating a variable, and in C we
would write int counter = 0;, where int specifies that the type of
our variable is an integer:
if (x < y)
{
printf("x is less than y\n");
}
if (x < y)
{
printf("x is less than y\n");
}
else
{
printf("x is not less than y\n");
}
Notice that lines of code that themselves are not some action
(if..., and the braces) don’t end in a semicolon.
And even else if:<
if (x < y)
{
printf("x is less than y\n");
}
else if (x > y)
{
printf("x is greater than y\n");
}
else if (x == y)
{
printf("x is equal to y\n");
}
while (true)
{
printf("hello, world\n");
}
int i = 0;
while (i < 50)
{
printf("hello, world\n");
i++;
}
For each of these examples, you can click on the sandbox links to
run and edit your own copies of them.
In int.c, we get and print an integer:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int age = get_int("What's your age?\n");
int days = age * 365;
printf("You are at least %i days old.\n", days);
}
#include <cs50.h>
#include <stdio.h>
int main(void)
{
float price = get_float("What's the price?\n");
printf("Your total is %f.\n", price * 1.0625);
}
Now, if we compile and run our program, we’ll see a price printed
out with tax.
We can specify the number of digits printed after the decimal with a
placeholder like %.2f for two digits after the decimal point.
With parity.c, we can check if a number is even or odd:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int n = get_int("n: ");
if (n % 2 == 0)
{
printf("even\n");
}
else
{
printf("odd\n");
}
}
#include <cs50.h>
#include <stdio.h>
int main(void)
{
// Prompt user for x
int x = get_int("x: ");
// Compare x and y
if (x < y)
{
printf("x is less than y\n");
}
else if (x > y)
{
printf("x is greater than y\n");
}
else
{
printf("x is equal to y\n");
}
}
Lines that start with // are comments, or note for humans that the
compiler will ignore.
For David to compile and run this program in his sandbox, he first
needed to run cd src1 in the terminal. This changes the directory, or
folder, to the one in which he saved all of the lecture’s source files.
Then, he could run make conditions and ./conditions. With pwd, he
can see that he’s in a src1 folder (inside other folders). And cd by
itself, with no arguments, will take us back to our default folder in
the sandbox.
In agree.c, we can ask the user to confirm or deny something:
// Logical operators
#include <cs50.h>
#include <stdio.h>
int main(void)
{
// Prompt user to agree
char c = get_char("Do you agree?\n");
#include <stdio.h>
int main(void)
{
printf("cough\n");
printf("cough\n");
printf("cough\n");
}
#include <stdio.h>
int main(void)
{
for (int i = 0; i < 3; i++)
{
printf("cough\n");
}
}
#include <stdio.h>
void cough(void);
int main(void)
{
for (int i = 0; i < 3; i++)
{
cough();
}
}
void cough(void)
{
printf("cough\n");
}
#include <stdio.h>
int main(void)
{
cough(3);
}
void cough(int n)
{
for (int i = 0; i < n; i++)
{
printf("cough\n");
}
}
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int i = get_positive_int("Positive integer: ");
printf("%i\n", i);
}
#include <stdio.h>
int main(void)
{
printf("????\n");
}
We can ask the user for a number of question marks, and then print
them, with mario2.c:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int n;
do
{
n = get_int("Width: ");
}
while (n < 1);
for (int i = 0; i < n; i++)
{
printf("?");
}
printf("\n");
}
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int n;
do
{
n = get_int("Size: ");
}
while (n < 1);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("#");
}
printf("\n");
}
}
Notice we have two nested loops, where the outer loop uses i to do
everything inside n times, and the inner loop uses j, a different
variable, to do something n times for each of those times. In other
words, the outer loop prints n “rows”, or lines, and the inner loop
prints n “columns”, or # characters, in each line.
Other examples not covered in lecture are available under “Source
Code” for Week 1.
#include <cs50.h>
#include <stdio.h>
int main(void)
{
// Prompt user for x
float x = get_float("x: ");
// Perform division
printf("x / y = %.50f\n", x / y);
}
x: 1
y: 10
x / y = 0.10000000149011611938476562500000000000000000000000
#include <stdio.h>
#include <unistd.h>
int main(void)
{
for (int i = 1; ; i *= 2)
{
printf("%i\n", i);
sleep(1);
}
}
1073741824
overflow.c:6:25: runtime error: signed integer overflow: 1073741824 * 2 cannot b
-2147483648
0
0
...