CCPROG1_syntax_printing
Variables and Accepting User Input
In CCPROG1_variables_operators, we talked about what C is and what are the different tokens. Here, we'll go more into that including what parameters are and basic print
statements.
Variables are essentially placeholders for data. We store data in variables by either directly assigning values or obtaining them from user input. Format specifiers tell the compiler about the datatype of what we want to print or scan (accept input). (Geeks4Geeks: Format Specifiers in C)
The most common ones you'll be using in CCPROG1-2 are below:
Data Type | Special Format/Conversion Character |
---|---|
Integer/Int (think "decimal") | %d or %i |
Float | %f |
Double (think "larger float" but it's just a double-precision floating point) | %lf |
Character | %c |
Long (long decimal integer) | %ld |
Address (declared as &val ) |
%p |
String | %s |
Additional Formatting Info |
The printf() Statement and Parameters
You'll be using this a lot -- for debugging, printing instructions, outputs, etc. It just prints to the standard output or stdout
. In our case, that's the console screen. To be able to print, you have to put the line #include <stdio.h>
.It stands for standard input/output. The .h
stands for a header file. We'll get into more on header files later. stdio.h
is a library available when C is downloaded on your system.
Anyways, after doing that, you can now use a function called printf()
with the syntax:
printf("<formatted string>, args...)
(args
is arguments) The formatted string can include the format specifiers and other text you wanna put. If you have no arguments you're just printing something to the console:
#include <stdio.h>
int main() {
printf("Hello world!");
return 0;
}
If you DO include arguments, it's usually a variable. You can also call a function there if it outputs a certain datatype, or an expression.
- Arguments are also called parameters.
- Parameters are like "clues" passed to a function to alter its functionality
- It can be constant values, variables, expressions, or addresses.
Segue: Making comments
By the way, I covered documentation here, but here's what internal documentation looks like:
// this is a single line comment
/**
* This is
* a multi-line comment
*/
/*
You can also
make multi-line comments like this
but your IDE might probably auto-complete it for you
like the one above.
*/
//none of these will be printed to the console. the compiler essentially ignores this
//printf("Hello world!") <-- this will not print
Segue 2: Other escape codes
unfinished
Code | Meaning |
---|---|
\a |
alert (ring bell) |
\n |
newline |
\b |
backspace |
\t |
tab |
\\ |
backslash |
\' |
single quotation mark |
\" |
double quotation mark |
Printing one variable
#include <stdio.h>
int main() {
int nVal;
nVal = 5;
printf("The value of nVal is %d", nVal); //output: "The value of nVal is 5"
return 0;
}
Printing one expression
#include <stdio.h>
int main() {
int nVal;
nVal = 5;
printf("The value of nVal is %d", nVal + 5); //output: "The value of nVal is 10"
return 0;
}
Printing more than one variable and an expression
#include <stdio.h>
int main() {
int nVal = 5, nVal2 = 28;
printf("The value of nVal is %d.\n", nVal);
printf("The value of nVal2 though, is %d", nVal2);
//or you can combine it like so
printf("The value of nVal is %d, while nVal2 is %d\n", nVal, nVal2);
printf("The value of nVal + nVal2 is %d", nVal+nVal2);
return 0;
}
/** console output
* The value of nVal is 5.
* The value of nVal2 though, is 28
* The value of nVal is 5, while nVal2 is 28
* The value of nVal + nVal2 is 33
*/
Note: You have to make sure that the order of the parameters match the special character formats/format specifiers. We can have multiple expressions given that you have the same number of special characters matching the format specifiers.
#include <stdio.h>
int main() {
// this comment will not print to the console
int nVal = 5, nVal2 = 28;
printf("Product: %d\n", nVal*nVal2);
printf("Quotient: %f\n", nVal * 1.0/nVal2);
// if we use %d, it becomes an integer. we use %f to turn it into a float
// to fix it, we multiply nVal by 1.0 to turn it into a float.
return 0;
}
/**
* Product: 140
* Quotient: 0.178571
*/
- in the line
printf("Quotient: %f\n", nVal * 1.0/nVal2);
, if we didn't turnnVal
into a float by multiplying it by 1.0, that would result in Precision Loss. - Precision loss is when we "lose" values after compiling.
Initialize four variables with any name you like. There should be 1 int
, 1 float
, 1 char
, and 1 double
. Create 4 printf()
statements that will display all the variables and their contents using the format specifiers. Make sure the float
displays 3 decimal points, while the double
displays 2 decimal points.
#include <stdio.h>
int main() {
int nInt = 27;
float fFloat = 3.145;
char cChar = 'p';
double dDouble = 36897.54;
printf("nInt: %d\n", nInt);
printf("fFloat: %.3f\n", fFloat);
printf("cChar: %c\n", cChar);
printf("dDouble: %.2lf\n", dDouble);
}
/** Console Output
* nInt: 27
* fFloat: 3.145
* cChar: p
* dDouble: 36897.54
*/
Why is C case sensitive?
It was born like that idk (i forgot what my CCPROG1 prof said but you can Google no?), but you can print an integer as a character. It comes out as an ASCII value.
#include <stdio.h>
int main() {
char cChar = 'a', chUpper = 'A';
printf("cChar is %c\n", cChar);
printf("ASCII value of cChar is %d\n", cChar);
printf("chUpper is %c\n");
printf("ASCII value of chUpper is %d\n", cChar);
return 0;
}
/**
* cChar is a
* ASCII value of cChar is 97
* chUpper is �
* ASCII value of chUpper is 97
*/
When we printed chUpper
, we got a weird character. When we compile and run our C programs, certain amounts of memory is allocated in our system in order to run it. The amount depends on the datatype. (Recall the range.)
Memory allocation/Variable addresses
Memory is allocated differently based on how much memory is in the system and where the assigned variable is located.
Garbage Values
Garbage values is the "initial" value that all uninitialized variables (or anything stored in the memory) have. These have no significance or meaning.
#include <stdio.h>
int main() {
float fVal; //declared
printf("The value of fVal is %f\n", fVal);
fVal = 45.57; //initialized
printf("The value of fVal is %f", fVal);
return 0;
}
/*
* The value of fVal is 0.000000
* The value of fVal is 45.570000
*/
In the example above, we got 0.000... this is the garbage value. It would have a different output if it was a character data type.
#include <stdio.h>
int main() {
char cVal;
printf("The value of cVal is %c\n", cVal);
cVal = 'b';
printf("The value of cVal is %c", cVal);
return 0;
}
Addresses
Where do you live? Addresses is where the variable is located in our memory. We can access this by using an ampersand (&). The ampersand is also called a reference unary operator or the address operator. (I'm not sure what you'll be taught in CCPROG1 but he called it the reference unary operator for us.)
Let's take one of the previous examples and print the address of fVal
.
#include <stdio.h>
int main() {
float fVal; //declared
printf("The value of fVal is %f\n", fVal);
fVal = 45.57; //initialized
printf("The value of fVal is %f\n", fVal);
printf("The address of fVal is %p", &fVal);
return 0;
}
/*
* The value of fVal is 0.000000
* The value of fVal is 45.570000
* The address of fVal is 0x7fff91adbfec
*/
Since we all have different computers, the output of the address (&fVal
) would differ from computer to computer.
Keep that in mind, you'll need it for pointers later on.
Getting Input From the User aka scanf() Statement
When making programs, we can ask for input from the user using scanf()
. This function is defined within the <stdio.h>
that we included. If you're running your program and we come across that line that has a scanf()
in it, it will wait until you put in some text using your keyboard (your input device) and press enter.
When you're scanning, the input has to go somewhere → into a variable. We tell the data to go to a variable by giving it the address.
The syntax of scanf()
is scanf(<string literal>, <parameters>);
The string literal only contains the format specifiers from earlier. (like you can't put a string in it like in printf()
) They also have to be in order, but don't require spaces. (Ex. scanf("%d%d", &integ1, &integ2) will be the same as scanf("%d %d", &integ1, &integ2)
Similar to printf()
, scanf()
can be used to get the values of several variables at once.
scanf("%c%d%f", &cKey, &nNum, &fValue);
- Note that the first conversion character will correspond to the first variable in the list, the second conversion character to the second variable, and so on. It is also important the number of conversion characters is exactly the same as the number of variables in the list and that they correspond to the same data type they were declared with.
Scanning 1 variable and printing it
#include <stdio.h>
int main() {
int nMyVal;
printf("Enter an integer: \n");
scanf("%d", &nMyVal);
printf("You entered %d\n", nMyVal);
}
Scanning 2 variables at a time
#include <stdio.h>
int main() {
int nInput1, nInput2;
printf("Enter two integers: \n");
scanf("%d%d", &nInput1, &nInput2);
printf("You entered %d %d\n", nInput1, nInput2);
}
Ignore the typo but in order to scan 2 variables at one time, you'll need to type a space in between. Else, it will think your input is just for the first variable, and then it will "wait" until you input something else for the second variable. This is the concept of the input buffer.
Input Buffer
- At the start or at runtime, the input buffer is empty.
- It puts the input stream data into the variable's address of the empty variable.
- If there's more contents (i.e. more variables to store things into), it will get the next in line. (Ex. you pressed
enter
before putting the value for the second variable.) It won't pause to get input if there's multiple inputs given. (This is what happens when you put 2 numbers in, separated by a space.) scanf()
gets the input from the input buffer
After every scanf()
, it's good practice to make sure it's empty. We do this using fflush(stdin);
.
#include <stdio.h>
int main()
{
int nPrice;
char chSize;
printf("Enter price: ");
scanf("%d",&nPrice);
fflush(stdin);
//we put this here so that we're sure that the second scanf takes a new NOT leftover value
printf("Enter size: [L] or [M]");
scanf("%c",&chSize);
printf("Price of %d of size %c!!!\n", nPrice, chSize);
}
The scanf()
statement reads data from the input buffer, which is a location in the computer's memory that holds all incoming input from an input device like the keyboard. After keying in all of the data we have previously entered, the input buffer would contain:
'1' | '\n ' |
'2' | "." | '5' | '\n ' |
'c' | '\n ' |
... |
---|---|---|---|---|---|---|---|---|
%d | ignored | %f | %c | |||||
If you want to include several scanf() statements without flushing it, and the scan statements are scanning different types of data, you can add an additional scanf() to take note of the newline character that is "read" by the program when you press enter . |
char cKey;
int nNum;
float fValue;
char cTemp;
printf("Input an integer: ");
scanf("%d", &nNum);
printf("Input a float: ");
scanf("%f", &fValue);
scanf("%c", &cTemp);
printf("Input a character: ");
scanf("%c", &cKey);