Write a Program That Reads a Floating-point Number and Prints Zero if the Number Is Zero
Lecture 1
- C
- hello, world
- Compilers
- String
- Scratch blocks in C
- Types, formats, operators
- More examples
- Screens
- Retention, imprecision, and overflow
C
- Today we'll learn a new language, C: a programming language that has all the features of Scratch and more, merely perhaps a piffling less friendly since it'south purely in text:
#include <stdio.h> int main ( void ) { printf ( "hello, world \n " ); }
- Though the words are new, the ideas are exactly as same as the "when dark-green flag clicked" and "say (hello, world)" blocks in Scratch:
- Though the words are new, the ideas are exactly as same as the "when dark-green flag clicked" and "say (hello, world)" blocks in Scratch:
- Though cryptic, don't forget that ii/iii of CS50 students have never taken CS earlier, 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 burn down hose, be bodacious that by the finish of the semester we'll exist 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 of import than the principles, which nosotros've already been introduced to.
hello, world
- 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 aforementioned is
int main(void)
, which we'll learn more about over the coming weeks, followed by an open up curly brace{
, and a airtight curly brace}
, wrapping everything that should be in our program. - The "say (howdy, world)" block is a function, and maps to
printf("hello, world");
. In C, the role to print something to the screen isprintf
, wheref
stands for "format", meaning nosotros can format the printed cord in dissimilar ways. Then, we use parentheses to pass in what we want to print. We have to use double quotes to surroundings our text and then information technology'due south understood as text, and finally, we add a semicolon;
to end this line of code. - To make our program work, we also need some other line at the meridian, a header line
#include <stdio.h>
that defines theprintf
role that we want to employ. Somewhere there is a file on our computer,stdio.h
, that includes the code that allows us to admission theprintf
function, and the#include
line tells the computer to include that file with our program. - To write our first program in Scratch, nosotros opened Scratch's website. Similarly, nosotros'll employ the CS50 Sandbox to start writing and running code the same manner. The CS50 Sandbox is a virtual, cloud-based surround with the libraries and tools already installed for writing programs in various languages. At the height, at that place is a simple code editor, where we tin can type text. Below, we take a last window, into which we can type commands:
- Nosotros'll blazon our lawmaking from before into the peak, afterwards using the
+
sign to create a new file chosenhello.c
:
- Nosotros stop our plan'south file with
.c
by convention, to indicate that it's intended as a C program. Discover that our code is colorized, so that certain things are more visible.
Compilers
- Once we save the code that we wrote, which is chosen source code, we need to convert it to machine code, binary instructions that the calculator understands straight.
- We use a program called a compiler to compile our source code into machine lawmaking.
- To practice this, we utilize the Final panel, which has a control prompt. The
$
at the left is a prompt, subsequently which nosotros can type commands.- We type
clang hello.c
(whereclang
stands for "C languages", a compiler written past a group of people). Simply 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 encounter that we take some other file now, calleda.out
(short for "associates output"). Inside that file is the code for our program, in binary. Now, nosotros tin type./a.out
in the concluding prompt to run the programmea.out
in our electric current folder. We just wrote, compiled, and ran our first program!
- We type
String
- Just after we run our program, we see
hello, world$
, with the new prompt on the same line as our output. Information technology turns out that we need to specify precisely that nosotros need a new line after our program, and then we can update our code to include a special newline character,\n
:#include <stdio.h> int main ( void ) { printf ( "hello, world \northward " ); }
- Now nosotros need to remember to recompile our program with
clang hello.c
before we tin run this new version.
- Now nosotros need to remember to recompile our program with
- Line two of our plan is intentionally blank since we desire to start a new section of code, much like starting new paragraphs in essays. It's not strictly necessary for our programme to run correctly, simply it helps humans read longer programs more easily.
- We tin modify the name of our program from
a.out
to something else, too. We tin can laissez passer command-line arguments, or additional options, to programs in the terminal, depending on what the programme is written to understand. For example, we tin typeclang -o hello hello.c
, and-o hi
is telling the programclang
to save the compiled output equally justhowdy
. Then, nosotros tin can just run./howdy
. - In our command prompt, we tin can run other commands, like
ls
(list), which shows the files in our electric current folder:$ ls a.out* hello* hullo.c
- The asterisk,
*
, indicates that those files are executable, or that they tin be run by our estimator.
- The asterisk,
- We can use the
rm
(remove) control to delete a file:$ rm a.out rm: remove regular file 'a.out'?
- We tin type
y
oraye
to confirm, and utilisels
again to see that information technology's indeed gone forever.
- We tin type
- Now, let's try to get input from the user, every bit we did in Scratch when we wanted to say "hello, David":
string answer = get_string ( "What's your name? \due north " ); printf ( "hello, %southward \n " , answer );
- Offset, we need a string, or piece of text (specifically, zero or more characters in a sequence in double quotes, like
""
,"ba"
, or "bananas"), that we can ask the user for, with the functionget_string
. We pass the prompt, or what we want to ask the user, to the function with"What is your name?\northward"
inside the parentheses. On the left, we desire to create a variable,answer
, the value of which volition be what the user enters. (The equals sign=
is setting the value from right to left.) Finally, the type of variable that we desire iscord
, then we specify that to the left ofanswer
. - Side by side, inside the
printf
office, we desire the value ofrespond
in what nosotros impress back out. We utilize a placeholder for our string variable,%southward
, inside the phrase we want to print, like"hello, %due south\n"
, and then we requiteprintf
some other statement, or option, to tell it that we want the variableanswer
to be substituted.
- Offset, we need a string, or piece of text (specifically, zero or more characters in a sequence in double quotes, like
- If we made a mistake, similar writing
printf("hello, earth"\northward);
with the\n
outside of the double quotes for our cord, nosotros'll encounter an errors from our compiler:$ clang -o hi hello.c hello.c:5:26: error: expected ')' printf ( "howdy, globe" \north ) ; ^ hullo.c:5:11: annotation: to match this '(' printf ( "hello, world" \northward ) ; ^ ane error generated.
- The first line of the fault tells us to look at
hello.c
, line 5, column 26, where the compiler expected a endmost parentheses, instead of a backslash.
- The first line of the fault tells us to look at
- To simplify things (at least for the beginning), nosotros'll include a library, or set of lawmaking, from CS50. The library provides united states with the
string
variable type, theget_string
role, and more. We just have to write a line at the peak toinclude
the filecs50.h
:#include <cs50.h> #include <stdio.h> int main ( void ) { string name = get_string ( "What'south your name? \n " ); printf ( "hello, proper noun \north " ); }
- So let's brand a new file,
string.c
, with this code:#include <stdio.h> int main ( void ) { string name = get_string ( "What'south your name? \due north " ); printf ( "hello, %s \northward " , name ); }
- Now, if nosotros try to compile that code, we get a lot of lines of errors. Sometimes, one mistake means that the compiler so starts interpreting correct code incorrectly, generating more errors than there actually are. Then we offset with our first error:
$ clang -o string cord.c string.c:5:5: fault: use of undeclared identifier 'string' ; did you lot mean 'stdin'? string proper noun = get_string( "What's your name? \n " ) ; ^~~~~~ stdin /usr/include/stdio.h:135:25: notation: 'stdin' declared hither extern struct _IO_FILE *stdin; /* Standard input stream. */
- Nosotros didn't mean
stdin
("standard in") instead ofcord
, so that error message wasn't helpful. In fact, we demand to import another file that defines the typestring
(actually a training bike from CS50, every bit we'll observe out in the coming weeks).
- Nosotros didn't mean
- And then nosotros can include another file,
cs50.h
, which likewise includes the functionget_string
, among others.#include <cs50.h> #include <stdio.h> int master ( void ) { string name = get_string ( "What's your name? \n " ); printf ( "hello, %s \due north " , name ); }
- Now, when nosotros try to compile our program, we have just one error:
$ clang -o string cord.c /tmp/cord-aca94d.o: In role `principal': cord.c:(.text+0x19): undefined reference to `get_string' clang-7: error: linker command failed with exit code 1 (employ -v to encounter invocation)
- It turns out that nosotros as well have to tell our compiler to add our special CS50 library file, with
clang -o cord string.c -lcs50
, with-l
for "link".
- It turns out that nosotros as well have to tell our compiler to add our special CS50 library file, with
- We can even abstract this away and just type
make string
. We run into that, past default in the CS50 Sandbox,make
usesclang
to compile our code fromcord.c
intostring
, with all the necessary arguments, or flags, passed in.
Scratch blocks in C
- The "ready [counter] to (0)" block is creating a variable, and in C nosotros would write
int counter = 0;
, whereint
specifies that the type of our variable is an integer:
- "change [counter] by (i)" is
counter = counter + 1;
in C. (In C, the=
isn't similar an equals sign in a equation, where we are sayingcounter
is the aforementioned ascounter + i
. Instead,=
is an assignment operator that means, "copy the value on the correct, into the value on the left".) And detect we don't need to sayint
anymore, since we presume that we already specified previously thatcounter
is anint
, with some existing value. We can likewise saycounter += 1;
orcounter++;
both of which are "syntactic carbohydrate", or shortcuts that have the same effect with fewer characters to type.
- A condition would map to:
if ( x < y ) { printf ( "x is less than y \n " ); }
- Notice that in C, we utilise
{
and}
(every bit well as indentation) to bespeak how lines of code should exist nested.
- Notice that in C, we utilise
- Nosotros can too have if-else conditions:
if ( ten < y ) { printf ( "x is less than y \north " ); } else { printf ( "x is not less than y \n " ); }
- Notice that lines of code that themselves are non some action (
if...
, and the braces) don't cease in a semicolon.
- Notice that lines of code that themselves are non some action (
- And even
else if
:<
if ( ten < y ) { printf ( "10 is less than y \northward " ); } else if ( ten > y ) { printf ( "x is greater than y \n " ); } else if ( ten == y ) { printf ( "x is equal to y \n " ); }
- Observe that, to compare two values in C, we utilise
==
, ii equals signs. - And, logically, we don't need the
if (x == y)
in the terminal status, since that'due south the just case remaining, and we can just sayelse
.
- Observe that, to compare two values in C, we utilise
- Loops can exist written like the following:
while ( true ) { printf ( "hi, world \n " ); }
- The
while
keyword likewise requires a condition, and then nosotros usetruthful
equally the Boolean expression to ensure that our loop will run forever. Our program will check whether the expression evaluates totruthful
(which it always will in this example), and then run the lines within the curly braces. So information technology volition echo that until the expression isn't true anymore (which won't alter in this example).
- The
- We could do something a certain number of times with
while
:
int i = 0 ; while ( i < 50 ) { printf ( "hello, world \north " ); i ++ ; }
- We create a variable,
i
, and set it to 0. So, whilei < 50
, we run some lines of code, and we add one toi
after each run. - The curly braces around the two lines inside the
while
loop indicate that those lines will repeat, and we can add additional lines to our program after if we wanted to.
- We create a variable,
- To do the aforementioned repetition, more than commonly we can use the
for
keyword:for ( int i = 0 ; i < l ; i ++ ) { printf ( "how-do-you-do, world \n " ); }
- Once more, outset we create a variable named
i
and set it to 0. Then, we cheque thati < 50
every fourth dimension nosotros attain the top of the loop, before we run any of the code inside. If that expression is true, and so we run the lawmaking inside. Finally, afterwards we run the lawmaking inside, we usei++
to add together 1 toi
, and the loop repeats.
- Once more, outset we create a variable named
Types, formats, operators
- There are other types we can use for our variables
-
bool
, a Boolean expression of eithertrue
orfalse
-
char
, a single graphic symbol likea
ortwo
-
double
, a floating-point value with even more digits -
bladder
, a floating-bespeak value, or existent number with a decimal value -
int
, integers up to a sure size, or number of $.25 -
long
, integers with more than bits, so they tin count higher -
cord
, a string of characters
-
- And the CS50 library has corresponding functions to become input of various types:
-
get_char
-
get_double
-
get_float
-
get_int
-
get_long
-
get_string
-
- For
printf
, too, there are different placeholders for each blazon:-
%c
for chars -
%f
for floats, doubles -
%i
for ints -
%li
for longs -
%south
for strings
-
- And there are some mathematical operators we can use:
-
+
for improver -
-
for subtraction -
*
for multiplication -
/
for division -
%
for residual
-
More than examples
- For each of these examples, you can click on the sandbox links to run and edit your ain copies of them.
- In
int.c
, nosotros go and print an integer:#include <cs50.h> #include <stdio.h> int main ( void ) { int age = get_int ( "What'due south your age? \due north " ); int days = historic period * 365 ; printf ( "You are at to the lowest degree %i days old. \n " , days ); }
- Notice that we utilize
%i
to print an integer. - We can now run
make int
and run our plan with./int
. - We tin can combine lines and remove the
days
variable with:int age = get_int ( "What's your age? \n " ); printf ( "You are at least %i days old. \n " , age * 365 );
- Or even combine everything in one line:
printf ( "You are at least %i days quondam. \n " , get_int ( "What'south your age? \n " ) * 365 );
- Though, once a line is besides long or complicated, it may be better to keep ii or even three lines for readability.
- Notice that we utilize
- In
float.c
, we can get decimal numbers (called floating-betoken values in computers, because the decimal point can "bladder" between the digits, depending on the number):#include <cs50.h> #include <stdio.h> int master ( void ) { float cost = get_float ( "What's the price? \n " ); printf ( "Your total is %f. \n " , cost * ane . 0625 ); }
- Now, if nosotros compile and run our program, we'll run across a cost printed out with tax.
- We can specify the number of digits printed afterward 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 north = get_int ( "due north: " ); if ( n % 2 == 0 ) { printf ( "even \n " ); } else { printf ( "odd \north " ); } }
- With the
%
(modulo) operator, we can go the remainder ofnorthward
after it's divided past 2. If the residue is 0, we know thatdue north
is even. Otherwise, nosotros know n is odd. - And functions like
get_int
from the CS50 library practice error-checking, where only inputs from the user that matches the type we want is accepted.
- With the
- In
weather condition.c
, nosotros turn the condition snippets from before into a plan:// Atmospheric condition and relational operators #include <cs50.h> #include <stdio.h> int main ( void ) { // Prompt user for x int ten = get_int ( "10: " ); // Prompt user for y int y = get_int ( "y: " ); // Compare x and y if ( x < y ) { printf ( "x is less than y \north " ); } else if ( x > y ) { printf ( "x is greater than y \northward " ); } 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 plan in his sandbox, he first needed to run
cd src1
in the terminal. This changes the directory, or folder, to the ane in which he saved all of the lecture'due south source files. Then, he could runmake conditions
and./conditions
. Withpwd
, he can see that he'south in asrc1
folder (inside other folders). Andcd
by itself, with no arguments, will take united states of america back to our default folder in the sandbox.
- Lines that start with
- In
agree.c
, nosotros tin inquire 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 y'all agree? \n " ); // Check whether agreed if ( c == 'Y' || c == 'y' ) { printf ( "Agreed. \n " ); } else if ( c == 'N' || c == 'n' ) { printf ( "Not agreed. \n " ); } }
- We utilize two vertical bars,
||
, to indicate a logical "or", whether either expression can exist true for the status to be followed. - And if none of the expressions are true, nothing will happen since our program doesn't have a loop.
- We utilize two vertical bars,
- Let'due south implement the coughing program from week 0:
#include <stdio.h> int main ( void ) { printf ( "cough \n " ); printf ( "coughing \due north " ); printf ( "coughing \n " ); }
- Nosotros could use a
for
loop:#include <stdio.h> int main ( void ) { for ( int i = 0 ; i < 3 ; i ++ ) { printf ( "cough \due north " ); } }
- By convention, programmers tend to start counting at 0, and so
i
will have the values of0
,1
, and2
before stopping, for a total of iii iterations. We could also writefor (int i = 1; i <= iii; i++)
for the same final result.
- By convention, programmers tend to start counting at 0, and so
- Nosotros can move the
printf
line to its own office:#include <stdio.h> void cough ( void ); int chief ( void ) { for ( int i = 0 ; i < 3 ; i ++ ) { coughing (); } } void cough ( void ) { printf ( "cough \northward " ); }
- We alleged a new function with
void cough(void);
, before ourmain
function calls it. The C compiler reads our code from acme to lesser, so we demand to tell it that thecoughing
function exists, before nosotros use it. Then, afterward ourmain
part, we tin can implement thecough
role. This way, the compiler knows the function exists, and we can keep ourmain
function close to the elevation. - And our
coughing
function doesn't accept any inputs, so nosotros havecough(void)
.
- We alleged a new function with
- We tin can abstruse
coughing
further:#include <stdio.h> void cough ( int due north ); int main ( void ) { cough ( 3 ); } void cough ( int n ) { for ( int i = 0 ; i < north ; i ++ ) { printf ( "cough \n " ); } }
- Now, when we want to impress "cough" any number of times, we can just call the aforementioned office. Notice that, with
void cough(int n)
, we indicate that thecough
function takes as input anint
, which we refer to asdue north
. And insidecoughing
, we applyn
in ourfor
loop to print "cough" the right number of times.
- Now, when we want to impress "cough" any number of times, we can just call the aforementioned office. Notice that, with
- Let'south look at
positive.c
:#include <cs50.h> #include <stdio.h> int get_positive_int ( void ); int main ( void ) { int i = get_positive_int (); printf ( "%i \n " , i ); } // Prompt user for positive integer int get_positive_int ( void ) { int n ; do { due north = get_int ( "%s" , "Positive Integer: " ); } while ( n < 1 ); return n ; }
- The CS50 library doesn't have a
get_positive_int
function, simply we can write one ourselves. Our functionint get_positive_int(void)
will prompt the user for anint
and render thatint
, which our main function stores asi
. Inget_positive_int
, we initialize a variable,int n
, without assigning a value to it all the same. And then, nosotros take a new construct,practice ... while
, which does something first, and so checks a condition, and repeats until the condition is no longer truthful. - Once the loop ends because we have an
n
that is not< 1
, we tin render information technology with thereturn
keyword. And dorsum in ourmain
office, we tin can setint i
to that value.
- The CS50 library doesn't have a
Screens
- We might want a program that prints part of a screen from a video game like Super Mario Bros. In
mario0.c
, we have:// Prints a row of 4 question marks #include <stdio.h> int main ( void ) { printf ( "???? \n " ); }
- We can enquire the user for a number of question marks, and then impress 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 ( " \northward " ); }
- And we can print a two-dimensional ready of blocks with
mario8.c
:// Prints an n-by-n filigree of bricks with a loop #include <cs50.h> #include <stdio.h> int main ( void ) { int north ; practise { due north = get_int ( "Size: " ); } while ( north < ane ); for ( int i = 0 ; i < n ; i ++ ) { for ( int j = 0 ; j < n ; j ++ ) { printf ( "#" ); } printf ( " \n " ); } }
- Notice we accept ii nested loops, where the outer loop uses
i
to exercise everything insiden
times, and the inner loop usesj
, a different variable, to practise somethingdue north
times for each of those times. In other words, the outer loop printsnorthward
"rows", or lines, and the inner loop printsn
"columns", or#
characters, in each line.
- Notice we accept ii nested loops, where the outer loop uses
- Other examples not covered in lecture are available under "Source Code" for Calendar week ane.
Memory, imprecision, and overflow
- Our computer has retentivity, in hardware fries called RAM, random-access memory. Our programs use that RAM to store information equally they run, but that memory is finite. And then with a finite number of bits, we tin't stand for all possible numbers (of which at that place are an infinite number of). Then our computer has a certain number of bits for each bladder and int, and has to round to the nearest decimal value at a sure point.
- With
floats.c
, we can see what happens when we use floats:#include <cs50.h> #include <stdio.h> int master ( void ) { // Prompt user for x float x = get_float ( "x: " ); // Prompt user for y float y = get_float ( "y: " ); // Perform division printf ( "x / y = %.50f \north " , x / y ); }
- With
%50f
, we can specify the number of decimal places displayed. - Hmm, now nosotros get …
x: i y: 10 10 / y = 0.10000000149011611938476562500000000000000000000000
- It turns out that this is chosen floating-signal imprecision, where nosotros don't have enough $.25 to shop all possible values, so the computer has to store the closest value it can to 1 divided by 10.
- With
- We can see a like problem in
overflow.c
:#include <stdio.h> #include <unistd.h> int chief ( void ) { for ( int i = ane ; ; i *= 2 ) { printf ( "%i \n " , i ); sleep ( ane ); } }
- In our
for
loop, we preparei
toone
, and double it with*= 2
. (And we'll go on doing this forever, so there's no condition we check.) - We also utilize the
slumber
function fromunistd.h
to allow our programme interruption each time. - Now, when we run this program, we see the number getting bigger and bigger, until:
1073741824 overflow.c:six:25: runtime fault: signed integer overflow: 1073741824 * 2 cannot exist represented in blazon 'int' -2147483648 0 0 ...
- Information technology turns out, our program recognized that a signed integer (an integer with a positive or negative sign) couldn't store that next value, and printed an error. And then, since it tried to double information technology anyways,
i
became a negative number, and then 0. - This trouble is called integer overflow, where an integer can only exist so big before it runs out of bits and "rolls over". Nosotros can moving-picture show adding i to 999 in decimal. The terminal digit becomes 0, we comport the 1 so the next digit becomes 0, and we get 1000. But if nosotros just had 3 digits, nosotros would stop upwardly with 000 since there'due south no place to put the final 1!
- In our
- The Y2K problem arose because many programs stored the agenda yr with only 2 digits, like 98 for 1998, and 99 for 1999. But when the yr 2000 approached, the programs would have stored 00, leading to confusion betwixt the years 1900 and 2000.
- A Boeing 787 plane also had a problems where a counter in the generator overflows later a certain number of days of continuous operation, since the number of seconds it has been running could no longer be stored in that counter.
- So, we've seen a few issues that tin can happen, just now empathize why, and how to forbid them.
- With this week's problem ready, we'll use the CS50 Lab, built on top of the CS50 Sandbox, to write some programs with walkthroughs to guide us.
Source: https://cs50.harvard.edu/x/2020/notes/1/
0 Response to "Write a Program That Reads a Floating-point Number and Prints Zero if the Number Is Zero"
Post a Comment