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, wherefstands 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 theprintfrole that we want to employ. Somewhere there is a file on our computer,stdio.h, that includes the code that allows us to admission theprintffunction, and the#includeline 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
.cby 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(whereclangstands 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.outin the concluding prompt to run the programmea.outin 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.cbefore 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.outto 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 hiis telling the programclangto 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
yorayeto confirm, and utiliselsagain 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
printfoffice, we desire the value ofrespondin 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 requiteprintfsome other statement, or option, to tell it that we want the variableanswerto 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\noutside 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
stringvariable type, theget_stringrole, and more. We just have to write a line at the peak toincludethe 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-lfor "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,makeusesclangto compile our code fromcord.cintostring, 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;, whereintspecifies 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 sayingcounteris 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 sayintanymore, since we presume that we already specified previously thatcounteris 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
whilekeyword likewise requires a condition, and then nosotros usetruthfulequally 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 toiafter each run. - The curly braces around the two lines inside the
whileloop 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
forkeyword:for ( int i = 0 ; i < l ; i ++ ) { printf ( "how-do-you-do, world \n " ); }- Once more, outset we create a variable named
iand set it to 0. Then, we cheque thati < 50every 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 eithertrueorfalse -
char, a single graphic symbol likeaortwo -
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:-
%cfor chars -
%ffor floats, doubles -
%ifor ints -
%lifor longs -
%southfor 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
%ito print an integer. - We can now run
make intand run our plan with./int. - We tin can combine lines and remove the
daysvariable 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
%.2ffor 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 ofnorthwardafter it's divided past 2. If the residue is 0, we know thatdue northis even. Otherwise, nosotros know n is odd. - And functions like
get_intfrom 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 src1in 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 conditionsand./conditions. Withpwd, he can see that he'south in asrc1folder (inside other folders). Andcdby 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
forloop:#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
iwill have the values of0,1, and2before 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
printfline 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 ourmainfunction calls it. The C compiler reads our code from acme to lesser, so we demand to tell it that thecoughingfunction exists, before nosotros use it. Then, afterward ourmainpart, we tin can implement thecoughrole. This way, the compiler knows the function exists, and we can keep ourmainfunction close to the elevation. - And our
coughingfunction doesn't accept any inputs, so nosotros havecough(void).
- We alleged a new function with
- We tin can abstruse
coughingfurther:#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 thecoughfunction takes as input anint, which we refer to asdue north. And insidecoughing, we applynin ourforloop 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_intfunction, simply we can write one ourselves. Our functionint get_positive_int(void)will prompt the user for anintand 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
nthat is not< 1, we tin render information technology with thereturnkeyword. And dorsum in ourmainoffice, we tin can setint ito 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
ito exercise everything insidentimes, and the inner loop usesj, a different variable, to practise somethingdue northtimes 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
forloop, we prepareitoone, and double it with*= 2. (And we'll go on doing this forever, so there's no condition we check.) - We also utilize the
slumberfunction fromunistd.hto 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,
ibecame 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