Академический Документы
Профессиональный Документы
Культура Документы
Farzin Asadi - Essentials of C Programming With Microsoft® Visual Studio®-Springer (2023)
Farzin Asadi - Essentials of C Programming With Microsoft® Visual Studio®-Springer (2023)
Essentials of C
Programming
with Microsoft®
Visual Studio®
Essentials of C Programming with Microsoft®
Visual Studio®
Farzin Asadi
Essentials of C Programming
with Microsoft® Visual
Studio®
Farzin Asadi
Department of Electrical and Electronics Engineering
Maltepe University
Istanbul, Turkey
© The Editor(s) (if applicable) and The Author(s), under exclusive license to Springer Nature
Switzerland AG 2023
This work is subject to copyright. All rights are solely and exclusively licensed by the Publisher, whether
the whole or part of the material is concerned, specifically the rights of translation, reprinting, reuse of
illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way, and
transmission or information storage and retrieval, electronic adaptation, computer software, or by similar
or dissimilar methodology now known or hereafter developed.
The use of general descriptive names, registered names, trademarks, service marks, etc. in this publication
does not imply, even in the absence of a specific statement, that such names are exempt from the relevant
protective laws and regulations and therefore free for general use.
The publisher, the authors, and the editors are safe to assume that the advice and information in this book
are believed to be true and accurate at the date of publication. Neither the publisher nor the authors or the
editors give a warranty, expressed or implied, with respect to the material contained herein or for any
errors or omissions that may have been made. The publisher remains neutral with regard to jurisdictional
claims in published maps and institutional affiliations.
This Springer imprint is published by the registered company Springer Nature Switzerland AG
The registered company address is: Gewerbestrasse 11, 6330 Cham, Switzerland
In loving memory of my father Moloud Asadi
and my mother Khorshid Tahmasebi, always
on my mind, forever in my heart.
Preface
vii
viii Preface
ix
x Contents
1.1 Introduction
You can install the Community edition of Visual Studio free of charge. You need the
Visual Studio installer to install the Community edition. The Visual Studio installer
can be downloaded from the Microsoft site. Search for “visual studio installer” to
find the download page (Fig. 1.1).
After installing the Visual Studio installer, run it and install the C++ (Figs. 1.2
and 1.3) with the installation details shown in Fig. 1.4.
After installation, run the Visual Studio. Window shown in Fig. 1.5 appears in the
first run. Click the Create a new project button (Fig. 1.5) to continue.
The window shown in Fig. 1.6 appears after clicking the Create a new project
button. Search for “Empty Project” (Fig. 1.6) and click the Next button.
Now give a name to your project and save it in the desired location (Fig. 1.7).
After clicking the Create button, an empty project is generated for you (Fig. 1.8).
You can close the current project by clicking the File> Close Solution (Fig. 1.9).
You can make a new project by clicking the File> New> Project… (Fig. 1.10).
After clicking the File> New> Project…, the window shown in Fig. 1.6 appears and
you can make what you want.
Making an empty project is studied in the previous section. This sections shows how
to add a C file to the generated project. In this section, we need the Solution Explorer
window (Fig. 1.11). Click the View> Solution Explorer (Fig. 1.12) if you can-
not see it.
1.3 Entering the C Code to Visual Studio 7
You can add a C file to the project by right clicking on Source Files, select the
Add and New Item (Fig. 1.13). After clicking the New Item, the Add New Item
window appears. Select the C++ File (.cpp) however, save your work with .c exten-
sion (Fig. 1.14).
8 1 Installation of Microsoft® Visual Studio®
After clicking the Add button in Fig. 1.14, a file is added under the Source Files
(Fig. 1.15). Double click on it to open it. Now you can write your code (Fig. 1.16).
Press the Ctrl+S to save your code.
1.3 Entering the C Code to Visual Studio 9
Press the F5 key of your keyboard to run the entered code. You can use the Build>
Build Solution (Fig. 1.17) as well. The Output window (Fig. 1.18) shows the prog-
ress of Build process. The Build process is successful according to Fig. 1.18.
Visual Studio runs the code after the build process. Figure 1.19 show the output
of code shown in Fig. 1.16.
1.4 Running the C Code with Visual Studio 11
Let’s take a look at the files generated by Visual Studio. Go to the path where you
saved your project (Fig. 1.20). You will see two folders (Debug and Project1) and
one file (Project1.sln) there.
Open the Debug folder. The executable file generated from the code is here
(Fig. 1.21).
Return to the Project 1 folder and open it (Fig. 1.22). Contents of Project 1 folder
are shown in Fig. 1.23.
The main file in Fig. 1.23 contains the C code that you wrote in Visual Studio
environment. You can use the Notepad to open it (Fig. 1.24). The code shown in
Fig. 1.16 is the same as the code shown in Fig. 1.24.
When your code has an error, the build process is stopped and an error message
appears in the Error List window. For instance, if you remove the ‘;’ after ‘return 0’
(Fig. 1.25), the Error List shown in Fig. 1.26 appears on the bottom of the screen
and tells you that you have an error in the seventh line.
1.6 Color of Keywords in Visual Studio 13
C programming language has 44 keywords. These keywords are shown in Table 1.1.
First four columns contain the more important keywords.
By default, Visual Studio uses two different colors (blue and purple) for these
keywords (Fig. 1.27).
14 1 Installation of Microsoft® Visual Studio®
You can change the default colors if you like. To do so click the Tools> Options…
(Fig. 1.28).
The Options window appears after clicking the Options… (Fig. 1.29).
1.6 Color of Keywords in Visual Studio 15
Select the Fonts and Colors. Use the C/C++ User Keywords (Fig. 1.30) and C/
C++ Keywords – Control (Fig. 1.30) to select the desired colors (Fig. 1.31).
1.7 Comments
Comments have no effect on the running of the program and they will be ignored by
the compiler. They are added with the purpose of making the source code easier for
humans to understand. You can use the /* */ and // for multiline and single line com-
ments, respectively. Visual Studio shows the comments in green color. An example
is shown below:
/* this is simple program to print a message
on the screen. After printing the message it
waits untill the user press a key.
*/
#include <stdio.h>
int main() {
printf("Hello World!"); //this line prints the message on the screen
getch(); //waits untill a key is pressed
return 0; //returns 0 to the operating system
}
Further Reading 17
C is a case sensitive language. It means that capital letters and small letters are con-
sidered different things. For instance, in the following code, two variables are
defined with a and A names and each one has its own value. Output of this code is
shown in Fig. 1.32.
#include <stdio.h> //adds the stdio library to our code
//printf function is defined here
Further Reading
1. Deitel P, Deitel H (2022) C how to program: with case studies in applications and systems
programming, 9th edn. Pearson
Chapter 2
Basics of C Programming
2.1 Introduction
This chapter studies the basic programming skills such as defining different types of
variables, printing on the screen, and taking values from the user.
Here are the five primitive or primary data types that one can find in C programming
language:
(a) Integer: We use these for storing various whole numbers, such as −500, 8, 67,
2390, etc.
(b) Character: It refers to all ASCII character sets as well as to the single alpha-
bets, such as ‘x’, ‘Y’, etc.
(c) Double: These include all large types of numeric values that do not come under
either floating-point data type or integer data type. Double variables require 8
bytes of memory. Double type is more accurate in comparison to the
floating-point.
(d) Floating-point: These refer to all the real number values or decimal points,
such as 40.1, 820.673, 5.9, etc. Floating-point variables require 4 bytes
of memory.
(e) Void: This term refers to no values at all. We mostly use this data type when
defining the functions in a program. This type is defined with the aid of key-
word void.
Table 2.1 shows the primary data types and their format specifiers. Format speci-
fiers are studied in Sect. 2.5. Signed datatypes can be both positive and negative.
Unsigned datatypes accept positive values only.
2.3 Creating Variables
To create a variable, specify the variable type and name: type variableName; You
can assign an initial value to the variable as well: type
variableName = initialValue;
Let’s study some examples:
int a; // creates an integer variable with name a.
char c = 'X'; // creates an character variable with name c and puts X into it.
2.5 Printing on the Screen 21
Meaningful descriptive names must be given to variables. Below rules must be fol-
lowed when naming a variable:
(a) Names can contain letters, digits, and underscores.
(b) Names must begin with a letter or an underscore (_).
(c) Names are case sensitive (for instance, myVar and myvar are different variables).
(d) Names cannot contain whitespaces or special characters, such as !, #, %, etc.
(e) Reserved words (such as int) cannot be used as names.
Let’s study some of the examples:
int var1; // it is correct
int 1var; // it is incorrect – the name of the variable should not start using a
number
int my_var1; // it is correct
int my$var; // it is incorrect – no special characters should be in the name of the
variable
char else; // there must be no keywords in the name of the variable
int my var; // it is incorrect – there must be no spaces in the name of the variable
The printf function prints a formatted output on the screen. An escape sequence in
C language is a sequence of characters that does not represent itself when used
inside string literal or character. Some of the important escape sequences are shown
in Table 2.2.
Format specifiers are used to display the value of variables. Table 2.3 shows the
important format specifiers.
22 2 Basics of C Programming
Let’s study some examples. The following code defines three variables and prints
them on the screen. Output of this code is shown in Fig. 2.1.
#include <stdio.h>
int main()
{
float a = 120.63;
double b = 786.633;
int c = 639;
printf("a=%f\n", a);
printf("b=%lf\n", b);
printf("c=%d\n", c);
return 0;
}
The following code prints the variables using scientific notations. Output of this
code is shown in Fig. 2.2. Note that %e or %E works with float or double data
types only.
#include <stdio.h>
int main()
{
float a = 120.63;
double b = 786.633;
printf("a=%e\n", a);
printf("b=%e\n", b);
return 0;
}
The following code shows how to print a double variable up to two decimal
points. Output of this code is shown in Fig. 2.3.
#include <stdio.h>
int main()
{
double a = 123.456789;
printf("a=%.2f", a);
return 0;
}
int main()
{
int a = 156;
printf("Hexadecimal equivalent of 156 is %X.", a);
return 0;
}
24 2 Basics of C Programming
int main() {
printf("1. We are learning C programming...");
printf("2. C is a powerful language\n");
printf("3. C\tis\ta\tcase sensitive language\n");
printf("4. C is developed by Dennis M. Ritchie \rin the early 1970");
return 0;
}
The following code shows how to clear the screen. Output of this code is shown
in Fig. 2.6.
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("1. We are learning C programming...");
printf("2. C is a powerful language\n");
printf("3. C\tis\ta\tcase sensitive language\n");
printf("4. C is developed by Dennis M. Ritchie \rin the early 1970");
system("cls");
return 0;
}
The following code shows how to print the % and \ on the screen. Output of this
code is shown in Fig. 2.7.
#include <stdio.h>
int main()
{
printf("80%% of students passed the course.\n");
printf("backslash \\");
return 0;
}
The following code shows how to position the cursor at the desired row and col-
umn. Output of this code is shown in Fig. 2.8.
#include<stdio.h>
#include<windows.h>
int main()
{
COORD c1;
c1.X = 0;
c1.Y = 0;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c1);
printf("*");//* is placed at (0,0)
c1.X= 16;
c1.Y = 2;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c1);
printf("?");//? is placed at (16,2)
return 0;
}
2.6 Overflow of Variables
Variable overflow occurs when you attempt to store inside a variable a value that is
larger than the maximum value the variable can hold. The C standard defines this
situation as undefined behavior (meaning that anything might happen).
26 2 Basics of C Programming
Let’s study an example. In the following code, variable a has the maximum
allowed value. Overflow occurs if you increase the value of variable by at least one
unit. Output of the following code is shown in Fig. 2.9. Note that values shown for
variables b and c are wrong.
#include <stdio.h>
int main()
{
int a = 2147483647;
int b = 2147483647 + 1;
int c = 2147483647 + 2;
return 0;
}
The datatype size_t is unsigned integral type. It can never be negative. The sizeof
operator and functions like: strlen and strcspn (Chap. 11) return size_t type.
Functions like: malloc and memcpy take the size_t as input arguments.
The following code prints the maximum value that can be stored in a size_t vari-
able. Output of this code is shown in Fig. 2.10.
#include <stdio.h>
#include <stdint.h> //SIZE_MAX is defined here
int main()
{
// minimum range of size_t is 0 up to 4,294,967,295
printf("Maximum value that can be stored in size_t vars: %zu", SIZE_MAX);
return 0;
}
The following code prints the minimum and maximum values that can be stored in
char (character data type), int (integer data type), and long long (long integer data
type) variables. This code also tells how much memory is required to store these
data types in memory. Output of this code is shown in Fig. 2.11.
#include <stdio.h>
#include <limits.h>
int main()
{
printf("size of a char variable in Bytes:%d \n", sizeof(char));
printf("Minimum of a char variable: %d\n",CHAR_MIN);
printf("Maximum of a char variable: %d\n", CHAR_MAX);
return 0;
}
Let’s study another example. The following code prints the minimum and maxi-
mum values that can be stored in float and double data types. This code also tells
how much memory is required to store these data types in memory. Output of this
code is shown in Fig. 2.12.
#include <stdio.h>
#include <float.h>
int main()
{
printf("Minimum value of a floating point number:%e \n", FLT_MIN);
printf("Maximum value of a floating point number:%e \n\n", FLT_MAX);
return 0;
The scanf function (scanf stands for scan formatted string) is the commonly used
function to take input from the user. It reads formatted input from the standard input
such as keyboards. The name of the variable that is read by the scanf function must
have an & behind it.
The following type specifiers are recognized by the scanf function:
%d to accept input of integers
%ld to accept input of long integers
%lld to accept input of long long integers
%f to accept input of real number
%c to accept input of character types
2.9 Taking a Value From the User 29
int main() {
//variables are defined here
float radius=0.0;
float perimeter = 0.0;
float area = 0.0;
return 0;
}
The previous code prints the results up to six decimal points. The following code
shows how to control the number of decimal places. This code prints the results up
to three decimal places. Sample output of this code is shown in Fig. 2.14.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#include <stdio.h>
int main() {
//variables are defined here
float radius = 0.0;
float perimeter = 0.0;
float area = 0.0;
return 0;
}
30 2 Basics of C Programming
Let’s study some more examples. The following code reads a character and prints
its ASCII code. Sample output of this code is shown in Fig. 2.15. Table of ASCII
code are shown in Fig. 2.16.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#include <stdio.h>
int main() {
char c;
printf("Please enter a character: ");
scanf("%c", &c);
The following code takes two integer values from the user and puts them into
variables x and y. The code then swaps the values of variable x and y. Sample output
of this code is shown in Fig. 2.17.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#include <stdio.h>
int main()
{
int x, y, temp;
printf("\n\nBefore swap");
printf("\nvalue of x = %d\n", x);
printf("value of y = %d\n", y);
temp = x;
x= y;
y = temp;
printf("\n\nAfter swap\n");
printf("value of x = %d\n", x);
printf("value of y = %d\n", y);
}
2.10 Blocks
A block is a program region that contains the definitions of variables and delimits
the regions where these definitions apply. In C programming language, a block is
created using a pair of curly braces. The beginning of the block is denoted by an
open curly brace '{' and the end is denoted by a closing curly brace '}'.
2.10 Blocks 33
A variable declared inside a block is accessible in the block and all inner blocks
of that block, but not accessible outside the block. Basically, these are local to the
blocks in which the variables are defined and are not accessible outside. Variables
declared in a block will be destroyed after exiting from the block.
Following is an example. Output of this code is shown in Fig. 2.18.
#include <stdio.h>
int main() {
int n = 1;
int m = 0;
{
int n = 2;
printf("value of n inside the block: %d\n", n);
printf("value of m is accesible from the inner block: %d\n", m);
}
printf("value of n outside the block: %d\n", n);
}
Let’s study another example. You will receive an error (Fig. 2.19) if you try to
compile the following code. Note that variable a is not accessible outside the block.
#include <stdio.h>
int main()
{
{
int a = 1;
}
printf("%d", a);
}
2.11 Global Variables
Variables declared inside of a block are accesible in that block (and inner blocks)
only and are not accesible in other places of the code. You need to define a global
variable if you need a variable that is accessible everywhere.
You can create a global variable by declaring it before the main function. For
example, variable b is a global variable in the following code. Output of this code is
shown in Fig. 2.20.
#include <stdio.h>
int b = 2;
int main()
{
{
printf("I can see the variable b, b=%d\n", b);
}
printf("Me too, b=%d\n", b);
}
2.12 Constants
#include <stdio.h>
int main() {
//variables are defined here
float radius=0.0;
float perimeter = 0.0;
float area = 0.0;
return 0;
}
2.13 Enumeration 35
The following code is quite similar to the previous code. This code used the const
keyword to define the π.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#include <stdio.h>
int main() {
//constant values are defined here
const float PI = 3.1415926;
//variables are defined here
float radius=0.0;
float perimeter = 0.0;
float area = 0.0;
return 0;
}
The following code defines a constant array. (Arrays are studied in Chap. 5)
#include <stdio.h>
int main()
{
const int a[] = {1,2,3,4,5};
return 0;
}
2.13 Enumeration
Enumeration (or enum) is a user defined data type in C. It is mainly used to assign
names to integral constants; the names make a program easy to read and maintain.
Let’s study an example. In the following code values of 0, 1, 2, 3, …, 6 will be
assigned to Monday, Tuesday, Wednesday, …, Sunday. We declared two variables
(today and tomorrow) and assigned initial value to them. Output of this code is
shown in Fig. 2.21.
36 2 Basics of C Programming
#include <stdio.h>
int main()
{
enum Day today = Tuesday;
enum Day tommarow = Wednesday;
printf("today= %d\n", today);
printf("tommarow= %d\n", tommarow);
return 0;
}
You can assign any value to each of the names. Following is an example. Output
of this code is shown in Fig. 2.22.
#include <stdio.h>
enum Day {
Monday=50, Tuesday=51, Wednesday=52, Thursday=53,
Friday=20, Saturday=21, Sunday=22
};
int main()
{
enum Day Day1= Monday;
enum Day Day2 = Tuesday;
enum Day Day3 = Wednesday;
enum Day Day4 = Thursday;
enum Day Day5 = Friday;
enum Day Day6 = Saturday;
enum Day Day7 = Sunday;
return 0;
}
2.14 typedef Keyword 37
2.14 typedef Keyword
The C programming language provides a keyword called typedef, which you can
use to give a type a new name. Let’s study some examples.
In the following code, uint is another name to unsigned int data type. Output of
this code is shown in Fig. 2.23.
#include <stdio.h>
int main()
{
uint a=123;
printf("value of a is %u.", a);
return 0;
}
The typedef keywords can be used with enum and struct types as well. Following
is an example. Compare this code with the code given in the previous section.
Output of this code is shown in Fig. 2.24.
#include <stdio.h>
int main()
{
day today = Tuesday;
day tommarow = Wednesday;
printf("today= %d\n", today);
printf("tommarow= %d\n", tommarow);
return 0;
}
38 2 Basics of C Programming
You can use the typedef with structures as well (see Chap. 9).
Further Readings
1. https://bit.ly/3N71Oqk
2. https://bit.ly/43RAPoz
Chapter 3
Conditional Statements
3.1 Introduction
Conditional Statements are used to make decisions based on the conditions. This
chapter studies different types of conditional statements in C programming.
3.2 if Command
The if command permits you to run a specific code when one or more conditions are
satisfied. You can run a specific code when the condition(s) is not satisfied as well.
Figure 3.1 shows how if command works: When the condition of if statement is
satisfied, the commands inside the {} are run. When the condition of if statement is
not satisfied, the commands inside the {} are ignored and the program continue
running from the command after the }.
Let’s study an example. In the following code, two Boolean variables are defined.
Note that you need to use the stdbool.h when you want to define Boolean variables.
Defined Boolean variables are used in the condition section of if statements. Output
of this code is shown in Fig. 3.2. Note that the if statement with true condition is run.
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool b1 = true;
bool b2 = false;
if (b1)
{
printf("b1 is true, therefore this line is printed");
}
if (b2)
{
printf("b2 is false, therefore this line is NOT printed");
}
}
You are not forced to use {} when you only have a single line command in the
then section of the if statement. For example, previous code can be written as:
3.3 if-else Command 41
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool b1 = true;
bool b2 = false;
if (b1)
printf("b1 is true, therefore this line is printed");
if (b2)
printf("b2 is false, therefore this line is NOT printed");
}
Table 3.1 shows the commonly used operators in the condition section of if
statements.
3.3 if-else Command
You can use the else command to determine what should be done when the condi-
tion of if statement is not satisfied.
Let’s study an example. In this example, we want to write a C program to deter-
mine whether a given number is even or odd. The following code takes a number
from the user and divides it by two. When the remainder of division by two is zero,
the number is even. When the remainder of division is not zero, the number is odd.
Remainder of an integer divisions can be calculated with the aid of % operator.
Sample output for this code is shown in Fig. 3.3.
42 3 Conditional Statements
#include <stdio.h>
int main() {
int num;
printf("Enter an integer: ");
scanf("%d", &num);
return 0;
}
Let’s study another example. In the following code, the value of 5 is assigned to
variable c when variables a and b are equal. Zero is assigned to variable c when
variables a and b are not equal.
#include <stdio.h>
int main()
{
int a = 10;
int b = 10;
int c = 1;
c = (a == b) ? 5 : 0;
return 0;
}
The previous code can be written in the following more readable way:
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
int c = 1;
if (a == b)
c = 5;
else
c = 0;
return 0;
}
3.5 Logical Operators
Logical operators can be used in the condition section of if statements to make more
complex conditions. Logical operators are shown in Table 3.2.
Let’s study an example. The following code detects whether an entered number
is in the (3, 5] or [7,9) intervals. Sample output of this code is shown in Fig. 3.5.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#include <stdio.h>
int main(){
float num1;
printf("please enter a number:");
scanf("%f", &num1);
if ((num1 > 3 && num1 <= 5) || (num1 >= 7 && num1 < 9))
printf("it is in the allowed list...");
else
printf("it is NOT in the allowed list...");
return 0;
}
3.6 Nested if Statements
if (num != 0) {
if (num < 0) {
printf("Entered number is negative...");
}else{
printf("Entered number is positive...");
}
}else{
printf("Entered number is zero, neither positive, nor negative!");
}
return 0;
}
3.7 switch-case Statement 45
Let’s study another example. The following code takes two integer numbers
from the user and compares them with each other. Comparison result is printed with
a suitable message on the screen. Sample output of this code is shown in Fig. 3.7.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#include <stdio.h>
int main()
{
int a,b;
printf("Enter two integer values: ");
scanf("%d %d", &a,&b);
if (a >= b) {
if (a == b) {
printf("These values are equal to each other.");
} else {
printf("%d>%d", a, b);
}
} else {
printf("%d<%d", a, b);
}
return 0;
}
3.7 switch-case Statement
The switch-case statement allows you to execute one code block among many alter-
natives. You can do the same thing with the if-else ladder. However, the syntax of
the switch statement is much easier to read and write. The flowchart of switch-case
statement is shown in Fig. 3.8.
46 3 Conditional Statements
Let’s study an example. The following code uses the switch-case statement to
simulate a simple calculator. Sample outputs of this code is shown in Figs. 3.9
and 3.10.
3.7 switch-case Statement 47
int main(){
char op;
float num1, num2;
switch (op) {
case '+':
printf("%.2f+%.2f=%.2f",num1,num2, num1 + num2);
break;
case'-':
printf("%.2f-%.2f=%.2f", num1, num2, num1 - num2);
break;
case'*':
printf("%.2f*%.2f=%.2f", num1, num2, num1 * num2);
break;
case'/':
printf("%.2f/%.2f=%.2f", num1, num2, num1 / num2);
break;
default:
printf("Error, operator is not correct!");
}
return 0;
}
Let’s study another example. The following code takes an integer number
between 20 and 29 and writes the name of the number. Sample outputs of this code
is shown in Figs. 3.11 and 3.12.
48 3 Conditional Statements
int main()
{
int num;
case 1:
printf("twnety one");
break;
case 2:
printf("twnety two");
break;
case 3:
printf("twnety three");
break;
case 4:
printf("twnety four");
break;
case 5:
printf("twnety five");
break;
case 6:
printf("twnety six");
break;
case 7:
printf("twnety seven");
break;
case 8:
printf("twnety eight");
break;
case 9:
printf("twnety nine");
break;
}
}
else {
printf("Entered value is not in the correct range.");
}
return 0;
}
Further Reading 49
Further Reading
1. Deitel P, Deitel H (2022) C how to program: with case studies in applications and systems
programming, 9th edn. Pearson
Chapter 4
Loops
4.1 Introduction
In programming, loops are used to repeat a block of code until the specified condi-
tion is met. C programming has three types of loops:
1. for loop
2. while loop
3. do-while loop
Use the for loop if number of iterations is known. Use while and do-while loop
when the number of iterations is not known: Use do-while if the loop must be run at
least one time.
4.2 for Loop
Let’s see how for loop works. The initialization statement is executed only once.
Then, the test expression is evaluated. If the test expression is evaluated to false, the
for loop is terminated. However, if the test expression is evaluated to true, state-
ments inside the body of the for loop are executed, and the update expression is
updated and again the test expression is evaluated. This process goes on until the
test expression is false. When the test expression is false, the loop terminates. The
flowchart of for loop is shown in Fig. 4.1.
Let’s study an example. The following code prints the numbers from 0 to 9.
Output of this code is shown in Fig. 4.2.
#include <stdio.h>
int main()
{
for (int i = 0; i < 10; i++) {
printf("%d\n", i);
}
printf("Program finished.");
return 0;
}
4.2 for Loop 53
The variables defined in the for loop will be destroyed once the for-loop execu-
tion is terminated. For example, the following program does not compile (Fig. 4.3).
#include <stdio.h>
int main()
{
for (int i = 0; i < 10; i++)
{
printf("%d\n", i);
}
printf("value of i after loop termination is: %d.", i);//variable i is destroyed.
//there is no access to it
//at this point of the code
return 0;
}
The variables defined outside the for loop will not be destroyed when the for-
loop execution is finished. For instance, in the following code, the variable i is
accessible after loop execution is finished. Output of this code is shown in Fig. 4.4.
54 4 Loops
#include <stdio.h>
int main()
{
int i;
for (i = 0; i < 10; i++) {
printf("%d\n", i);
}
printf("\nvalue of i after loop termination is: %d.",i);
return 0;
}
The previous code can be written as follow as well. Output of following code is
shown in Fig. 4.5.
int main()
{
int i=0;
for (i ; i < 10; i++) {
printf("%d\n", i);
}
printf("\nvalue of i after loop termination is: %d.",i);
return 0;
}
4.2 for Loop 55
Let’s study more examples. The following code prints the even numbers from 0
to 8 on the screen. Output of this code is shown in Fig. 4.6.
#include <stdio.h>
int main()
{
for (int i = 0; i < 10; i=i+2) {
printf("%d\n",i);
}
return 0;
}
The following code prints the multiplication table. Output of this code is shown
in Fig. 4.7.
#include <stdio.h>
int main()
{
for (int i = 1; i < 10; i++) {
for (int j=1; j<10; j++){
printf("%d\t", i*j);
if (j == 9) printf("\n");
}
}
return 0;
}
56 4 Loops
The following code draws the right triangle shown in Fig. 4.8.
#include <stdio.h>
int main()
{
for (int i = 0; i < 10; i++) {
for (int j = 0; j < i; j++) {
printf("*");
}
printf("\n");
}
}
int main()
{
int N = 6; //N-1 gives the number of rows
int i, j, k;
for (i = 1; i <= N; i++)
{
for (j = N; j > i; j--)
{
printf(" ");
}
for (k = 1; k < i; k++)
{
printf("* ");
}
printf("\n");
}
return 0;
}
The following code calculates the factorial of value entered to variable n. Output
of this code is shown in Fig. 4.10.
#include <stdio.h>
int main()
{
int n = 5;
int product = 1;
for (int i = 1; i <= n; i++)
product *= i;
printf("%d!=%d\n\n", n, product);
return 0;
}
58 4 Loops
Let’s change the above code to print the factorial of numbers from 1 to 20. The
following code uses the nested for loops to calculate the factorial of numbers from
1 to 20. Output of this code is shown in Fig. 4.11. The correct values of factorials
are shown in the right side of Fig. 4.11. Therefore, the code gave correct results.
#include <stdio.h>
int main()
{
long long product;
return 0;
}
4.2 for Loop 59
The previous code can be written as follows as well. Output of this code is shown
in Fig. 4.12. You can compare the outputs with the correct values shown in Fig. 4.11
to ensure that the code works correctly.
#include <stdio.h>
int main()
{
__int64 product; //__int64 is the same as long long
Note that you will obtain a wrong result if you use the int type. In the below code,
product is defined as integer. Output of this code is shown in Fig. 4.13. Note that
starting from 13! outputs are wrong. The reason is the quick overflow of integer
variable.
int main()
{
int product; //variable product is defined as int
return 0;
}
62 4 Loops
The following code extracts the factors of a number. Output of this code is shown
in Fig. 4.14.
int main()
{
int number;
printf("please enter a number: ");
scanf("%d", &number);
printf("factors of entered number are:\n");
for (int i = 1; i <= number/2; i++) {
if (number % i == 0) {
printf("%d\n", i);
}
}
return 0;
}
In the following code, a delay is made with a loop which counts from 1 to
1,000,000,000. The time.h library is used to measure the generated delay. Output of
this code is shown in Fig. 4.15.
64 4 Loops
#include <stdio.h>
#include <time.h>
#define limit 1000000000
int main()
{
clock_t start = clock();
for (int i = 1; i <= limit; i++) {};
clock_t end = clock();
return 0;
}
4.3 break Command
#include <stdio.h>
int main()
{
for (int i = 0; i < 10; i++) {
if (i >=5) break;
printf("%d\n", i);
}
printf("first command after the for loop");
return 0;
}
4.4 continue Command 65
4.4 continue Command
The continue statement works somewhat like the break statement. Instead of forcing
termination, it forces the next iteration of the loop to take place, skipping any code
in between.
For the for loop, continue statement causes the conditional test and increment
portions of the loop to execute. For the while and do-while loops, continue
statement causes the program control to pass to the conditional tests.
Let’s study an example. The following code uses the continue statement to avoid
printing the even numbers on the screen. Output of this code is shown in Fig. 4.17.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) continue;
printf("%d\n", i);
}
return 0;
}
4.5 while Loop
The while loop evaluates the testExpression inside the parentheses. If testEx-
pression is true, statements inside the body of while loop are executed. Then, tes-
tExpression is evaluated again. The process goes on until testExpression is evaluated
to false. If testExpression is false, the loop terminates (ends).
The flowchart of while loop is shown in Fig. 4.18.
Let’s study an example. The following code draws a reverse right triangle.
Sample output of this code is shown in Fig. 4.19.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#include <stdio.h>
int main()
{
int n;
printf("please enter the number of lines: ");
scanf("%d", &n);
while (n>=0) {
for (int i = 0; i < n; i++)
printf("*");
printf("\n");
n--;
}
return 0;
}
4.6 Infinite Loop 67
4.6 Infinite Loop
An infinite loop is a looping construct that does not terminate the loop and executes
the loop forever. It is also called an indefinite loop or an endless loop. It either pro-
duces a continuous output or no output.
For instance, in the following code, value of a is set to ten and its value did not
change at all. Therefore, the condition of while is always true and commands inside
the {} are executed forever. The output of this code is shown in Fig. 4.20. Press the
Ctrl+Pause to stop counting.
#include <stdio.h>
int main()
{
int a = 10;
int b = 0;
while (a>5)
{
b++;
printf("%d",b);
}
return 0;
}
68 4 Loops
The following is a digital clock code. In this code, an infinite loop is used to print
the time each 1 second. After running the code you need to enter the current time
(Fig. 4.21). It starts to show the time after entering the current time (Fig. 4.22).
4.6 Infinite Loop 69
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <Windows.h>
int main()
{
int hour, minute, second;
printf("Please enter the hour: ");
scanf("%d", &hour);
printf("Please enter the minute: ");
scanf("%d", &minute);
printf("Please enter the second: ");
scanf("%d", &second);
second++;
if (second >= 60) {
minute++;
second = 0;
}
if (minute >= 60) {
hour++;
minute = 0;
}
if (hour >= 24) {
hour = 0;
}
}
return 0;
}
4.7 do-while Loop
The do-while loop is similar to the while loop with one important difference. The
body of do-while loop is executed at least once. Only then, the test expression is
evaluated. The syntax of the do-while loop is:
do
{
// the body of the loop
} while (testExpression);
The body of do-while loop is executed once. Only then, the testExpression is
evaluated. If the testExpression is true, the body of the loop is executed again and
testExpression is evaluated once more. This process goes on until testExpression
becomes false. If testExpression is false, the loop ends. Flowchart of do-while loop
is shown in Fig. 4.23.
The following code takes a number from the user and prints the number of digits.
Sample output of this code is shown in Fig. 4.24.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#include <stdio.h>
int main()
{
int n, count=0;
printf("please enter a number: ");
scanf("%d", &n);
do {
n = n / 10;
++count;
} while (n != 0);
Let’s study another example. The following code takes some numbers from the
user. Once zero is entered, the program stops getting more numbers and calculates
sum and average of entered numbers. Sample output of this code is shown in
Fig. 4.25.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#include <stdio.h>
int main()
{
float number, sum=0.0, average=0.0;
int n = 0;
do {
n = n + 1;// you can write it is as n++;
printf("please enter a number: ");
scanf("%f", &number);
sum = sum + number; //you can write it as number+=sum;
} while (number !=0.0);
Let’s study some more examples. The following code takes some numbers from
the user and returns the maximum of entered values. This code stops taking new
numbers when the user enters zero. Sample output of this code is shown in Fig. 4.26.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#include <stdio.h>
int main()
{
float number, max=0.0;
do {
printf("please enter a number: ");
scanf("%f", &number);
if (number > max) max = number;
} while (number != 0.0);
The following code returns the minimum of entered values. Sample output of
this code is shown in Fig. 4.27.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#include <stdio.h>
int main()
{
float number, min;
do {
printf("please enter a number: ");
scanf("%f", &number);
if (number != 0.0 && number < min) min = number;
} while (number != 0.0);
The following code is a simple guess game. In this code, the computer selects a
random integer number from 1 to 10 and the user needs to guess the computer’s
number with minimum trials. Here, the do-while loop continues until the user num-
ber equals the computer number. Sample output of this code is shown in Fig. 4.28.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#define _CRT_RAND_S
#include <stdio.h>
#include <stdlib.h>
int main() {
unsigned int number;
int userGuess;
int n = 0;
do {
n++;
printf("Enter your guess(1..10):");
scanf("%d",&userGuess);
if (userGuess == selectedNumber) {
printf("You winned after %d trial.",n);
}
} while (userGuess != selectedNumber);
return 0;
}
74 4 Loops
Further Reading
1. Deitel P, Deitel H (2022) C how to program: with case studies in applications and systems
programming, 9th edn. Pearson
Chapter 5
Arrays
5.1 Introduction
An array is defined as the collection of similar type of data items stored at contigu-
ous memory locations. Arrays are the derived data type in C programming language
which can store the primitive type of data such as int, char, double, float, etc. It also
has the capability to store the collection of derived data types, such as pointers,
structure, etc. The array is the simplest data structure where each data element can
be randomly accessed by using its index number.
C array is beneficial if you have to store similar elements. For example, if we
want to store the marks of a student in six subjects, then we do not need to define
different variables for the marks in the different subject. Instead, we can define an
array which can store the marks in each subject at the contiguous memory locations.
By using the array, we can access the elements easily. Only a few lines of code
are required to access the elements of the array.
5.2 Defining an Array
To create an array, define the data type (like int) and specify the name of the array
followed by square brackets []. For instance, double myArray[7] makes an array
with myArray name and it can store seven double values.
An array with four elements is shown in Fig. 5.1. Note that the first element of
the array has index of zero.
Let’s study an example. The following code defines array a to store five integer
elements. Array a is initialized with 1, 2, 3, 4 and 5 values. Array b can store five
integers but it is not initialized. Output of this code is shown in Fig. 5.2.
#include <stdio.h>
int main()
{
int a[5] = { 1,2,3,4,5 };
printf("value of a[0]=%d\n", a[0]);
printf("value of a[1]=%d\n", a[1]);
printf("value of a[2]=%d\n", a[2]);
printf("value of a[3]=%d\n", a[3]);
printf("value of a[4]=%d\n", a[4]);
int b[5];
return 0;
}
You are not forced to write the number of elements when an array is initialized
(when an array is not initialized you need to determine the number of elements
inside the brackets). For instance, the previous code can be written as follows:
#include <stdio.h>
int main()
{
int a[] = { 1,2,3,4,5 };
printf("value of a[0]=%d\n", a[0]);
printf("value of a[1]=%d\n", a[1]);
printf("value of a[2]=%d\n", a[2]);
printf("value of a[3]=%d\n", a[3]);
printf("value of a[4]=%d\n", a[4]);
int b[5];
return 0;
}
5.3 Arrays and Pointers 77
Let’s study another example. In the following code, five numbers are taken from
the user, stored in an array and then printed in the reverse order, i.e., from the last
one to the first one. Sample output of this code is shown in Fig. 5.3.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int number[5];
As shown in Fig. 5.4, name of an array is a pointer to the first element of the array
(pointers are studied in Chap. 8). Let’s study an example.
In the following code, an array with name a is defined. Output of this code is
shown in Fig. 5.5 (address shown on your computer may be different). Note that a
and &a[0] are the same. It is because the array name points to the first element of
the array.
#include <stdio.h>
int main()
{
int a[] = { 1,2,3,4,5 };
Note that &x[0] is equivalent to x and x[0] is equivalent to *x. &x[1] is equiva-
lent to x+1 and x[1] is equivalent to *(x+1). &x[2] is equivalent to x+2 and x[2] is
equivalent to *(x+2), etc. Basically, &x[i] is equivalent to x+i and x[i] is equivalent
to *(x+i).
Let’s study another example. Consider the following code:
#include <stdio.h>
int main() {
int a[] = { 7,1,3,9,0,2,4,5,8,6 };
int* b;
printf("initial value of a[1]= %d", a[1]);
b = a;
b[1] = 60;
In the above code, array a with ten integer elements and pointer b are defined
(Fig. 5.6). The b=a forces the pointer b to point to first element of the array a
(Fig. 5.7). Therefore, after the b=a line, the values stored in the array a can be
manipulated by using the pointer b. Output of this code is shown in Fig. 5.8.
5.4 Length of an Array 79
5.4 Length of an Array
You can count the number of elements in an array, i.e., length of an array, with the
aid of sizeof operator. The following code shows how to do so. Output of this code
is shown in Fig. 5.9.
#include <stdio.h>
int main()
{
int array[] = { 1,2,3,4,5,6,7,8,9,10};
return 0;
}
The following code shows how to remove an element from an array. After removing
the requested element −1 is added to the end of the array. In this code, a function is
defined to remove the element. User defined functions are studied in Chap. 6
(Fig. 5.10).
#include <stdio.h>
int main()
{
int array[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 };
int N = sizeof(array) / sizeof(array[0]);
printf("Original array:\n");
for (int i = 0; i < N; i++)
printf("%d ", array[i]);
return 0;
}
5.6 2D Arrays
One dimensional arrays are studied in the previous sections of this chapter. Two-
dimensional arrays can be defined in C as well. A two-dimensional array with three
rows and four columns is shown in Fig. 5.11.
int main()
{
// |1 3 5|
//array= | |
// |2 4 6|
int array[2][3] = { {1,3,5},{2,4,6} };
printf("array[0][1]=%d\n", array[0][1]);
printf("array[1][2]=%d\n", array[1][2]);
return 0;
}
Let’s study another example. The following code prints the multiplication table
on the screen. It stores the multiplication table in a 9 by 9 array and then prints the
content of the array using a nested for loop. Output of this code is shown in Fig. 5.13.
#include <stdio.h>
int main()
{
int array[9][9];
return 0;
}
1 3 5
Let’s study another example. The following code multiplies mat1=
6 6 2 8 7 4 2
with mat2= 1 3 4 4 and prints the obtained result on the screen. Output of this
7 5 6 2
code is shown in Fig. 5.14.
5.7 Size of 2D Arrays 83
#include <stdio.h>
int main()
{
// this code calculates the matrix product of mat1 and mat2;
// i.e., prod=mat1*mat2
// product is a 2X4 matrix
int mat1[2][3] = { {1,3,5},{7,4,2} };
int mat2[3][4] = { {6,6,2,8},{1,3,4,4},{7,5,6,2}};
int prod[2][4] = { {0,0,0,0},{0,0,0,0} };
return 0;
}
5.7 Size of 2D Arrays
The size of operator can be used to obtain the number of rows and columns a 2D
array has. Let’s study an example. The following code shows how sizeof operator
can be used to determine the number of rows and columns an array has. It uses two
nested for loops to print the content of the 2D array as well. Output of this code is
shown in Fig. 5.15.
84 5 Arrays
#include <stdio.h>
int main()
{
// |1 3 5|
//array= | |
// |2 4 6|
int array[2][3] = { {1,3,5},{2,4,6} };
printf("array=\n");
for (int i = 0; i < numberOfRows; i++) {
for (int j = 0; j < numberOfColumns; j++) {
printf("%d ", array[i][j]);
}
printf("\n");
}
return 0;
}
5.8 malloc Function
The size of the arrays defined in the previous sections is constant and the compiler
knows how much each array require space on the stack memory. In C programming,
you can define arrays with variable size as well.
The malloc function can be used to allocate the specified number of bytes. The
allocated memory is always on the heap memory. Prototype of malloc function is:
void *malloc(size_t size). It takes the size of the memory block in bytes and return
a pointer to the allocated memory or NULL if the request fails (pointers are studied
in Chap. 8).
Note that the allocated memory must be released before ending the program. The
memory allocated by malloc (or calloc) can be deallocated by calling the free
function. Prototype of free function is void free(void *ptr). The free function takes
the pointer to a memory block previously allocated with malloc (or calloc).
5.8 malloc Function 85
Let’s study an example. In the following code, length of an integer array is asked
at the runtime, then an array with the entered length is made on the heap and filled
with the values entered by the user. Sample output of this code are shown in
Fig. 5.16.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> //malloc is defined here.
//add stdlib when you want to use malloc
int main()
{
printf("please enter the length of array: ");
int N=0;
scanf("%d", &N);
free(myArray);
return 0;
}
Let’s study another example. The following code generates a password with the
length determined by the user at the runtime. This code uses the rand function
(Chap. 10). Sample output of this code is shown in Fig. 5.17.
86 5 Arrays
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //The strlen function is defined here.
#include <time.h>
int main()
{
int length;
printf("Enter the desired length for the password: ");
scanf("%d", &length);
switch (char_type)
{
case 0:
password[i] = digits[rand() % digits_length];
break;
case 1:
password[i] = lowers[rand() % lowers_length];
break;
case 2:
password[i] = uppers[rand() % uppers_length];
break;
case 3:
password[i] = symbols[rand() % symbols_length];
break;
}
}
password[length] = '\0'; //makes the last character NULL character
printf("Generated password: %s\n", password);
free(password);
return 0;
}
5.9 calloc Function 87
5.9 calloc Function
Similar to malloc function, the calloc function can be used for dynamic memory
allocation purposes (dynamic memory allocation can be defined as a procedure in
which the size of a data structure, like an array, is changed during the runtime).
However, following differences exists between malloc and calloc:
(a) malloc takes a single argument (the amount of memory to allocate in bytes),
while calloc takes two arguments: the number of elements and the size of each
element.
(b) malloc only allocates memory, while calloc allocates and sets the bytes in the
allocated region to zero.
Let’s study an example. In the following code, the length of an integer array is
asked at the runtime, then an array with the entered length is made on the heap and
initialized with zero. The initialized values are replaced with the values entered by
the user. Sample output of this code are shown in Fig. 5.18.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> //calloc is defined here.
//add stdlib when you want to use calloc
int main()
{
printf("please enter the length of array: ");
int N=0;
scanf("%d", &N);
int * myArray;
myArray=( int *) calloc(N , sizeof (int )); //making the array
free(myArray);
return 0;
}
88 5 Arrays
Further Reading
1. Deitel P, Deitel H (2022) C how to program: with case studies in applications and systems
programming, 9th edn. Pearson
Chapter 6
Functions
6.1 Introduction
6.2 Definition of a Function
return_type function_name(parameterList)
{
body of the function
}
#include <stdio.h>
int main()
{
printf("add(7,5)=%d\n", add(7,5));
return 0;
}
//function definition is given below:
int add(int x, int y) {
int result = x + y;
return result;
}
There is no need to function declaration when the function definition is above the
main function. Following is an example. Output of this code is shown in Fig. 6.2.
#include <stdio.h>
//function definition:
int add(int x, int y) {
int result = x + y;
return result;
}
int main()
{
printf("add(7,5)=%d\n", add(7, 5));
return 0;
}
The return command is the last command that is run in a function. For instance,
in the following code “end of function” expression is not printed on the screen
(Fig. 6.3).
#include <stdio.h>
int main()
{
printf("add(7,5)=%d\n", add(7, 5));
return 0;
}
In the following code, implicit type casting is applied to the arguments. Output
of this code is shown in Fig. 6.4.
#include <stdio.h>
int main()
{
printf("add(7.6,5.4)=%d\n", add(7.6, 5.4));
return 0;
}
6.3 Pass by Value
In pass by value, the function parameters get the copy of actual parameters which
means changes made in function parameters did not reflect in actual parameters.
The following code helps understand the nature of pass by value. Note that the value
of variables a and b did not change after calling the function. Output of this code is
shown in Fig. 6.5.
6.3 Pass by Value 93
#include <stdio.h>
int main()
{
int a = 7;
int b = 5;
printf("add(a,b)=%d\n", add(a,b));
6.4 List of Functions
Consider the following code. This function contains three functions: main, mult,
and add. Output of this code is shown in Fig. 6.6.
#include <stdio.h>
int main()
{
printf("mult(7,5)=%d\n", mult(7, 5));
return 0;
}
You can see the list of functions by clicking the function list (Fig. 6.7). Click on
the desired function to go to its definition or declaration.
6.5 void Functions 95
6.5 void Functions
A void function is a function that does not return any value. An example of a void
function is given below. Output of this function is shown in Fig. 6.8.
#include <stdio.h>
void displayMessage();
int main()
{
displayMessage();
return 0;
}
void displayMessage() {
printf("Function is run");
}
96 6 Functions
void functions do not return any value to their calling function. Therefore, there
is no need to use any return command in the function definition. In void functions,
a return statement can help end the execution of the function, and return the control
to the calling function.
Let’s study an example. Consider the following code. Output of this code is
shown in Fig. 6.9. Note that calling the printNumbers with a negative argument
caused a new line.
#include <stdio.h>
int main()
{
printNumbers(10);
printNumbers(-5);
printNumbers(8);
return 0;
}
Let’s change the code in a way that no new line is generated for negative argu-
ments. Change the code to what is shown below. Now, when a negative value is
passed to printNumbers, the return command is run and execution is stopped and
control is returned to the calling function. Output of this code is shown in Fig. 6.10.
Note that there is no white line at this time.
6.5 void Functions 97
int main()
{
printNumbers(10);
printNumbers(-5);
printNumbers(8);
return 0;
}
The following code uses the return command to call another void function when
negative values are passed to printNumbers. Output of this code is shown in
Fig. 6.11.
#include <stdio.h>
int main()
{
printNumbers(10);
printNumbers(-5);
printNumbers(8);
return 0;
}
void errorMessage()
{
printf("Negative numbers are not acceptable!\n");
}
98 6 Functions
Variables defined inside a function (i.e., variables defined between { and }) are
local. Variables defined inside the function will be destroyed when function execu-
tion is finished.
Let’s study an example. In the following code, variable x is defined inside the
myFunction. Variable x is not accessible inside the main function. If you try to com-
pile the following code, you will receive the error message shown in Fig. 6.12.
#include <stdio.h>
int main() {
myFunction();
printf("value of x=%d", x);
return(0);
}
void myFunction()
{
int x = 0;
printf("Hello! I am myFunction.");
}
int main()
{
float tempF;
float tempC;
printf("Enter the Fahrenheit value: ");
scanf("%f", &tempF);
tempC = Far2Cel(tempF);
printf("Entered value in Celsius= %.2f",tempC);
return 0;
}
int main()
{
int n, r, nPr;
return 0;
}
int factorial(int n) {
int product = 1;
for (int i = 1; i <= n; i++) {
product = i * product;
}
return product;
}
6.9 Password Checker
The following code is a password checker program. It ensures that the password
entered to the array p has the conditions written in the first four rows. Output of this
code is shown in Fig. 6.15.
6.10 Heads and Tails 101
// at least 8 characters
// at least 1 uppercase letter
// at least 1 lowercase letter
// at least 1 symbol
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
int main()
{
char p[] ="Aqws6t % Bn@";
if (verify_password(p))
printf("Verified.");
else
printf("Invalid password!");
return 0;
}
bool verify_password(char* s)
{
int length = strlen(s);
if (length < 8) return false;
if (hasUpperCaseLetter &&
hasLowerCaseLetter &&
hasSymbol) return true;
}
The following programs generate the heads and tails. Sample output of this code is
shown in Fig. 6.16.
102 6 Functions
#include <stdio.h>
#include <time.h>
coin flipCoin();
int main()
{
srand(time(NULL));
return 0;
}
coin flipCoin()
{
if (rand() % 2 == 0)
return HEADS;
else
return TAILS;
}
6.11 Cost of a Hotel
The following code is a hotel cost calculator. Hotel rates are given as Saturday 600
$, Sunday 550 $ and other days of the week 400 $. Sample output of the code is
shown in Fig. 6.17.
6.11 Cost of a Hotel 103
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
typedef enum Day {
Monday, Tuesday, Wednesday, Thursday,
Friday, Saturday, Sunday
} day;
int costCalc(day d);
day str2day(char s[]);
int main()
{
printf("Day of arrival: ");
char dayOfArrival[10];
scanf("%s", dayOfArrival);
int payment= costCalc(str2day(dayOfArrival));
printf("You need to pay: %d $.", payment);
return 0;
}
int costCalc(day d)
{
switch (d)
{
case Monday:
case Tuesday:
case Wednesday:
case Thursday:
case Friday:
return 400;
break;
case Saturday:
return 600;
break;
case Sunday:
return 550;
break;
}
}
day str2day(char s[])
{
if (!strcmp(s,"Monday") | !strcmp(s,"monday"))
return Monday;
if (!strcmp(s,"Tuesday") | !strcmp(s,"tuesday"))
return Tuesday;
if (!strcmp(s,"Wednesday") | !strcmp(s,"wednesday"))
return Wednesday;
if (!strcmp(s,"Thursday") | !strcmp(s,"thursday"))
return Thursday;
if (!strcmp(s,"Friday") | !strcmp(s,"friday"))
return Friday;
if (!strcmp(s,"Saturday") | !strcmp(s,"saturday"))
return Saturday;
if (!strcmp(s,"Sunday") | !strcmp(s,"sunday"))
return Sunday;
}
104 6 Functions
The Fibonacci sequence is a set of integers (the Fibonacci numbers) that starts with
zero, followed by one, then by another one, and then by a series of steadily increas-
ing numbers. The sequence follows the rule that each number is equal to the sum of
the preceding two numbers. The Fibonacci sequence begins with: 0, 1, 1, 2, 3, 5, 8,
13, 21, 34, 55, 89, 144, 233 ... Each number, starting with the third, adheres to the
prescribed formula. For example, the seventh number, 8, is preceded by 3 and 5,
which add up to 8. The sequence can theoretically continue to infinity, using the
same formula for each new number.
The following is an iterative approach to generate the first n terms of Fibonacci
sequence. Sample output of this code is shown in Fig. 6.18.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int term1 = 0;
int term2 = 1;
int tmp=0;
int fibn = 0;
int n = 0;
printf("0, 1,");
return 0;
}
A function that calls itself is known as a recursive function (Fig. 6.19). This tech-
nique is known as recursion. The recursion continues until some condition is met to
prevent it. To prevent infinite recursion, if...else statement (or similar approach) can
be used where one branch makes the recursive call, and the other does not.
The following code generates the first n terms of Fibonacci sequence using a
recursive approach. Sample output of this code is shown in Fig. 6.20.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int term1 = 0;
int term2 = 1;
int tmp = 0;
int fibn = 0;
int n = 0;
return 0;
}
int fib(int n)
{
if (n > 1) return fib(n - 1) + fib(n - 2); //recursive step
else if (n == 1) return 1;
else if (n == 0) return 0;
}
106 6 Functions
Increase the number of terms and compare the speed of both approaches (itera-
tive and recursive) and see which one is more rapid.
6.14 Recursive Factorial
The following code uses the recursive approach to calculate the factorial. Sample
output of this code is shown in Fig. 6.21.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int fact(int n);
int main()
{
int n;
printf("Calculation of n! Please enter n: ");
scanf("%d", &n);
printf("%d!=%d",n,fact(n));
return 0;
}
int fact(int k)
{
if (k != 1) return k * fact(k - 1);
else if (k == 1) return 1;
}
6.15 Recursive Product
The following code uses the recursive approach to calculate the product of two
numbers (hint: for instance, 5 × 3 = 5 + 5 × 2 = 5 + 5 + 5 × 1 = 5 + 5 + 5). Sample
output of this code is shown in Fig. 6.22.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int x,y;
printf("Please enter two numbers: ");
scanf("%d %d", &x,&y);
printf("%d*%d=%d",x,y,product(x,y));
return 0;
}
The following code uses a recursive approach to calculate the maximum of a given
array. Sample output of this code is shown in Fig. 6.23.
108 6 Functions
#include <stdio.h>
int main()
{
int array[] = {4, 1, 8};
int n = 3;
return 0;
}
#include <stdio.h>
int main()
{
int array[] = { 4, 1, 8 };
int n = 3;
return 0;
}
6.17 Static Variables
Static variables have a property of preserving their value even after they are out of
their scope! Hence, static variables preserve their previous value in their previous
scope and are not initialized again in the new scope. Note that static variables are
allocated memory in data segment, not stack segment. Static variables should not be
declared inside structure. The reason is C compiler requires the entire structure ele-
ments to be placed together, i.e., memory allocation for structure members should
be contiguous.
A static int variable remains in memory while the program is running. A normal
or auto variable is destroyed when a function call where the variable was declared
is over. For example, we can use static int to count a number of times a function is
called, but an auto variable cannot be used for this purpose.
Let’s study some examples. Following code prints 1 1 1 after three call (Fig. 6.25).
110 6 Functions
#include <stdio.h>
void myFunction();
int main()
{
myFunction();
myFunction();
myFunction();
return 0;
}
void myFunction()
{
int calls = 0;
calls++;
printf("calls: %d\n", calls);
}
However, the following code prints 1 2 3 after three calls (Fig. 6.26). Note that
calls variable is defined as static variable at this time.
#include <stdio.h>
void myFunction();
int main()
{
myFunction();
myFunction();
myFunction();
return 0;
}
void myFunction()
{
static int calls = 0; //initialization only happens in the first run
calls++;
printf("calls: %d\n", calls);
}
6.18 Pass by Reference 111
6.18 Pass by Reference
Pass by value is studied in Sect. 6.3. There is another way to pass a function argu-
ment as well: pass by reference. Pass by reference is studied in this section.
Pass by reference (or more exactly, pass by pointer) means to pass the reference
of an argument in the calling function to the corresponding formal parameter of the
called function. The called function can modify the value of the argument by using
its reference passed in.
The following example shows how arguments are passed by reference. The refer-
ence parameters are initialized with the actual arguments when the function is
called. Output of this function is shown in Fig. 6.27.
#include <stdio.h>
int main() {
int x = 5;
int y = 10;
printf("before calling the swap function: x=%d y=%d", x, y);
swap(&x, &y);
printf("\nafter calling the swap function : x=%d y=%d", x, y);
return(0);
}
Arrays can be given to functions as argument. Let’s study an example. In the follow-
ing code, calcSum function calculates the sum of array elements given to it. Output
of this code is shown in Fig. 6.28.
#include <stdio.h>
int main() {
float num[] = { 23.4, 55, 22.6, 3, 40.5, 18 };
return 0;
}
The previous code can be written as follows as well. Output of this code is shown
in Fig. 6.29.
6.19 Passing an Array to a Functions 113
#include <stdio.h>
float calcSum(float* numbers, int length); //Equal to: float calcSum(float numbers[],
int length);
int main() {
float num[] = { 23.4, 55, 22.6, 3, 40.5, 18 };
return 0;
}
#include <stdio.h>
#include <math.h>
main(void)
{
double a[] = {9.2, 1.5, 6.7, 8.2, 5.5, 7.1};
double numerator = 0;
for (int j = 0; j < N; j++)
numerator = numerator + pow((x[j] - mu), 2);
Let’s study another example. In the following code, string str is reversed. Output
of this code is shown in Fig. 6.31.
6.20 Functions with Variable Number of Arguments 115
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "This is a test message.";
return 0;
}
Variadic functions are functions that can take a variable number of arguments. In C
programming, a variadic function adds flexibility to the program. It takes one fixed
argument and then any number of arguments can be passed. The variadic function
consists of at least one fixed variable and then an ellipsis(…) as the last parameter.
Let’s study some examples. myFunction in the following code takes a variable
number of arguments and prints them on the screen. Output of this code is shown in
Fig. 6.32.
116 6 Functions
#include <stdio.h>
#include <stdarg.h> // add this library
int main()
{
return 0;
}
void myFunction(int num_args, ...) //... shows that myFunction takes a variable number
of args.
{
va_list args;
va_start(args, num_args);
va_end(args);
The following code takes some numbers and returns the maximum. Sample out-
put of this code is shown in Fig. 6.33.
6.21 Entering the Functions to Separate Files 117
#include <stdio.h>
#include <stdarg.h>
int main()
{
printf("max(10, 23, 6, 45, 9)= %d\n", max(5, 10, 23, 6, 45, 9));
printf("max(7, 4, 2)= %d\n", max(3, 7, 4, 2));
return 0;
}
int max(int num_args, ...) //maximum function with variable number of args.
{
va_list args;
va_start(args, num_args);
int max = 0;
va_end(args);
return max;
}
It is a good idea to write each function in a seperate file. Let’s study an example.
Consider the following code. In this code, all the required functions are placed in
one single file.
118 6 Functions
#include <stdio.h>
int main()
{
int a =60;
int b = 22;
printf("a=60, b=22\n\n");
Let’s put the used functions in separate files. Right click on the Source Files
(Fig. 6.34) in the Solution Explorer window and select the Add>> New Item
(Fig. 6.35). Click the View> Solution Explorer (Fig. 6.36) if the Solution Explorer
window is not visible.
6.21 Entering the Functions to Separate Files 119
After clicking the View> Solution Explorer, Add New Item window appears on
the screen. Select the C++ File (.cpp) and make the add.c file (Fig. 6.37). Now, add.c
is added to the Source Files (Fig. 6.38).
Double click the add.c file in the Solution Explorer window and write the code
for add function (Fig. 6.39).
Add the other required functions to the Source Files (Fig. 6.40).
The code of sub and div functions (Fig. 6.40) are shown below:
//sub.c file
int sub(int x, int y)
{
return x - y;
}
//div.c file
int div(int x, int y)
{
return x / y;
}
Now all the functions are defined in separate files. Double click the main func-
tion and change it to:
#include <stdio.h>
int main()
{
int a =60;
int b = 22;
printf("a=60, b=22\n\n");
6.22 extern Keyword
The extern keyword permits you to access variable defined in other files. It is impor-
tant to note that the extern keyword is used to only declare a variable and not define
a variable. Let’s study a simple example.
Further Reading 123
Double click the div.c function (Fig. 6.40) and change it to:
//div.c file
int z=125;
Now an integer variable is defined in div.c file. To use the variable z in the main.c
you need to use the extern keyword:
#include <stdio.h>
extern int z;
int main()
{
printf("z=%d", z);
return 0;
}
Further Reading
1. Deitel P, Deitel H (2022) C how to program: with case studies in applications and systems
programming, 9th edn. Pearson, London
Chapter 7
Some Useful Functions
7.1 Introduction
In Visual Studio, you have access to many ready to use functions. This chapter stud-
ies some of these functions.
You can use the system function to run .exe files. For instance, the following code
shows how to run the Adobe® Acrobat Reader®.
#include <stdio.h>
#include <stdlib.h>
int main()
{
// system("C:\\Program Files\\Adobe\\Acrobat DC\\Acrobat\\Acrobat.exe");
// if you get an error for above command see here: https://bit.ly/3GF7nbC
return 0;
}
© The Author(s), under exclusive license to Springer Nature Switzerland AG 2023 125
F. Asadi, Essentials of C Programming with Microsoft® Visual Studio®,
https://doi.org/10.1007/978-3-031-35711-4_7
126 7 Some Useful Functions
#include <stdio.h>
#include <stdlib.h>
int main()
{
return 0;
}
int main()
{
PlaySound(TEXT("c:\\wave.wav"), NULL, SND_FILENAME|SND_SYNC);
return 0;
}
You can use the following code as well. You need to add the winmm library
manually if you use the following code.
// see: https://bit.ly/3GiDLzy for more information
int main()
{
PlaySound(TEXT("c:\\wave.wav"), NULL, SND_FILENAME|SND_SYNC);
return 0;
}
Click the Project> Project1 Properties (Fig. 7.1) and then add the winmm.lib to
Additional Dependencies (Fig. 7.2). This adds the winmm library to your project.
Fig. 7.1 Project> Project Properties
7.4 main Arguments
Sometimes it is useful to pass some arguments to the main function. For example,
assume that you want to write a program to copy the files. In this case, it is useful to
take the source and destination paths from the command line.
The main function has two arguments traditionally called argc and argv: int main
(int argc, char *argv[]). The argument definitions are as follows:
argc: An integer that contains the count of arguments that follow in argv. The argc
parameter is always greater than or equal to 1.
argv: An array of null-terminated strings representing command-line arguments
entered by the user of the program. By convention, argv[0] is the command with
which the program is invoked. argv[1] is the first command-line argument. The
last argument from the command line is argv[argc - 1], and argv[argc] is
always NULL.
Let’s study an example. The following code prints the arguments passed to it
from the command line. Output of this code is shown in Fig. 7.3.
#include <stdio.h>
Let’s give more command line arguments to the previous code. Click the Project>
Project1 Properties (Fig. 7.4) and enter the arguments to the Command Arguments
(Fig. 7.5). If you run the program, you will receive the output shown in Fig. 7.6.
7.4 main Arguments 129
You can pass the arguments to the main function using the command prompt.
Open the command line (Fig. 7.7) and enter the arguments after the .exe file path
(Fig. 7.8).
Let’s study another example. Here, we want to write a program to play a .wav
file. The path of the .wav file is given to the main function as an argument. Code is
shown below:
#include <stdio.h>
#include <Windows.h> // This needs to be included for PlaySound()
#pragma comment(lib,"winmm.lib") // This adds the static library
// "winmm.lib" to the project
return 0;
}
7.4 main Arguments 131
Click the Project> Project1 Properties (Fig. 7.9) and select the Use Multi-Byte
Character Set (Fig. 7.10).
Let’s test the program. Click the Project> Project1 Properties (Fig. 7.11) and give
the path of the file to the Command Arguments (Fig. 7.12). Press the F5 to run the
code and see the result.
Fig. 7.11 Project> Project Properties
7.5 exit Function
The exit function terminates the program immediately. Any open file descriptors
belonging to the program are closed as well.
Let’s study an example. The following code terminates as soon as it reaches the
exit function. Output of this code is shown in Fig. 7.13.
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Hello World!\n");
exit(EXIT_SUCCESS); // exit(EXIT_SUCCESS) is the same as exit(0)
// exit(EXIT_FAILURE) is the same as exit(1)
printf("C programming is fun...");
return 0;
}
7.6 atexit Function
The atexit function causes the specified function to be called when the program
terminates. Let’s study an example. In the following code, cleanup function is called
once the code reaches the end of the main function, i.e., return 0 line. Output of this
code is shown in Fig. 7.14.
#include <stdio.h>
#include <stdlib.h>
void cleanup();
int main()
{
atexit(cleanup);
printf("Hello World!\n");
printf("main function finished here.\n");
return 0;
}
void cleanup()
{
printf("Hi. I am cleanup function...");
}
7.6 atexit Function 135
Let’s study another example. In the following code, cleanup function is called
when the code reaches the exit function. Output of this code is shown in Fig. 7.15.
#include <stdio.h>
#include <stdlib.h>
void cleanup();
int main()
{
atexit(cleanup);
printf("Hello World!\n");
exit(EXIT_FAILURE);
printf("main function finished here.\n");
return 0;
}
void cleanup()
{
printf("Hi. I am cleanup function...");
}
The following code calculates the amount of time that the code is run. A sample
output of this code is shown in Fig. 7.16.
136 7 Some Useful Functions
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void cleanup();
time_t start, end;
int main()
{
time(&start);
atexit(cleanup);
int a, b;
printf("please enter two numbers: ");
scanf("%d %d", &a, &b);
printf("Sum of entered numbers is: %d\n", a+b);
return 0;
}
void cleanup()
{
time(&end);
double diff = difftime(end, start);
printf("Execution time: %.2f sec\n", diff);
}
The following code can be used to read the mouse position. Origin of the screen is
shown in Fig. 7.17 (Fig. 7.18).
7.7 Reading the Mouse Pointer Position 137
#include <stdio.h>
#include <windows.h>
int main()
{
POINT Point;
while (1)
{
GetCursorPos(&Point);
return 0;
}
7.8 Timer
Timers are used to call a function at a specified interval of time repeatedly. In the
following code, function f is called repeatedly after 1000 ms.
#include <windows.h>
#include <stdio.h>
void CALLBACK f(HWND hwnd, UINT uMsg, UINT timerId, DWORD dwTime)
{
printf("Hello World!\n");
}
int main()
{
MSG msg;
return 0;
}
Let’s study another example. The following code calls the readMousePosition
function repeatedly every 1000 ms. This program prints the mouse pointer location
every 1 s.
Further Reading 139
#include <windows.h>
#include <stdio.h>
POINT Point;
void CALLBACK readMousePosition(HWND hwnd, UINT uMsg, UINT timerId, DWORD dwTime);
int main()
{
MSG msg;
return 0;
}
void CALLBACK readMousePosition(HWND hwnd, UINT uMsg, UINT timerId, DWORD dwTime)
{
GetCursorPos(&Point);
You can shut down the computer with the aid of the following code:
#include <stdio.h>
int main()
{
//see here: https://bit.ly/3vKnzlz
system("C:\\WINDOWS\\System32\\shutdown -s");
return 0;
}
Further Reading
8.1 Introduction
A pointer is a variable whose value is the address of another variable, i.e., direct
address of the memory location. Like any variable or constant, you must declare a
pointer before using it to store any variable address.
The general form of a pointer variable declaration is: type* var-name. Here, the
type is the pointer’s base type; it must be a valid C data type, and var-name is the
name of the pointer variable. The asterisk (*) used to declare a pointer is the same
asterisk used for multiplication. However, in this statement the asterisk is being
used to designate a variable as a pointer. Take a look at some of the valid pointer
declarations:
int* ip; /* pointer to an integer */
double* dp; /* pointer to a double */
float* fp; /* pointer to a float */
char* ch; /* pointer to a character */
Some C programming tasks are performed more easily with pointers, and other
tasks, such as dynamic memory allocation, cannot be performed without using
pointers. So, it becomes necessary to learn pointers to become a perfect C
programmer.
To access the address of a variable, we use the unary or address-of operator &
(ampersand) that returns the address of that variable. For example, &a gives us the
address of variable a. Following is an example. Sample output of this code is shown
© The Author(s), under exclusive license to Springer Nature Switzerland AG 2023 141
F. Asadi, Essentials of C Programming with Microsoft® Visual Studio®,
https://doi.org/10.1007/978-3-031-35711-4_8
142 8 Pointers
in Fig. 8.1 (you may receive a different output since the address of variables changes
from computer to computer).
#include <stdio.h>
int main()
{
int a = 42;
return 0;
}
8.3 Pointers
A pointer is a variable that stores the memory address of another variable as its
value. A pointer variable points to a data type (like int) of the same type, and is cre-
ated with the * operator. The address of the variable you are working with is assigned
to the pointer.
Following is an example. In this code, the address of variable a is saved in pointer
b. Sample output of this code is shown in Fig. 8.2 (you may receive a different
output since the address of variables changes from computer to computer).
#include <stdio.h>
int main()
{
int a = 42;
int* b;
b = &a;
printf("address of variable a is %p", b);
return 0;
}
It is a good idea to start the pointers name with a “ptr” to show that they are
pointer. Following is an example:
#include <stdio.h>
int main()
{
int a = 42;
int* ptrb;
ptrb = &a;
printf("address of variable a is %p", ptrb);
return 0;
}
To access the value stored in the address, we use the unary operator * that returns the
value of the variable located at the address specified by its operand. This is also called
dereferencing. Following is an example. Output of this code is shown in Fig. 8.3.
#include <stdio.h>
int main()
{
int a = 42;
int* b;
b = &a;
printf("value stored in pointer b is %d\n", *b);
return 0;
}
int main()
{
int a = 42;
int* b;
b = &a;
*b = 50;
printf("a=%d", a);
return 0;
}
144 8 Pointers
Let’s study another example. The following code studies the address of array
elements. Output of this code is shown in Fig. 8.5. Note that in C programming, the
name of the array is a pointer to the first element of the array, i.e., the element with
index 0.
#include <stdio.h>
int main()
{
int myArray[] = { 50,100,200 }; // myArray is a pointer to the
// first location of myArray.i.e. 50
printf("myArray=%zu\n", myArray);
//dereferencing
printf("\nvalue of myArray[0] is %zu\n", *myArray);
printf("value of myArray[1] is %zu\n", *(myArray + 1));
printf("value of myArray[2] is %zu\n", *(myArray + 2));
return 0;
}
8.5 Pointer Arithmetic
Note that when we increment or decrement the pointer, the pointer increases or
decreases a block of memory (block of memory depends on pointer data type).
Generally, people make mistakes when they calculate the next pointing address
of the pointer. Here is the technique to calculate the next pointing address of a
pointer when applying arithmetic operation on it. To understand this technique, let
us consider ptr is a pointer that has data type “T,” and “i” is the pointer offset.
address(ptr + i) = address(ptr) + (sizeof(T) * i);
address(ptr - i) = address(ptr) - (sizeof(T) * i);
int main()
{
int array[] = { 0,1,2,3,4 }; //remember that int takes 4 Bytes.
return 0;
}
146 8 Pointers
8.6 Call by Reference
The call by reference (or more exactly call by pointer) method of passing arguments
to a function copies the reference (address) of an argument into the formal param-
eter. Inside the function, the reference is used to access the actual argument used in
the call. This means that changes made to the parameter affect the passed argument.
Let’s study some examples. Consider the following code. Output of this code is
shown in Fig. 8.7. In this code, the address of variables a and b (remember that &
returns the address of variables) are passed to the scanf function. Therefore, scanf
function used call by reference.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a;
int b;
printf("please enter 2 numbers:");
scanf("%d %d", &a, &b);
printf("sum: %d", a+b);
return 0;
}
8.6 Call by Reference 147
The swap function in the following code takes the address of variables a and b
and swaps their values. Sample output of this code is shown in Fig. 8.8.
#include <stdio.h>
int main()
{
int x = 50;
int y = 60;
printf("before swap");
printf("value of x is: %d\n", x);
printf("value of x is: %d\n", y);
swap(&x, &y);
printf("\nafter swap");
printf("value of x is: %d\n", x);
printf("value of x is: %d\n", y);
return 0;
}
8.7 malloc Function
The malloc function (defined in stdlib.h header file) allocates the requested memory
and returns a pointer to it.
Following is an example. This code asks the user to enter a length and makes an
array with the length equal to what the user entered. Sample output of this code is
shown in Fig. 8.9.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptra;
int N = 0;
return 0;
}
8.8 NULL Pointer
int main()
{
int* ptr=NULL;
return 0;
}
int main()
{
int* ptr=NULL;
printf("ptr: %p\n", ptr);
if (ptr != NULL)
printf("*ptr: %d", *ptr);
return 0;
}
Some functions (for instance, malloc) return the NULL pointer to show that an error
occurred. Let’s study an example. Consider the following code. Output of this code is
shown in Fig. 8.11. In this code, we used the malloc function to request 1015 blocks
(each block has 4 bytes length) to save integer data. Output of malloc function (ptr) is
checked to see whether it is NULL. The memory is not assigned when ptr is NULL.
150 8 Pointers
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptr;
ptr = malloc(sizeof(int)*1000000000000000);
if (ptr != NULL)
{
printf("No error occured.");
}
else {
printf("Error: ptr is NULL!\n");
}
free(ptr);
return 0;
}
If you request a small amount of memory, then ptr will not be NULL. Following
is an example. Output of this code is shown in Fig. 8.12.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptr;
ptr = malloc(sizeof(int) * 10);
if (ptr != NULL)
{
printf("No error occured.");
}
else {
printf("Error: ptr is NULL!\n");
}
free(ptr);
return 0;
}
Let’s see what happens to the pointer (generated by the malloc function) after
calling the free function. Consider the following code. Output of this code is shown
in Fig. 8.13. According to Fig. 8.13, the pointer still points to the assigned mem-
ory block.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptr;
ptr = malloc(sizeof(int) * 10);
if (ptr != NULL)
{
printf("No error occured.\n");
printf("value of ptr=%d in the beginning of the code.\n", ptr);
}
else {
printf("Error: ptr is NULL!\n");
}
free(ptr);
printf("value of ptr=%d after running the free function.\n", ptr);
return 0;
}
In the following code, the NULL is assigned to the ptr pointer after calling the
free function. Output of this code is shown in Fig. 8.14.
152 8 Pointers
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptr;
ptr = malloc(sizeof(int) * 10);
if (ptr != NULL)
{
printf("No error occured.\n");
printf("value of ptr=%d in the beginning of the code.\n", ptr);
}
else {
printf("Error: ptr is NULL!\n");
}
free(ptr);
ptr = NULL;
printf("value of ptr=%d after running the free function.\n", ptr);
return 0;
}
8.9 void Pointer
A void pointer is a pointer that has no associated data type with it. A void pointer
can hold the address of any type and can be type casted to any type.
Functions like malloc and calloc return void* type and this allows these func-
tions to be used to allocate memory of any data type (just because of void*). Void
pointers are used to implement generic functions as well. For instance, prototype of
memcmp is int memcmp (const void* str1, const void* str2, size_t n). Therefore,
memcmp can work with int*, double*, char*, … .
Let’s study an example. In the following code, a void pointer is defined and took
the address of an integer and a character variable. Output of this code is shown in
Fig. 8.15.
Further Reading 153
#include <stdio.h>
int main() {
int a=10;
char b = 'x';
ptr = &b;
printf("ptr= &b = %p\n",ptr);
return(0);
}
Void pointers cannot be dereferenced. For example, the following program does
not compile.
#include <stdio.h>
int main()
{
int a = 10;
void* ptr = &a;
printf("%d", *ptr);
return 0;
}
Further Reading
1. Deitel P, Deitel H (2022) C How to program: with case studies in applications and systems
programming, 9th edn. Pearson, Boston
Chapter 9
Structures and Unions
9.1 Introduction
Structures are a way to group several related variables into one place. Each variable
in the structure is known as a member of the structure. Unlike an array, a structure
can contain many different data types (int, float, char, etc.). This chapter studies the
structures and unions and their applications in C programming.
9.2 Defining a Structure
You can create a structure by using the struct keyword and declare each of its mem-
bers inside curly braces. Let’s study an example. In the following code, Student
structure is defined and a structure variable of Student called s1 is created. Note that
to access members of a structure, use the dot syntax. Output of this code is shown
in Fig. 9.1.
© The Author(s), under exclusive license to Springer Nature Switzerland AG 2023 155
F. Asadi, Essentials of C Programming with Microsoft® Visual Studio®,
https://doi.org/10.1007/978-3-031-35711-4_9
156 9 Structures and Unions
#include<stdio.h>
#include<string.h>
struct Student
{
char name[50];
char id[10];
int age;
int grades[5];
};
int main()
{
struct Student s1;
strcpy(s1.name, "John");
strcpy(s1.id, "231708457");
s1.age = 18;
s1.grades[0] = 70;
s1.grades[1] = 63;
s1.grades[2] = 40;
s1.grades[3] = 90;
s1.grades[4] = 86;
You can initialize a structure in the following way as well. Output of this code is
shown in Fig. 9.2.
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
typedef struct
{
char name[50];
char id[10];
int age;
int grades[5];
} student;
int main()
{
student s1 = { "John", "231708457", 18, {70,63,40,90,86} };
9.3 typedef Keyword
The typedef keyword allows the user to provide alternative name for the primitive
(e.g.,int) and user-defined(e.g., struct) data types. This keyword adds a new name
to some existing data type but does not create a new type. Using typedef struct
results in a cleaner, more readable code, and saves the programmer keystrokes.
Let’s study an example. In the following code, the keyword struct is removed
when structure s1 is created (compare this code with the previous ones). Output of
this code is shown in Fig. 9.3.
#include<stdio.h>
#include<string.h>
typedef struct
{
char name[50];
char id[10];
int age;
int grades[5];
} student;
int main()
{
student s1;
strcpy(s1.name, "John");
strcpy(s1.id, "231708457");
s1.age = 18;
s1.grades[0] = 70;
s1.grades[1] = 63;
s1.grades[2] = 40;
s1.grades[3] = 90;
s1.grades[4] = 86;
You can copy the content of a structure into another structure with the aid of equal-
ity operator. In the following code, two struct variables are defined with two differ-
ent values. After calling s2=s1, content of s1 is copied into s2. Output of this code
is shown in Fig. 9.4.
#include<stdio.h>
#include<string.h>
typedef struct
{
char name[50];
char id[10];
int age;
int grades[5];
} student;
int main()
{
student s1, s2;
strcpy(s1.name, "John");
strcpy(s1.id, "231708457");
s1.age = 18;
s1.grades[0] = 70;
s1.grades[1] = 63;
s1.grades[2] = 40;
s1.grades[3] = 90;
s1.grades[4] = 86;
strcpy(s2.name, "Mary");
strcpy(s2.id, "231708458");
s2.age = 18;
s2.grades[0] = 30;
s2.grades[1] = 70;
s2.grades[2] = 75;
s2.grades[3] = 50;
s2.grades[4] = 95;
s2 = s1;
return 0;
}
9.5 Functions with Structure Arguments 159
Functions can take structure variables as argument. For instance, in the following
code, print_student function takes a structure variable and prints its contents.
Output of this code is shown in Fig. 9.5.
160 9 Structures and Unions
#include<stdio.h>
#include<string.h>
typedef struct
{
char name[50];
char id[10];
int age;
int grades[5];
} student;
int main()
{
student s1;
strcpy(s1.name, "John");
strcpy(s1.id, "231708457");
s1.age = 18;
s1.grades[0] = 70;
s1.grades[1] = 63;
s1.grades[2] = 40;
s1.grades[3] = 90;
s1.grades[4] = 86;
print_student(s1);
return 0;
}
void print_student(student s)
{
printf("name= %s\n", s.name);
printf("id= %s\n", s.id);
printf("age= %d\n", s.age);
printf("grades[0]= %d\n", s.grades[0]);
printf("grades[1]= %d\n", s.grades[1]);
printf("grades[2]= %d\n", s.grades[2]);
printf("grades[3]= %d\n", s.grades[3]);
printf("grades[4]= %d\n", s.grades[4]);
}
9.6 Array of Structures
You can define an array of structures. In the following code, an array of structures is
defined. Output of this code is shown in Fig. 9.6.
#include<stdio.h>
#include<string.h>
typedef struct
{
char name[50];
char id[10];
int age;
int grades[5];
} student;
int main()
{
student s[2];
strcpy(s[0].name, "John");
strcpy(s[0].id, "231708457");
s[0].age = 18;
s[0].grades[0] = 70;
s[0].grades[1] = 63;
s[0].grades[2] = 40;
s[0].grades[3] = 90;
s[0].grades[4] = 86;
strcpy(s[1].name, "Mary");
strcpy(s[1].id, "231708458");
s[1].age = 18;
s[1].grades[0] = 30;
s[1].grades[1] = 70;
s[1].grades[2] = 75;
s[1].grades[3] = 50;
s[1].grades[4] = 95;
return 0;
}
162 9 Structures and Unions
You can define functions which get an array of structures as argument. The
print_student in the following code prints the contents of each structure vari-
able. Output of this code is shown in Fig. 9.7.
9.6 Array of Structures 163
#include<stdio.h>
#include<string.h>
typedef struct
{
char name[50];
char id[10];
int age;
int grades[5];
} student;
int main()
{
student s[2];
strcpy(s[0].name, "John");
strcpy(s[0].id, "231708457");
s[0].age = 18;
s[0].grades[0] = 70;
s[0].grades[1] = 63;
s[0].grades[2] = 40;
s[0].grades[3] = 90;
s[0].grades[4] = 86;
strcpy(s[1].name, "Mary");
strcpy(s[1].id, "231708458");
s[1].age = 18;
s[1].grades[0] = 30;
s[1].grades[1] = 70;
s[1].grades[2] = 75;
s[1].grades[3] = 50;
s[1].grades[4] = 95;
return 0;
}
9.7 Arrow Operator
The dot (.) operator is used to normally access members of a structure (or union).
The arrow (->) operator is used to access the members of the structure (or union)
using pointers. In the following code, values stored in structure variable s1 are
manipulated with the aid of s2 pointer. Output of this code is shown in Fig. 9.8.
9.7 Arrow Operator 165
#include<stdio.h>
#include<string.h>
typedef struct
{
char name[50];
char id[10];
int age;
int grades[5];
} student;
int main()
{
student s1;
strcpy(s1.name, "John");
strcpy(s1.id, "231708457");
s1.age = 18;
s1.grades[0] = 70;
s1.grades[1] = 63;
s1.grades[2] = 40;
s1.grades[3] = 90;
s1.grades[4] = 86;
student* s2;
s2 = &s1;
strcpy(s2->name, "David");
strcpy(s2->id, "231708480");
s2->age = 19;
s2->grades[0] = 0;
return 0;
}
In the following code, arrow operator is used to access the variables in the pointer
s3. Output of this code is shown in Fig. 9.9. Note that this code uses the dynamic
memory allocation (see Sect. 8.7 in Chap. 8) to assign a value to pointer s3.
#include<stdio.h>
#include<string.h>
typedef struct
{
char name[50];
char id[10];
int age;
int grades[5];
} student;
int main()
{
student* s3;
s3 = malloc(sizeof(student)); //allocates memory for one student struct variable
strcpy(s3->name, "Lisa");
strcpy(s3->id, "231708488");
s3->age = 18;
s3->grades[0] = 85;
s3->grades[1] = 90;
s3->grades[2] = 70;
s3->grades[3] = 70;
s3->grades[4] = 85;
return 0;
}
The previous code can be written as follows as well. Output of this code is shown
in Fig. 9.10.
#include<stdio.h>
#include<string.h>
typedef struct
{
char name[50];
char id[10];
int age;
int grades[5];
} student;
int main()
{
student* s3;
s3 = malloc(1*sizeof(student)); //allocates memory for one student struct variable
strcpy((*s3).name, "Lisa"); //parantheses are necessary. Don’t write *s3.name
strcpy((*s3).id, "231708488");
(*s3).age = 18;
(*s3).grades[0] = 85;
(*s3).grades[1] = 90;
(*s3).grades[2] = 70;
(*s3).grades[3] = 70;
(*s3).grades[4] = 85;
return 0;
}
9.9 Unions
A union is a user-defined type similar to structures except for one key difference.
Structures allocate enough space to store all their members, whereas unions can
only hold one-member value at a time.
Let’s study an example. In the following code, a union with three data types: int,
double, and a character array with 32 elements is defined. Integer requires 4 bytes,
double requires 8 bytes and a character array with 32 elements requires 32 bytes.
The union will take max(4, 8, 32)=32 bytes. Output of the following code is shown
in Fig. 9.11. Note that values shown for x and y are wrong but value of z is shown
correctly. The reason is that character data is the last data written to the union and a
union always store the last data written to it.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
union Data
{
int x;
double y;
char z[32];
};
int main()
{
union Data mydata;
mydata.x = 10;
mydata.y = 20.5;
strcpy(mydata.z, "test 123");
printf("mydata.x=%d\n", mydata.x);
printf("mydata.y=%f\n", mydata.y);
printf("mydata.z=%s\n\n", mydata.z);
return 0;
}
Let’s change the previous code to what is shown below. Output of this code is
shown in Fig. 9.12. This time, the value of y is shown correctly since y is the last
variable written to the union.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
union Data
{
int x;
double y;
char z[32];
};
int main()
{
union Data mydata;
strcpy(mydata.z, "test 123");
mydata.x = 10;
mydata.y = 20.5;
printf("mydata.x=%d\n", mydata.x);
printf("mydata.y=%f\n", mydata.y);
printf("mydata.z=%s\n\n", mydata.z);
return 0;
}
9.10 Pointer to a Union
Similar to structures, you can use the arrow operator to access the data of a pointer
to a union. Following is an example. Output of this code is shown in Fig. 9.13.
170 9 Structures and Unions
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
union Data
{
int x;
double y;
char z[32];
};
int main()
{
union Data mydata;
strcpy(mydata.z, "test 123");
return 0;
}
Further Reading
1. Deitel P, Deitel H (2022) C how to program: with case studies in applications and systems
programming, 9th edn. Pearson, London
Chapter 10
Mathematical Functions
10.1 Introduction
10.2 Precedence of Operators
© The Author(s), under exclusive license to Springer Nature Switzerland AG 2023 171
F. Asadi, Essentials of C Programming with Microsoft® Visual Studio®,
https://doi.org/10.1007/978-3-031-35711-4_10
172 10 Mathematical Functions
Let’s study an example. In the following code, multiplication is done first, then
division, subtraction, and addition are done. Output of this code is shown in
Fig. 10.1.
#include <stdio.h>
int main()
{
int n = 1 - 5 + 3 * 4 / 2;
printf("%d",n);
return 0;
}
10.2 Precedence of Operators 173
In the following code, addition is done first, then multiplication and division are
done. Output of this code is shown in Fig. 10.2.
#include <stdio.h>
int main()
{
int n = 1 - (5 + 3) * 4 / 2;
printf("%d",n);
return 0;
}
int main()
{
printf("15%%4+6*2=%d\n", 15 % 4 + 6 * 2);
printf("15%%4*6+2=%d\n", 15 % 4 * 6 + 2);
return 0;
}
10.3 Remainder of Division
The modulo operator % computes the remainder of integer division. For instance,
9%4 returns 1 since 9 = 4 × 2 + 1. In the following code, modulo operator is used to
calculate the greatest common divisor of two numbers. Output of this code is shown
in Fig. 10.4.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#include <stdio.h>
int main()
{
int n1, n2, i, gcd;
return 0;
}
int main()
{
// 12.4 / 2.3 = 5.3913
// 12.4 - ( 2.3 * [5.3913] ) = 12.4 - (2.3*5) = 12.4 - 11.5 = 0.9
return 0;
}
10.4 sizeof Operator 175
10.4 sizeof Operator
int main(){
float x=1.2;
int s1 = sizeof(x);
int s2 = sizeof(double);
int s3 = sizeof(int);
printf("sizeof(x)=%d Bytes\n",s1);
printf("sizeof(double)= %d Bytes\n", s2);
printf("sizeof(int) = %d Bytes\n", s3);
return 0;
}
In the following code, sizeof operator is used to calculate the number of elements
in an array. Output of this code is shown in Fig. 10.7.
#include <stdio.h>
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
printf("Number of elements:%lu ", sizeof(arr)/sizeof(arr[0]));
return 0;
}
176 10 Mathematical Functions
The sizeof operator is used in dynamic memory allocation as well. For instance,
int* ptr = (int*)malloc(10 * sizeof(int)); allocates a memory block on the heap to
save ten integers.
10.5 Type Casting
Converting one data type into another is known as type-conversion. Figure 10.8
helps you understand the nature of data conversion. For instance, when 5.8 (a float
value) is converted to integer, its value will be 5. Therefore, we lose 0.8 in this
conversion.
Let’s study some examples. Consider the following code. In this code, variable a
is automatically converted into an integer by using the ASCII code of character 5
(when compiler sees int+char, it converts the lower data type, i.e., char, to a higher
one, i.e., int; thus, operation is converted to int+int). Output of this code is shown in
Fig. 10.9.
#include <stdio.h>
int main()
{
char a = '5';
int b = 9;
int result = a + b; //ASCII of '5' id 53.
printf("result= %d", result);
return 0;
}
int main()
{
double a = 5.8;
int b = 9;
int result = a + b; //result=5.8+9.0=14.8-->14
printf("result= %d", result);
return 0;
}
In the following code, the variable result is double. Output of this code is shown
in Fig. 10.11. Output shows that integer variable b is converted to double automati-
cally and then a+b=5.8+9.0=14.8 is calculated.
#include <stdio.h>
int main()
{
double a = 5.8;
int b = 9;
double result = a + b; //result=5.8+9.0=14.8
printf("result= %f", result);
return 0;
}
int main()
{
int a = 5.67; //implicit type conversion
printf("a= %d", a);
return 0;
}
In the previous examples, data type conversions were done automatically. This
type of cast is called implicit cast.
The programmer can also force the code to do the conversion at the desired point
as well. This type of casts is called explicit cast. Let’s study an example of explicit
cast. Consider the following code.
10.5 Type Casting 179
#include <stdio.h>
int main()
{
int num1, num2, num3;
float average;
return 0;
}
In the previous code, three numbers are taken from the user and their average is
printed. Sample output of this code is shown in Fig. 10.13. Note that sum is an inte-
ger variable. The variable sum is divided by 3. Dividing an integer number by
another integer number leads to an integer number. Therefore, numbers after the
decimal point are not shown in Fig. 10.13.
Consider the following example where the cast operator causes the division of
one integer variable by another to be performed as a floating-point operation.
Sample output of this code is shown in Fig. 10.14. Note that digits after decimal
points are shown.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
// this is a sample code for type casting
#include <stdio.h>
int main()
{
int num1, num2, num3;
float average;
return 0;
}
180 10 Mathematical Functions
10.6 Mathematical Constants
Table 10.2 shows the mathematical constants available in Microsoft Visual Studio.
Let’s study some examples. The following code prints the values of Euler’s and
pi numbers. Output of this code is shown in Fig. 10.15.
#define _USE_MATH_DEFINES // This line must be added if you want to use the
// defined constants. Otherwise you will receive
// an error.
#include <stdio.h>
#include <math.h> // Mathematical functions are here.
int main() {
printf("Value of e=M_E=%f\n\n",M_E); // Prints the Euler’s number
printf("Value of pi=M_PI=%f\n\n",M_PI); // Prints the pi number
return 0;
}
10.7 Power Function 181
The following code calculates the area of a circle. Sample output of this code is
shown in Fig. 10.16.
#define _CRT_SECURE_NO_WARNINGS // put this line otherwise
// the scanf command doesn't work
#define _USE_MATH_DEFINES // This line must be added if you want to use the
// defined constants. Otherwise you will receive
// an error.
#include <stdio.h>
#include <math.h> // Mathematical functions are here.
int main() {
float r = 0.0;
return 0;
}
10.7 Power Function
int main() {
float x = 5.25;
printf("x^4.5=%.3f\n\n", pow(x,4.5));
printf("x^2=%.3f\n\n", pow(x,2));
return 0;
}
182 10 Mathematical Functions
The square root of a number can be calculated with the aid of sqrt function.
Following is an example. Output of this code is shown in Fig. 10.18.
#include <stdio.h>
#include <math.h>
int main()
{
// sqrtf takes float inputs and returns float values
// sqrtl takes long double inputs and returns long double values
// sqrt takes double inputs and returns double values
float x =2.0;
float result1 = sqrtf(x);
printf("sqrtf(x)=%f\n\n", result1);
double y = 2.0;
double result2 = sqrt(y);
printf("sqrt(y)=%f\n\n", result2);
return 0;
}
You can use the cbrt function to calculate the cubic root of a number. Following is
an example. Output of this code is shown in Fig. 10.19.
#include <stdio.h>
#include <math.h> // Mathematical functions are here.
int main() {
printf("cbrt(28)=%.3f\n", cbrt(28));
return 0;
}
10.10 Logarithm Function
You can use the log and log10 functions to calculate the natural logarithm (ln) and
decimal logarithm, respectively. Following is an example. Output of this code is
shown in Fig. 10.20.
#include <stdio.h>
#include <math.h> // Mathematical functions are here.
int main() {
float x = 5.25;
printf("ln(x)=%.3f\n\n", log(x));
printf("log10(x)=%.3f\n\n", log10(x));
return 0;
}
10.11 Trigonometric Functions
Trigonometric functions can be calculated with the aid of sin, cos, and tan functions.
Cotangent is calculated with the aid of tan function (remember that tan(x).cot(x)=1).
Following is an example. Output of this code is shown in Fig. 10.21.
#define _USE_MATH_DEFINES // This line must be added if you want to use the
// defined constants. Otherwise you will receive
// an error.
#include <stdio.h>
#include <math.h> // Mathematical functions are here.
int main() {
float x = M_PI/3; // x is in Radyans
printf("sin(x)=%.3f\n\n", sin(x));
printf("cos(x)=%.3f\n\n", cos(x));
printf("tan(x)=%.3f\n\n", tan(x));
printf("cot(x)=%.3f\n\n", 1/tan(x));
return 0;
}
Inverse of trigonometric functions can be calculated with the aid of asin, acos, and
atan functions. Arc cotangent can be calculated with the aid of atan function. Note
that the outputs of these functions are in Radians.
Following is an example. The two methods for calculation of arc cotangent are
shown below. Output of this code is shown in Fig. 10.22.
10.13 Hyperbolic Functions 185
#define _USE_MATH_DEFINES // This line must be added if you want to use the
// defined constants. Otherwise you will receive
// an error.
#include <stdio.h>
#include <math.h> // Mathematical functions are here.
int main() {
float x = 0.8;
printf("asin(x)=%.3f\n\n", asin(x));
printf("acos(x)=%.3f\n\n", acos(x));
printf("atan(x)=%.3f\n\n", atan(x));
//two methods to calculate arccot:
printf("acot(x)=%.3f\n\n", atan(1/x)); // remember acot(x)=atan(1/x)
printf("acot(x)=%.3f\n\n", M_PI_2-atan(x)); // remember acot(x)+atan(x)=pi/2
return 0;
}
10.13 Hyperbolic Functions
Hyperbolic functions can be calculated with the aid of sinh, cosh, and tanh func-
tions. Hyperbolic cotangent is calculated with the aid of tanh function.
Following is a sample code. Output of this code is shown in Fig. 10.23.
#define _USE_MATH_DEFINES // This line must be added if you want to use the
// defined constants. Otherwise you will receive
// an error.
#include <stdio.h>
#include <math.h> // Mathematical functions are here.
int main() {
float x = 0.8;
printf("sinh(x)=%.3f\n\n", sinh(x));
printf("cosh(x)=%.3f\n\n", cosh(x));
printf("tanh(x)=%.3f\n\n", tanh(x));
printf("coth(x)=%.3f\n\n", 1/tanh(x));
return 0;
}
186 10 Mathematical Functions
Inverse of hyperbolic functions can be calculated with the aid of asinh, acosh, and
atanh functions. Inverse hyperbolic cotangent can be calculated with the aid of
1 x 1
acoth x ln formula.
2 x 1
Following is a sample code. Output of this code is shown in Fig. 10.24.
#define _USE_MATH_DEFINES // This line must be added if you want to use the
// defined constants. Otherwise you will receive
// an error.
#include <stdio.h>
#include <math.h> // Mathematical functions are here.
int main() {
float x = 1.8;
printf("asinh(x)=%.3f\n\n", asinh(x));
printf("acosh(x)=%.3f\n\n", acosh(x));
printf("atanh(x)=%.3f\n\n", atanh(x));
printf("acoth(x)=%.3f\n\n", 0.5*log((x+1)/(x-1)));
return 0;
}
10.15 Exponential Function
The exp function computes e (2.71828) raised to the power of the given argument.
Following is a sample code. Output of this code is shown in Fig. 10.25.
#include <stdio.h>
#include <math.h>
int main()
{
float x = 2;
float y = exp(x);
printf("exp(%.2f)=%.2f", x, y);
return 0;
}
Round function returns the nearest integer value of the float/double/long double argu-
ment passed to this function. If the decimal value is from ".1 to .5", it returns an inte-
ger value which is less than the argument we passed, and if the decimal value is from
".6 to .9", the function returns an integer value greater than the argument we passed.
In short the round function returns an integer value nearest to the argument we passed.
The trunc function allows to truncate (remove) the decimal value from a floating
number and return an integer value.
Following is an example. Output of this code is shown in Fig. 10.26.
#include <stdio.h>
#include <math.h>
int main()
{
double x = 6.5;
printf("round(%.2f) = %.2f\n", x, round(x)); //returns the nearest integer value
//(rounded value) of the given
float,
//integer, or double number based
on
//the decimal part of the number
The floor function calculates the nearest integer less than or equal to the argument
passed. The ceil function computes the nearest integer greater than the argu-
ment passed.
Following is an example. Output of this code is shown in Fig. 10.27.
#include <stdio.h>
#include <math.h> // Mathematical functions are here.
int main() {
printf("floor(+3.6)=%f\n\n", floor(3.6));
printf("floor(-3.6)=%f\n\n", floor(-3.6));
printf("ceil(3.6)=%f\n\n", ceil(3.6));
printf("ceil(-3.6)=%f\n\n", ceil(-3.6));
return 0;
}
The fabs function returns the absolute value of a number. The hypotenuse is the
longest side of a right-angled triangle. The hypot function is used to find hypotenuse
when other two sides are provided ( hypot x,y x 2 y 2 ).
Following is an example. Output of this example is shown in Fig. 10.28.
#include <stdio.h>
#include <math.h> // Mathematical functions are here.
int main() {
printf("fabs(+3.6)=%.3f\n\n", fabs(3.6));
printf("fabs(-3.6)=%.3f\n\n", fabs(-3.6));
printf("hypot(3,4)=%.3f\n\n", hypot(3,4));
return 0;
}
The function rand is used to generate pseudo random numbers. It returns an integer
value and its range is from 0 to RAND_MAX, i.e., 32767. The function srand does
not return anything and is used to initialize the generated pseudo random number by
rand function. If random numbers are generated with rand without first calling
srand, your program will create the same sequence of numbers each time it runs
(Fig. 10.29). The rand and srand functions are defined in cstdlib.h header file.
Let’s study some examples. The following code prints the maximum value that
may be generated by the rand function. Output of this code is shown in Fig. 10.30.
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%d", RAND_MAX);
return 0;
}
The following code generates ten random values from 1 to 6. Output of this code
is shown in Fig. 10.31.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(time(NULL)); //random generator is feed with current time
int randomNumber = 0;
printf("Generated Random Numbers:\n");
for (int i=0;i<10;i++)
{
randomNumber = rand() % 6 + 1; // rand()%6 gives a random integer number
from 0 to 5.
printf("%d\n", randomNumber);
}
return 0;
}
The following code generates ten random values from 20 to 100. Output of this
code is shown in Fig. 10.32.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(time(NULL)); //random generator is feed with current time
int randomNumber = 0;
int ub = 100;
int lb = 20;
The rand_s function in Visual Studio is the secure version of rand function. The
following example shows how to use the rand_s function to generate a random inte-
ger value from 1 to 6. Sample output of this code is shown in Fig. 10.33. There is no
need to call the srand function when you use the rand_s function since the algorithm
used by rand_s is not the same as the algorithm used by the rand function.
192 10 Mathematical Functions
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main() {
unsigned int number;
return 0;
}
int main() {
printf("UINT_MAX= %u\n", UINT_MAX);
return 0;
}
The following code generates a random double value from [1, 6] interval. Note
that the output of following code is not an integer number, it is a double value.
Sample output of this code is shown in Fig. 10.35.
10.19 Generation of Random Numbers 193
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main() {
//following three line generates a random double number in the
// [1,maximum] range and save it in number variable
return 0;
}
The following code takes an array and fills it with random integers. Sample out-
put for this code is shown in Fig. 10.36.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
int main()
{
srand(time(NULL)*getpid());
int a[10];
generateRandomVector(a, sizeof(a) / sizeof(a[0]), 1, 50);
The following code introduces some of the functions that help you see whether a
floating-point number is finite or infinite. Output of this code is shown in Fig. 10.37.
//isnan returns a non-zero value if x is a NaN value; and 0 otherwise
//signbit return 1 for negative values and 0 for others
#include <stdio.h>
#include <math.h>
#include <float.h>
int main()
{
printf("Minimum normalized positive value: %e. \n", FLT_MIN);
printf("Maximum normalized positive value: %e. \n", FLT_MAX);
float not_a_number = d / b;
if (isnan(not_a_number))
printf("%f is not a number.\n", not_a_number);
return 0;
}
The following code introduces the fpclassify function. The fpclassify returns a
value of type int that matches one of the classification macro constants shown in
Table 10.3.
The following simple code takes three floating point numbers from the user and
classifies them. Sample output of this code is code is shown in Fig. 10.38.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>
#include <float.h>
int main()
{
float a;
case FP_NAN:
printf("%f is not a number (NaN=0/0)\n\n", a);
break;
case FP_NORMAL:
printf("%f is normal\n\n", a);
break;
}
}
return 0;
}
196 10 Mathematical Functions
10.21 Complex Functions
The complex library permits you to do calculation with complex numbers. Following
code is an example. Output of this code is shown in Fig. 10.39.
10.21 Complex Functions 197
#include <stdio.h>
#include <complex.h>
int main()
{
//list of complex.h functions are given here:https://bit.ly/3IqxKnf
//use the _Dcomplex for double complex numbers.
//use the _Fcomplex for float complex numbers.
//use the _Lcomplex for long double complex numbers.
_Dcomplex C1 = { 1 , 2 }; //C1=1+2i
_Dcomplex C2 = { 3 , 4 }; //C2=3+4i
_Dcomplex C5 = csin(C1);
_Dcomplex C6 = ccos(C1);
_Dcomplex C7 = ctan(C1);
_Dcomplex C8 = cexp(C1);
_Dcomplex C9 = cpow(C1,C2); //C9=C1^C2
_Dcomplex C10 = csqrt(C1);
_Dcomplex C11 = casin(C1);
_Dcomplex C12 = cacos(C1);
_Dcomplex C13 = catan(C1);
return 0;
}
198 10 Mathematical Functions
int main()
{
int a = 0b101; //a=101 in binary which equals to 5 in decimal
int b = 0xFE5; //b=0xFE5 in hexadeciimal which equals to 4069 in decimal
10.23 Bitwise Operation
int main()
{
int a = 0b00111011;
int b = 0b00101110;
printf("a=%d\n", a);
printf("b=%d\n", b);
return 0;
}
200 10 Mathematical Functions
The following is a sample code for shift operator. Output of this code is shown in
Fig. 10.42.
#include <stdio.h>
int main()
{
//apply bitwise shift operations to int and char types only.
int a = 7; //a=00000000 00000000 00000000 00000111 in binary
//simply take a=111
printf("a=7\n");
printf("a>>2=%d\n", a >> 2); // expected value is a>>2=1 or 1 in decimal
printf("a<<2=%d\n", a << 2); // expected value is a<<2=11100 or 28 in decimal
return 0;
}
The GNU Scientific Library (GSL) is a numerical library for C and C++ program-
mers. It is a free software under the GNU General Public License.
The library provides a wide range of mathematical routines such as random num-
ber generators, special functions, and least-squares fitting. There are over 1000
functions in total with an extensive test suite.
Further Readings 201
#include <stdio.h>
#include <gsl/gsl_linalg.h>
main(void)
{
int n = 3;
gsl_vector* x = gsl_vector_alloc(n);
gsl_permutation* perm = gsl_permutation_alloc(n);
int signum;
gsl_linalg_LU_decomp(&A.matrix, perm, &signum);
gsl_linalg_LU_solve(&A.matrix, perm, &b.vector, x);
printf("solution is:\n");
gsl_vector_fprintf(stdout, x, "%lf");
return 0;
}
Further Readings
1. Deitel P, Deitel H (2022) C how to program: with case studies in applications and systems
programming, 9th edn. Pearson, London
2. https://bit.ly/2u8ywhE
3. https://bit.ly/3H7qprc
4. https://bit.ly/41R6DIc
Chapter 11
String Processing
11.1 Introduction
11.2 Defining a String
int main()
{
char str[5];
str[0] = 't';
str[1] = 'e';
str[2] = 's';
str[3] = 't';
str[4] = '\0'; //Non-printable char. \0 shows the end of string.
//Unused locations are filled with \0 as well.
printf("%s", str);
return 0;
}
© The Author(s), under exclusive license to Springer Nature Switzerland AG 2023 203
F. Asadi, Essentials of C Programming with Microsoft® Visual Studio®,
https://doi.org/10.1007/978-3-031-35711-4_11
204 11 String Processing
int main()
{
char str[5]="test";
printf("%s", str);
return 0;
}
You do not need to write the size of character array as well. Therefore, the previ-
ous code can be simplified to:
#include <stdio.h>
int main()
{
char str[]="test";
printf("%s", str);
return 0;
}
11.3 String Inputs
The scanf function can be used to take a string from the user. The character array
which stores the user string must be defined big enough to store the worst case, i.e.,
the longest string.
Let’s study an example. In the following code, a character array with length of
100 is defined to store the user string. The scanf with %s is used to read the user
string. When you use the scanf function with %s, it returns the string up to the first
white space. Sample output of this code is shown in Fig. 11.2.
11.3 String Inputs 205
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
char buffer[100];
return 0;
}
According to Fig. 11.2, the section after white space, i.e., World, is not copied
into the buffer. To read a whole line, you need to use %[^\n]%*c with the scanf
function. The following code reads the whole line entered by the user. Sample out-
put of this code is shown in Fig. 11.3.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
char buffer[100];
return 0;
}
There is another way to read the whole line as well: using the fgets function. The
following code shows this method. Sample output of this code is shown in Fig. 11.4.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
char buffer[100];
11.4 strlen Function
The strlen is defined in the string.h header file and returns the length of a string.
Note that the strlen function does not count the “\0” character at the end of the
strings.
Let’s study an example. In the following code, strlen is used to obtain the length
of a string. Then a for loop is used to count the number of letter o in the test string.
Output of this code is shown in Fig. 11.5.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char test[]="Hello World!";
int numberOfO = 0;
for (int i = 0; i < length; i++)
{
if (test[i] == 'o' || test[i] == 'O') numberOfO++;
}
printf("\nnumber of o in the string: %d", numberOfO);
return 0;
}
11.6 strncpy Function 207
11.5 strcpy Function
The strcpy is defined in the string.h header file and copies one string into another
string. When you use strcpy(), the size of the destination string should be large
enough to store the copied string. Otherwise, it may result in undefined behavior.
Prototype of this function is char* strcpy(char* destination, const char* source).
Let’s study an example. The following code copies the source string into the
destination string. Output of this code is shown in Fig. 11.6.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char source[]="Hello World!";
char destination[50];
strcpy(destination, source);
printf("%s\n", destination);
return 0;
}
11.6 strncpy Function
The strncpy is defined in the string.h header. The prototype of this function is char*
strncpy(char* dest, const char* src, size_t n) and it copies up to n characters from
the string pointed to, by src to dest. In a case where the length of src is less than that
of n, the remainder of dest will be padded with null bytes.
Let’s study an example. The following code copies the first five characters of
source string into the destination array. Output of this code is shown in Fig. 11.7.
208 11 String Processing
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char source[] = "Hello World!";
char destination[10];
memset(destination, '\0',sizeof(destination)); //fills the destination with '\0'
printf("%s\n", destination);
return 0;
}
11.7 memset Function
The memset function is defined in the string.h header file. The prototype of this
function is void* memset(void* str, int c, size_t n) and it copies the character c (an
unsigned char) to the first n characters of the string pointed to, by the argument str.
Let’s study an example. In the following code, two arrays are initialized with the
aid of memset function. Output of this code is shown in Fig. 11.8.
#include <stdio.h>
#include <string.h>
int main()
{
int a[15];
char b[15];
memset(a, 0, sizeof(a));
memset(b, '$', sizeof(b));
printf("array a: ");
for (int i = 0; i < 15; i++)
printf("%d ", a[i]);
printf("\narray b: ");
for (int i = 0; i < 15; i++)
printf("%c ", b[i]);
return 0;
}
11.9 memmove Function 209
11.8 memcpy Function
The memcpy function is defined in the string.h header file. The prototype of this
function is void* memcpy(void* dest, const void* src, size_t n) and it copies n
characters from memory area src to memory area dest.
Let’s study an example. The following code copies the first five characters of
source array into the destination array. Output of this code is shown in Fig. 11.9.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char source[] = "Hello World!";
char destination[10];
memset(destination, '\0', sizeof(destination)); //fills the destination with '\0'
printf("%s\n", destination);
return 0;
}
11.9 memmove Function
The memmove function is defined in the string.h header file. The prototype of this
function is void* memmove(void* dest, const void* src, size_t n) and it copies n
characters from src array to dest array. The memmove do the same job as memcpy
function. However, with memcpy, the destination cannot overlap the source at all.
With memmove it can.
210 11 String Processing
Let’s study an example. In the following code, ten elements of source array are
copied into the destination array. Output of this code is shown in Fig. 11.10.
#include <stdio.h>
#include <string.h>
int main()
{
int source[10] = { 1,2,3,4,5,6,7,8,9,10 };
int destination[10];
memmove(destination, source, 10 * sizeof(int));
printf("destination array:\n");
for (int i = 0; i < 10; i++)
printf("%d ", destination[i]);
return 0;
}
Let’s study another example. In the following code, fourth, fifth, sixth… thir-
teenth elements of source array are copied into the destination array. Output of this
code is shown in Fig. 11.11.
#include <stdio.h>
#include <string.h>
int main()
{
int source[15] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
int destination[10];
memmove(destination, source + 3, 10 * sizeof(int));
printf("destination array:\n");
for (int i = 0; i < 10; i++)
printf("%d ", destination[i]);
return 0;
}
11.10 strcmp Function
The strcmp function is defined in the string.h header file and is used to compare two
strings together. The prototype of this function is int strcmp(const char* str1, const
char* str2). Table 11.1 summarizes the return value from the strcmp function.
Let’s study an example. In the following code, str1 and str2 strings are not equal.
Hence, the result is a non-zero integer (Fig. 11.12). str1 and str3 are equal. Hence,
the result is 0 (Fig. 11.12).
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "abcd", str2[] = "AbCd", str3[] = "abcd";
int result;
11.11 strncmp Function
The strncmp function is defined in the string.h header file. The prototype of this
function is int strncmp(const char* str1, const char* str2, size_t n) and it compares
at most the first n bytes of str1 and str2. Table 11.2 summarizes the return value
from the strncmp function.
Let’s study an example. In the following code, str1 and str2 strings are compared
to each other up to the five and seven characters. Output of this code is shown in
Fig. 11.13.
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "abcdeFghij", str2[] = "abcdefghij";
int result;
11.12 memcmp Function
The memcmp function is defined in the string.h header file. The prototype of this
function is int memcmp(const void* str1, const void* str2, size_t n) and it compares
the first n bytes of memory area str1 and str2.
Let’s study an example. In the following code, two strings are compared to the
other up to the fifth character. Output of this code is shown in Fig. 11.14.
#include <stdio.h>
#include <string.h>
int main() {
char str1[10] = "abcdefgh";
char str2[10] = "abcdeFgh";
int result;
if (result > 0) {
printf("str2 is less than str1");
}
else if (result < 0) {
printf("str1 is less than str2");
}
else {
printf("str1 is equal to str2");
}
return(0);
}
Let’s study another example. In the following code, two integer arrays are com-
pared to each other up to the fifth element. Output of this code is shown in Fig. 11.15.
214 11 String Processing
#include <stdio.h>
#include <string.h>
int main() {
int a[] = {0,1,2,3,4,5};
int b[] = {0,1,2,3,5,7};
int result;
if (result > 0) {
printf("b is less than a");
}
else if (result < 0) {
printf("a is less than b");
}
else {
printf("a is equal to b");
}
return(0);
}
11.13 strcat Function
The strcat function is defined in the string.h header file and concatenates (joins) two
strings. The prototype of this function is char* strcat(char* destination, const char*
source). The strcat() function concatenates the destination string and the source
string, and the result is stored in the destination string.
Let’s study an example. In the following code, three strings are concatenated
together. Output of this code is shown in Fig. 11.16.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char str1[30] = "Hello ", str2[] = "World", str3[] = "!";
strcat(str1, str2); //result is stored in str1
strcat(str1, str3); //result is stored in str1
printf("%s", str1);
return 0;
}
11.15 strtok Function 215
11.14 strncat Function
The strncat function is defined in the string.h header file. The prototype of this func-
tion is char* strncat(char *destination, const char *source, size_t n) and it appends
the string pointed to by source to the end of the string pointed to by destination up
to n characters long.
Let’s study an example. The following code adds the first three character of str2
to str1. Output of this code is shown in Fig. 11.17.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char str1[10] = "Hello ", str2[] = "World!!!";
strncat(str1, str2, 3); //result is stored in str1.
//only 3 characters of str2 are
//copied to str1.
printf("%s", str1);
return 0;
}
11.15 strtok Function
The strtok function is defined in the string.h header file. The prototype of this func-
tion is char* strtok(char* str, const char* delim) and it breaks string str into a series
of tokens using the delimiter delim.
Let’s study an example. In the following, strtok function is used with space
delimiter. Output of this code is shown in Fig. 11.18.
216 11 String Processing
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "Learnig C is fun."; // our string
char delim[] = " "; // space is the delimiter
return 0;
}
The following code do the same job as the previous code. However, this code
uses a while loop instead of calling strtok manually. Note that the strtok returns
NULL when no token (portion) remains. Output of this code is shown in Fig. 11.19.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "Learnig C is fun."; // our string
char delim[] = " "; // we entered the space as delimiter
return 0;
}
11.15 strtok Function 217
The strtok function parses the string up to the first instance of the delimiter char-
acter, replaces the character in place with “\0,” and returns the address of the first
character in the token. Subsequent calls to strtok begin parsing immediately after
the most recently placed null character. The following code shows what happens to
the string when strtok function is called. Output of this code is shown in Fig. 11.20.
218 11 String Processing
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "Learnig C is fun."; // our string
char delim[] = " "; // space is entered as delimiters
int n = strlen(str);
printf("original string:");
for (int i = 0; i <= n; i++)
{
if (str[i] == '\0')
printf("\\0");
else
printf("%c", str[i]);
}
11.16 strcspn Function
The strcspn is defined in the string.h header file. The prototype of this function is
size_t strcspn(const char* str1, const char* str2) and it calculates the length of the
initial segment of str1, which consists entirely of characters not in str2.
Let’s study an example. Assume that we have a serial number (label) which is
composed of an alphabetic section followed by a number. The following code
calculates the length of alphabetic section. Output of this code is shown in Fig. 11.21.
#include <stdio.h>
#include <string.h>
int main()
{
char string[] = "CZCASDETRY62580";
char num[] = "0123456789"; //order is not important
The following code extracts the numeric section of the label. Output of this code
is shown in Fig. 11.22.
#include <stdio.h>
#include <string.h>
int main()
{
char string[] = "CZCASDETRY62580";
char num[] = "0123456789"; //order is not important
return 0;
}
11.17 strspn Function
The strspn function is defined in the string.h header file. Prototype of this function
is size_t strspn(const char* str1, const char* str2) and it returns the number of
characters in the initial segment of str1 which consist only of characters from str2.
Let’s study an example. Assume that we have a serial number (label) which is
composed of an alphabetic section followed by a number. The following code
calculates the length of alphabetic section. Output of this code is shown in Fig. 11.23.
#include <stdio.h>
#include <string.h>
int main()
{
char string[] = "CZCASDETRY62580";
char letter[] = "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //order is not important
//2 "" are used to break the line
The following code extracts the numeric section of the label. Output of this code
is shown in Fig. 11.24.
#include <stdio.h>
#include <string.h>
int main()
{
char string[] = "CZCASDETRY62580";
char letter[] = "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //order is not important
//2 "" are used to break the line
return 0;
}
11.19 atof Function 221
11.18 atoi Function
The atoi function is defined in the string.h header file. The prototype of this function
is int atoi (const char* str) and it converts the string argument str to an integer (type
int). If no valid conversion could be performed, it returns zero.
Let’s study an example. In the following code, a number (in the form of a string)
is taken from the user, ten units are added to it, and the obtained result is printed on
the screen. Output of this code is shown in Fig. 11.25.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{
char str[10];
printf("please enter a number: ");
scanf("%s", str);
11.19 atof Function
The atof function is defined in the string.h header file. The prototype of this function
is double atof(const char* str) and it converts the string argument str to a floating-
point number (type double). If no valid conversion could be performed, it
returns zero.
222 11 String Processing
Let’s study an example. In the following code, a number (in the form of a string)
is taken from the user, ten units are added to it, and the obtained result is printed on
the screen. Output of this code is shown in Fig. 11.26.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char str[10];
printf("please enter a number: ");
scanf("%s", str);
float N = atof(str);
N = N + 10.0;
printf("Entered value +10 = %f\n", N);
return 0;
}
11.20 sscanf Function
The sscanf function is defined in the stdio.h header file. The prototype of this func-
tion is int sscanf (const char* str, const char* format, ...) and it reads data from str
and stores them according to parameter format into the locations given by the addi-
tional arguments, as if scanf was used, but reading from str instead of the standard
input (keyboard).
The sscanf function returns the number of variables filled on success. In the case
of an input failure before any data could be successfully read, EOF is returned.
Let’s study an example. The following code shows how to read integer and string
values with sscanf function. Output of this code is shown in Fig. 11.27.
11.20 sscanf Function 223
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int day, year;
char weekday[20], month[20], dtm[100];
return(0);
}
Let’s study another example. The following code shows how to read characters
and floating-point values with sscanf function. Output of this code is shown in
Fig. 11.28.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
float temp;
char sign, unit;
char todayTemp[20];
return(0);
}
11.21 sprintf Function
The sprintf function is defined in the stdio.h header file. The prototype of this func-
tion is int sprintf (char* str, const char* format, ...) and it sends formatted output to
a string pointed to by str.
The sprint returns the total number of characters written excluding the null-
character appended at the end of the string if successful. Otherwise a negative num-
ber is returned in case of failure.
Let’s study an example. The following code sends a formatted output to the buf-
fer array. Output of this code is shown in Fig. 11.29.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
char buffer[50];
int a = 10;
float b = 20.76, c;
c = a + b;
sprintf(buffer, "Sum of %d and %.2f is %.2f", a, b, c);
// The string "sum of 10 and 20 is 30" is stored
// into buffer instead of printing on screen
return 0;
}
11.22 strchr Function
The strchr function is defined in the string.h header file. The prototype of this func-
tion is char* strchr(const char* str, int c) and it searches for the first occurrence of
the character c (an unsigned char) in the string pointed by the argument str.
Let’s study an example. In the following code, strchr function searches a string
for “u” and “@.” Output of this code is shown in Fig. 11.30.
11.22 strchr Function 225
#include <stdio.h>
#include <string.h>
int main()
{
char string[] = "Computer";
char* result= strchr(string, 'u');
printf("%s\n", result);
if (strchr(string, '@') == NULL) //returns NULL when it doesn't find the character
printf("No such character exists!");
return 0;
}
Let’s study another example. In the following code, found “u” character is
replaced with a “*.” Output of this code is shown in Fig. 11.31.
#include <stdio.h>
#include <string.h>
int main()
{
char string[] = "Computer";
char* result = strchr(string, 'u');
result[0] = '*';
printf("\nOriginal string changed to: %s", string);
return 0;
}
226 11 String Processing
Further Reading
1. Deitel P, Deitel H (2022) C how to program: with case studies in applications and systems
programming, 9th edn. Pearson, London
Chapter 12
Character Processing
12.1 Introduction
12.2 isalnum Function
© The Author(s), under exclusive license to Springer Nature Switzerland AG 2023 227
F. Asadi, Essentials of C Programming with Microsoft® Visual Studio®,
https://doi.org/10.1007/978-3-031-35711-4_12
228 12 Character Processing
int main() {
char c;
printf("Please enter a character: ");
scanf("%c", &c);
if (isalnum(c)) {
printf("Entered character is an alpha numeric (a,...,z, A,...,Z, 0,...,9)
character.\n");
}
else {
printf("Entered character is NOT an alpha numeric (a,...,z, A,...,Z,
0,...,9) character.\n");
}
return 0;
}
12.3 isalpha Function
int main() {
char c;
printf("Please enter a character: ");
scanf("%c", &c);
if (isalpha(c)) {
printf("Entered character is an alphabet (a,...,z, A,...,Z)
character.\n");
}
else {
printf("Entered character is NOT an alpha numeric (a,...,z, A,...,Z)
character.\n");
}
return 0;
}
12.4 isdigit Function
This function checks whether the argument passed to it is a digit character or not.
The prototype of isdigit function is: int isdigit(int argument). The isdigit function
returns 0 if the argument is not a digit character and returns a non-zero value if the
argument is a digit character.
Let’s study an example. The following code takes a character from the user and
determines whether it is a digit character. Sample output of this code is shown in
Fig. 12.3.
230 12 Character Processing
int main() {
char c;
printf("Please enter a character: ");
scanf("%c", &c);
if (isdigit(c)) {
printf("Entered character is a numeric (0-9) character.\n");
}
else {
printf("Entered character is NOT a numeric (0-9) character.\n");
}
return 0;
}
12.5 iscntrl Function
Characters that cannot be printed on the screen are known as control characters. For
example, backspace, Escape, newline, etc. The iscntrl() function checks whether a
character (passed to the function) is a control character or not. The prototype of
iscntrl function is: int iscntrl(int argument). The iscntrl function returns 0 if the
argument is not a control character and returns a non-zero value if the argument is a
control character.
Let’s study an example. The following code prints the ASCII code of control
characters. Output of this code and ASCII codes are shown in Figs. 12.4 and 12.5,
respectively.
#include <stdio.h>
#include <ctype.h>
int main() {
for (int i = 0; i < 127; i++) {
if (iscntrl(i))
printf("%d\n", i);
}
return 0;
}
12.5 iscntrl Function 231
12.6 ispunct Function
int main() {
for (int i = 0; i < 127; i++) {
if (ispunct(i))
printf("%c\n", i);
}
return 0;
}
12.7 isspace Function
int main() {
char c1 = ' ';
char c2 = 'a';
printf("isspace(c1)=%d\n", isspace(c1));
printf("isspace(c2)=%d\n", isspace(c2));
return 0;
}
Let’s study another example. The following code prints the ASCII code of white-
space characters. Output of this code is shown in Fig. 12.8. ASCII codes are shown
in Fig. 12.9 as well.
#include <stdio.h>
#include <ctype.h>
int main() {
for (int i = 0; i < 127; i++) {
if (isspace(i))
printf("%d\n", i);
}
return 0;
}
12.8 islower Function
int main() {
char c;
printf("Please enter a character: ");
scanf("%c", &c);
if (isalpha(c)) {
if (islower(c)) {
printf("Entered character is a small letter.\n");
}
else {
printf("Entered character is a capital letter.\n");
}
}else {
printf("Entered character is NOT a letter.\n");
}
return 0;
}
12.9 isupper Function
int main() {
char c;
printf("Please enter a character: ");
scanf("%c", &c);
if (isalpha(c)) {
if (isupper(c)) {
printf("Entered character is a capital letter.\n");
}
else {
printf("Entered character is a small letter.\n");
}
}else {
printf("Entered character is NOT a letter.\n");
}
return 0;
}
12.10 tolower Function
Let’s study an example. According to Fig. 12.9, ASCII character of capital letters
starts from 65 and ends at 90. The following code gives the integer numbers 65, 66,
67, …, 90 to the tolower function and prints the output generated by the tolower
function. Output of this code is shown in Fig. 12.13.
#include <stdio.h>
#include <ctype.h>
int main() {
for (int i = 65; i <= 90; i++) {
printf("%c\n", tolower(i));
}
return 0;
}
12.11 toupper Function
Let’s study an example. According to Fig. 12.9, ASCII character of small letters
starts from 97 and ends at 120. The following code gives the integer numbers 97, 98,
99, …, 122 to the toupper function and prints the output generated by the toupper
function. Output of this code is shown in Fig. 12.14.
#include <stdio.h>
#include <ctype.h>
int main() {
for (int i = 97; i <= 122; i++) {
printf("ASCII code of %d belong to %c. toupper(%d)=%c\n", i, i, i,
toupper(i));
}
return 0;
}
12.12 getch Function
The function getch in C is used to get a character as input from the user. The input
provided by the user is not displayed on the output screen. The code execution is
paused until a character is entered when a getch function is called. The getch() func-
tion returns the equivalent ASCII value for the character entered. There is no need
to add ctype.h to use the getch function.
240 12 Character Processing
int main()
{
printf("Please enter a character...\n");
printf("Passed value by the User is: %c", getch()); // print a character entered
by the user
return 0;
}
After running the code, the message shown in Fig. 12.15 appears on the screen
and waits to receive a character from the keyboard.
After pressing a key, the second printf runs and shows the character (Fig. 12.16).
Further Reading
1. Deitel P, Deitel H (2022) C how to program: with case studies in applications and systems
programming, 9th edn. Pearson, London
Chapter 13
Time and Date
13.1 Introduction
This chapter studies some of the ready-to-use functions to work with date and time.
Sleep function allows the users to wait for a current thread for a specific time. Let’s
study an example. The following code prints three messages on the screen. There is
a five-second delay between printings. Output of this code is shown in Figs. 13.1,
13.2, and 13.3.
#include <stdio.h>
#include <Windows.h> //Don’t forget this header
int main()
{
printf("Hello ");
Sleep(5000); //sleep for 5000 ms.
printf("World...\n");
Sleep(5000); //sleep for 5000 ms.
printf("C programming is fun!");
}
© The Author(s), under exclusive license to Springer Nature Switzerland AG 2023 241
F. Asadi, Essentials of C Programming with Microsoft® Visual Studio®,
https://doi.org/10.1007/978-3-031-35711-4_13
242 13 Time and Date
13.3 Time Measurement
The clock function returns the number of clock ticks elapsed since the program was
launched. To get the number of seconds used by the CPU, you will need to divide
by CLOCKS_PER_SEC.
Let’s study an example. The following code measure the required time to count
from 0 up to 1000000000-1=999999999. Output of this code is shown in Fig. 13.4.
The number shown on the output depends on the CPU speed and changes from
computer to computer.
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
int main()
{
clock_t start, end;
start = clock();
end = clock();
13.4 time Function
The time function returns the time since 00:00:00 UTC, January 1, 1970 (Unix
timestamp) in seconds. The prototype of this function is time_t time( time_t* sec-
ond). This function accepts single parameter second. This parameter is used to set
the time_t object which store the time. If second is not a null pointer, the returned
value is also stored in the object pointed to by second.
Following is an example. Output of this code is shown in Fig. 13.5.
244 13 Time and Date
#include <stdio.h>
#include <Windows.h>
#include <time.h>
int main()
{
printf("Program started...\n");
time_t now1 = time(NULL); // number of seconds since Jan. 1, 1970 midnight
printf("value of now1 is equal to %ld\n", now1);
Sleep(3000);
printf("Now 3 seconds passed...\n");
time_t now2 = time(NULL);
printf("value of now2 is equal to %ld\n", now2);
printf("Difference between now2 and now1 variables is: %f sec.", difftime(now2,
now1)); // difftime returns the difference of now2-now1 as a double value in seconds
return 0;
}
int main()
{
printf("Program started...\n");
time_t now1 = time(NULL); // number of seconds since Jan. 1, 1970 midnight
printf("value of now1 is equal to %ld\n", now1);
Sleep(3000); // waits for 3000 ms
printf("Now 3 seconds passed...\n");
time_t now2 = time(NULL);
printf("value of now2 is equal to %ld\n", now2);
printf("Difference between now2 and now1 variables is: %d sec.", now2-now1);
return 0;
}
The prototype of ctime function is char* ctime(const time_t* timer). This function
returns a string representing the local time based on the argument timer. The format
of returned string is Www Mmm dd hh:mm:ss yyyy. Where Www is the weekday,
13.6 gmtime Function 245
Mmm the month (in letters), dd the day of the month, hh:mm:ss the time, and yyyy
the year. The string is followed by a new-line character (“\n”) and terminated with a
null-character.
Following is an example. Output of this function is shown in Fig. 13.6.
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
int main()
{
time_t now = time(NULL);
char* string_now = ctime(&now);
printf("%s\n", string_now);
return 0;
}
13.6 gmtime Function
The gmtime function has the prototype of struct tm* gmtime(const time_t* timer).
It uses the value pointed by timer to fill a tm structure with the values that represent
the corresponding time, expressed in Coordinated Universal Time (UTC) or GMT
time zone.
This function returns a pointer to a tm structure with the time information filled
in. Fields of the tm structure are:
struct tm {
int tm_sec; /* seconds, range 0 to 59 */
int tm_min; /* minutes, range 0 to 59 */
int tm_hour; /* hours, range 0 to 23 */
int tm_mday; /* day of the month, range 1 to 31 */
int tm_mon; /* month, range 0 to 11, January=0 */
int tm_year; /* The number of years since 1900 */
int tm_wday; /* day of the week, range 0 to 6;Sunday=0 */
int tm_yday; /* day in the year, range 0 to 365, Jan 1=0 */
int tm_isdst; /* daylight saving time */
};
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
int main()
{
time_t now = time(NULL);
char* string_now = ctime(&now);
printf("%s\n", string_now);
struct tm *gm_time=gmtime(&now);
printf("tm_hour: %d\n", gm_time->tm_hour);
printf("tm_min : %d\n", gm_time->tm_min);
printf("tm_sec : %d\n", gm_time->tm_sec);
return 0;
}
13.7 localtime Function
The localtime function has the prototype of struct tm* localtime(const time_t*
timer). It uses the value pointed by timer to fill a tm structure with the values that
represent the corresponding local time.
This function returns a pointer to a tm structure with the time information filled
in. Fields of the tm structure are:
struct tm {
int tm_sec; /* seconds, range 0 to 59 */
int tm_min; /* minutes, range 0 to 59 */
int tm_hour; /* hours, range 0 to 23 */
int tm_mday; /* day of the month, range 1 to 31 */
int tm_mon; /* month, range 0 to 11, January=0 */
int tm_year; /* The number of years since 1900 */
int tm_wday; /* day of the week, range 0 to 6;Sunday=0 */
int tm_yday; /* day in the year, range 0 to 365, Jan 1=0 */
int tm_isdst; /* daylight saving time */
};
int main()
{
time_t now = time(NULL);
char* string_now = ctime(&now);
printf("%s\n", string_now);
struct tm *cur_time=localtime(&now);
printf("tm_hour: %d\n", cur_time->tm_hour);
printf("tm_min : %d\n", cur_time->tm_min);
printf("tm_sec : %d\n", cur_time->tm_sec);
return 0;
}
248 13 Time and Date
13.8 asctime Function
The asctime function has the prototype of char* asctime(const struct tm* timeptr)
and returns a pointer to a string which represents the day and time of the timeptr.
The timeptr is a pointer to tm structure that contains a calendar time broken down
into its components as shown below:
struct tm {
int tm_sec; /* seconds, range 0 to 59 */
int tm_min; /* minutes, range 0 to 59 */
int tm_hour; /* hours, range 0 to 23 */
int tm_mday; /* day of the month, range 1 to 31 */
int tm_mon; /* month, range 0 to 11, January=0 */
int tm_year; /* The number of years since 1900 */
int tm_wday; /* day of the week, range 0 to 6;Sunday=0 */
int tm_yday; /* day in the year, range 0 to 365, Jan 1=0 */
int tm_isdst; /* daylight saving time */
};
int main()
{
time_t now = time(NULL);
struct tm* cur_time = localtime(&now);
char* string1 = asctime(cur_time);
//asctime works with struct tm type.
printf("%s\n", string1);
return 0;
}
13.9 strftime Function 249
13.9 strftime Function
The strftime function has the prototype size_t strftime(char* str, size_t maxsize,
const char* format, const struct tm* timeptr). This function formats the time repre-
sented in the structure timeptr according to the formatting rules defined in format
and stored into str. Table 13.1 shows the formatting specifiers that can be used.
int main()
{
time_t now = time(NULL);
struct tm* cur_time = localtime(&now);
return 0;
}
The _strtime function has the prototype of char* _strtime(char* timestr). This func-
tion copies the current local time into the buffer pointed to by timestr. The time is
formatted as hh:mm:ss, where hh is two digits that represent the hour in 24-hour
notation, mm is two digits for the minutes past the hour, and ss is two digits for
seconds. For example, the string 18:23:44 represents 23 minutes and 44 seconds
after 6 P.M. The buffer must be at least 9 bytes long.
The _strdate function has the prototype of char* _strdate(char* datestr). This
function copies the current system date to the buffer pointed to by datestr, formatted
mm/dd/yy, where mm is two digits representing the month, dd is two digits repre-
senting the day, and yy is the last two digits of the year. For example, the string
01/04/99 represents January 04, 2023. The buffer must be at least 9 bytes long.
Following is an example. Output of this code is shown in Fig. 13.11.
Further Reading 251
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
char tmpbuf[128];
_strtime(tmpbuf, 128);
printf("OS time is (hh:mm:ss): %s\n", tmpbuf);
_strdate(tmpbuf, 128);
printf("OS date is (mm/dd/yy): %s\n", tmpbuf);
return 0;
}
Further Reading
14.1 Introduction
14.2 Bubble Sort
The bubble sort is not an efficient method to sort an array if the array size is big.
However, coding the bubble sort algorithm is a good programming practice. Suppose
we are trying to sort the elements in an ascending order using bubble sort. Here are
the steps of first Iteration (Compare and Swap) for bubble sort (Fig. 14.1):
(a) Starting from the first index, compare the first and the second elements.
(b) If the first element is greater than the second element, they are swapped.
(c) Now, compare the second and the third elements. Swap them if they are not
in order.
(d) The above process goes on until the last element.
© The Author(s), under exclusive license to Springer Nature Switzerland AG 2023 253
F. Asadi, Essentials of C Programming with Microsoft® Visual Studio®,
https://doi.org/10.1007/978-3-031-35711-4_14
254 14 Sorting and Searching
i=0 –2 45 0 11 –9
i=1 –2 45 0 11 –9
i=2 –2 0 45 11 –9
i=3 –2 0 11 45 –9
–2 0 11 –9 45
The same process goes on for the remaining iterations. After each iteration, the
largest element among the unsorted elements is placed at the end (Fig. 14.2).
i=0 –2 0 11 –9 45
i=1 –2 0 11 –9 45
i=2 –2 0 11 –9 45
–2 0 –9 11 45
14.2 Bubble Sort 255
In each iteration, the comparison takes place up to the last unsorted element
(Fig. 14.3).
i=0 –2 0 –9 11 45
i=1 –2 0 –9 11 45
–2 –9 0 11 45
The array is sorted when all the unsorted elements are placed at their correct
positions (Fig. 14.4).
i=0 –2 –9 0 11 45
–9 –2 0 11 45
The following code uses bubble sort to sort the array a. Functions a_bubble_sort
and d_bubble_sort sort the array in ascending and descending orders, respectively.
Output of this code is shown in Fig. 14.5.
256 14 Sorting and Searching
#include <stdio.h>
void a_bubble_sort(int a[], int length); //ascending sort
void d_bubble_sort(int a[], int length); //descending sort
int main() {
int a[] = { 7,1,3,9,0,2,4,5,8,6};
int length = sizeof(a) / sizeof(a[0]);
a_bubble_sort(a, length);
printf("ascending order : ");
for (int i = 0; i < length; i++)
{
printf("%d ", a[i]);
}
d_bubble_sort(a, length);
printf("\ndescending order: ");
for (int i = 0; i < length; i++)
{
printf("%d ",a[i]);
}
return 0;
}
The following code is an optimized version of the previous code. Output of this
code is shown in Fig. 14.6.
258 14 Sorting and Searching
#include <stdio.h>
#include <stdbool.h>
int main() {
int a[] = { 7,1,3,9,0,2,4,5,8,6};
int length = sizeof(a) / sizeof(a[0]);
a_bubble_sort(a, length);
printf("ascending order : ");
for (int i = 0; i < length; i++)
{
printf("%d ", a[i]);
}
d_bubble_sort(a, length);
printf("\ndescending order: ");
for (int i = 0; i < length; i++)
{
printf("%d ",a[i]);
}
return 0;
}
14.3 Insertion Sort
Insertion sort is a sorting algorithm that places an unsorted element at its suitable
place in each iteration. Insertion sort works similarly as we sort cards in our hand in
a card game. We assume that the first card is already sorted, then we select an
unsorted card. If the unsorted card is greater than the card in hand, it is placed on the
right, otherwise, to the left. In the same way, other unsorted cards are taken and put
in their right place. A similar approach is used by insertion sort.
Let’s study an example. Suppose we need to sort the array shown in Fig. 14.7 in
an ascending order using the insertion sort.
The first element in the array is assumed to be sorted. Take the second element
and store it separately in key.
Compare key with the first element. If the first element is greater than key, then
key is placed in front of the first element (Fig. 14.8).
Now, the first two elements are sorted. Take the third element and compare it
with the elements on its left. Place it just behind the element smaller than it. If there
is no element smaller than it, then place it at the beginning of the array (Fig. 14.9).
Similarly, place every unsorted element at its correct position (Figs. 14.10
and 14.11).
14.3 Insertion Sort 261
The following code uses insertion sort to sort the array a in an ascending order.
Output of this code is shown in Fig. 14.12.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int a[] = { 8,4,9,5,7,6,3,2 };
insertion_sort(a, sizeof(a) / sizeof(a[0]));
The following code uses the qsort function (which is defined in the stdlib.h header
file) to arrange the integer array values in an ascending order. Output of this code is
shown in Fig. 14.13.
#include <stdio.h>
#include <stdlib.h>
int main() {
return(0);
}
The following code uses the qsort function to arrange the integer array values in
a descending order. Output of this code is shown in Fig. 14.14.
#include <stdio.h>
#include <stdlib.h>
int main() {
return(0);
}
The following code uses the qsort function to arrange the double array values in an
ascending order. Output of this code is shown in Fig. 14.15.
14.6 Quick Sort for Double Values 265
#include <stdio.h>
#include <stdlib.h>
double values[] = { 88.3, 56.5, 100.4, 2.0, 0.25, 7.63, 26.41, 45.22,-3.04 };
int main() {
return(0);
}
The following code uses the qsort function to arrange the double array values in
a descending order. Output of this code is shown in Fig. 14.16.
266 14 Sorting and Searching
#include <stdio.h>
#include <stdlib.h>
double values[] = { 88.3, 56.5, 100.4, 2.0, 0.25, 7.63, 26.41, 45.22,-3.04 };
int main() {
return(0);
}
The following code uses the qsort function to arrange the string array cities in an
ascending order. Output of this code is shown in Fig. 14.17.
14.7 Quick Sort for Strings 267
#include <stdio.h>
#include <stdlib.h>
char* cities[] = { "new york", "new york", "New York", "Los Angeles",
"chicago", "Houston", "phoenix", "Dallas", "Texas" };
int main() {
return(0);
}
The following code uses the qsort function to arrange the string array cities in a
descending order. Output of this code is shown in Fig. 14.18.
268 14 Sorting and Searching
#include <stdio.h>
#include <stdlib.h>
char* cities[] = { "new york", "new york", "New York", "Los Angeles",
"chicago", "Houston", "phoenix", "Dallas", "Texas" };
int main() {
return(0);
}
14.8 Binary Search
Let x = 4 be the element to be searched. Set two pointers low and high at the
lowest and the highest positions, respectively (Fig. 14.20).
Find the middle element mid of the array, i.e., arr[(low + high)/2] =
arr[(0+6)/2]=arr[3]=6 (Fig. 14.21).
If x == mid, then return mid. Else, compare the element to be searched with mid.
If x > mid, compare x with the middle element of the elements on the right side
of mid. This is done by setting low to low = mid + 1.
Else, compare x with the middle element of the elements on the left side of mid.
This is done by setting high to high = mid – 1 (Fig. 14.22).
Repeat steps 3 to 6 until low meets high. x=4 is found (Fig. 14.23).
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int sorted[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13 };
int n = 0;
printf("enter -1 to exit\n");
do
{
printf("\nplease enter the number that you want to be searched : ");
scanf("%d", &n);
return 0;
}
if (a[mid] == e)
return mid;
if (a[mid] < e)
l = mid + 1;
else
r = mid - 1;
}
return -1;
}
14.8 Binary Search 271
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int sorted[] = {1,2,3,4,5,6,7,8,9,10,11,12,13};
int n = 0;
printf("enter -1 to exit\n");
do
{
printf("\nplease enter the number that you want to be searched : ");
scanf("%d", &n);
return 0;
}
if (l > r) return -1; //shows that element doesn't exist in the list
if (a[mid] == e)
return mid;
else if (a[mid] > e)
return binary_search(a, e, l, mid - 1);
else
return binary_search(a, e, mid+1, r);
}
Further Reading
1. Deitel P, Deitel H (2022) C how to program: with case studies in applications and systems
programming, 9th edn. Pearson, London
Chapter 15
File Processing
15.1 Introduction
A file represents a sequence of bytes on the disk where a group of related data is
stored. File is created for permanent storage of data. Files permit you to easily move
your data from one computer to another without any changes as well.
When dealing with files, there are two types of files you should know about: text
files and binary files.
Text files are the normal .txt files. You can easily create text files using any sim-
ple text editors such as Notepad. When you open those files, you will see all the
contents within the file as plain text. You can easily edit or delete the contents. They
take minimum effort to maintain, are easily readable, but provide the least security
and take bigger storage space.
Binary files are mostly the .bin files in your computer. Instead of storing data in
plain text, they store it in the binary form (0s and 1s). They can hold a higher amount
of data, are not readable easily, and provides better security than text files.
This chapter studies the files.
When working with files, you need to declare a pointer of type file: FILE* fptr;
opening a file is performed using the fopen function defined in the stdio.h header
file. The syntax for opening a file in standard I/O is: fptr = fopen("PathAndFileNam
e","mode"). The different types of opening modes are shown in Table 15.1.
© The Author(s), under exclusive license to Springer Nature Switzerland AG 2023 275
F. Asadi, Essentials of C Programming with Microsoft® Visual Studio®,
https://doi.org/10.1007/978-3-031-35711-4_15
276 15 File Processing
The file (both text and binary) should be closed (using the fclose function) after
reading/writing. Let’s study an example. In the following code, a text file in D:\ path
with name io.txt is opened for writing. Then the fputs function writes a string to the
specified stream up to but not including the null character. After running the code,
open the io.txt and ensure that Hello World is written there (Fig. 15.1).
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
FILE* fh_output; //file handle
fh_output = fopen("D:\\io.txt", "w"); //"w" open the file for writing
//if io.txt doesn't exists, it will create
it.
//if io.txt does exist, it will delete
everything there.
fputs("Hello \nWorld!", fh_output);
fclose(fh_output);
return 0;
}
15.2 Creating a New File 277
#include <stdio.h>
main(void)
{
FILE* fh_output;
fh_output = fopen("D:\\io.txt", "w");
fputs("Hello", fh_output);
fputs("World", fh_output);
fputs("!", fh_output);
fclose(fh_output);
return 0;
}
Let’s study another example. The following code shows how to handle the errors.
Note that when NULL is returned, an error is occurred.
278 15 File Processing
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <errno.h>
#include <string.h>
main(void)
{
FILE* fh_output;
fh_output = fopen("C:\\io.txt", "w");
if (fh_output == NULL)
{
printf("Error Message: %s\n", strerror(errno));
return 1;
}
else {
fputs("Hello \nWorld!", fh_output);
fclose(fh_output);
}
return 0;
}
15.3 Append Mode
In append mode, the previous contents of the file are not affected. New data will be
written to the end of the file. Let’s study an example. The following code opens the
D:\io.txt in the append mode. You will obtain the result shown in Fig. 15.3 if you run
the code twice.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
FILE* fh_output;
fh_output = fopen("D:\\io.txt", "a");
fputs("Hello World!\n", fh_output);
fclose(fh_output);
return 0;
}
15.4 ftell Function
ftell returns the current file position of the given stream. Following is an example.
Output of this code and content of io.txt are shown in Figs. 15.4 and 15.5,
respectively.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
FILE* fh_output; //file handle
fh_output = fopen("D:\\io.txt", "w");
printf("current location of cursor: %d.\n", ftell(fh_output));
fclose(fh_output);
return 0;
}
15.5 fprintf Function
fprintf function sends formatted output to a stream. Format specifiers are shown in
Table 15.2.
280 15 File Processing
#include <stdio.h>
main(void)
{
FILE* fh_output;
fh_output = fopen("D:\\io.txt", "w");
int a = 10;
float b = 20.30;
char c = 'x';
fclose(fh_output);
return 0;
}
15.6 fseek Function
fseek function sets the file position of the stream to the given offset. The prototype
of this function is int fseek(FILE *stream, long int offset, int whence). The descrip-
tion of parameters are given below:
stream: This is the pointer to a FILE object that identifies the stream.
offset: This is the number of bytes to offset from whence.
whence: This is the position from where offset is added. It is specified by one of
the constants shown in Table 15.3.
#include <stdio.h>
main(void)
{
FILE* file;
file= fopen("D:\\file.txt", "w");
if (file == NULL)
{
printf("Error opening file.\n");
return 1;
}
fprintf(file, "abcdefgh\n");
fprintf(file, "ijklmnop");
fseek(file, 0, SEEK_SET);
fprintf(file, "qrstuvwx\n");
fclose(file);
return 0;
}
#include <stdio.h>
main(void)
{
FILE* file;
file = fopen("D:\\file.txt", "w");
if (file == NULL)
{
printf("Error opening file.\n");
return 1;
}
fprintf(file, "abcdefgh\n");
fprintf(file, "ijklmnop");
fclose(file);
return 0;
}
#include <stdio.h>
main(void)
{
FILE* file;
file = fopen("D:\\file.txt", "w");
if (file == NULL)
{
printf("Error opening file.\n");
return 1;
}
fprintf(file, "abcdefgh\n");
fprintf(file, "ijklmnop");
fclose(file);
return 0;
}
15.7 rewind Function
The void rewind(FILE* stream) sets the file position to the beginning of the file of
the given stream. Following is an example. Output of this code is shown in Fig. 15.10.
284 15 File Processing
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
FILE* file;
file = fopen("D:\\file.txt", "w");
if (file == NULL)
{
printf("Error opening file.\n");
return 1;
}
fprintf(file, "abcdefgh");
fprintf(file, "ijklmnop");
rewind(file);
fprintf(file, "+-*/");
fclose(file);
return 0;
}
15.8 Reading a File
The int fscanf(FILE* stream, const char* format, argument-list) reads formatted
input from a stream. The following codes reads the values stored in io.txt file. The
content of io.txt is shown in Fig. 15.11. Output of this code is shown in Fig. 15.12.
15.8 Reading a File 285
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
FILE* fh_input;
fh_input = fopen("D:\\io.txt", "r");
int a;
float b;
fclose(fh_input);
return 0;
}
The EOF indicates the file reached end with nothing to read. The following code
continues reading the io.txt until it reaches the EOF. The content of io.txt is shown
in Fig. 15.13. Output of this code is shown in Fig. 15.14.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
FILE* fh_input;
fh_input = fopen("D:\\io.txt", "r");
int a;
fclose(fh_input);
return 0;
}
15.10 fgets Function
The char* fgets(char* str, int n, FILE* stream) reads a line from the specified stream
and stores it into the string pointed to by str. It stops when either (n-1) characters are
read, the newline character is read, or the end-of-file is reached, whichever
comes first.
Following is an example. This code reads the io.txt line by line. The content of
io.txt is shown in Fig. 15.15. Output of this code is shown in Fig. 15.16.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
FILE* fh_input;
fh_input = fopen("D:\\io.txt", "r");
char buffer[256];
fgets(buffer, 256, fh_input);
printf("%s", buffer);
fclose(fh_input);
return 0;
}
fgets returns NULL when it reaches the end of file. The following code checks to
see whether fgets returned NULL. It stops reading once fgets returned NULL. Output
of this code is shown in Fig. 15.17.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
FILE* fh_input;
fh_input = fopen("D:\\io.txt", "r");
char buffer[256];
fclose(fh_input);
return 0;
}
15.11 getc Function
The int getc(FILE *stream) gets the next character (an unsigned char) from the
specified stream and advances the position indicator for the stream.
Following is an example. This code reads the io.txt character by character. The
content of io.txt is shown in Fig. 15.18. Output of this code is shown in Fig. 15.19.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
FILE* fh_input;
fh_input = fopen("D:\\io.txt", "r");
char ch;
do
{
ch = getc(fh_input);
printf("%c", ch);
} while (ch != EOF);
return 0;
}
15.12 Writing to a Binary File 289
A binary file is the one in which data is stored in the file in the same way as it is
stored in the main memory for processing. It is stored in binary format instead of
ASCII characters. It is normally used for storing numeric information (int, float,
double). Normally, a binary file can be created only from within a program and its
contents can be read only by a program.
Table 15.4 showed the major differences between text files and binary files.
Table 15.4 Major differences between text files and binary files
Text file Binary file
In text file, text, character, numbers are stored In binary file, data is stored in binary format
one character per byte, i.e., 32667 occupies 5 and each data would occupy the same
bytes although it occupies 2 bytes in memory number of bytes on disks as it occupies in
memory
In the text file, the newline character is converted In binary file, conversion of newline to
to carriage-return/linefeed before being written carriage-return and linefeed does not take
to the disk place
Text files are used to store data more user Binary files are used to store data more
friendly compactly
In the text file, a special character(“\0”) whose In the binary file, no such character is
ASCII value is 26 inserted after the last character present. Files keep track of the end of the file
to mark the end of file from the number of characters present
Content written in text files is human readable Content written in binary files is not human
readable and looks like encrypted content
290 15 File Processing
To write into a binary file, you need to use the fwrite function. The prototype of
this function is: size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE*
stream). This function takes four arguments:
ptr: This is the pointer to the array of elements to be written.
size: This is the size in bytes of each element to be written.
nmemb: This is the number of elements, each one with a size of size bytes.
stream: This is the pointer to a FILE object that specifies an output stream.
Let’s study some examples. The following code writes integer data to a binary file.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
FILE* file;
file= fopen("D:\\file.bin", "wb");
if (file == NULL)
{
printf("Error opening file.\n");
return 1;
}
int data = 123;
fwrite(&data, sizeof(data), 1, file);
fclose(file);
return 0;
}
#include <stdio.h>
main(void)
{
int data[] = {100,200,300,400,500,600,700};
FILE* file;
file= fopen("D:\\file.bin", "wb");
if (file == NULL)
{
printf("Error opening file.\n");
return 1;
}
To read from a binary file, you need to use the fread function. The prototype of this
function is:
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream). This function
takes four arguments:
ptr : This is the pointer to a block of memory with a minimum size of
size*nmemb bytes.
size : This is the size in bytes of each element to be read.
nmemb : This is the number of elements, each one with a size of size bytes.
stream : This is the pointer to a FILE object that specifies an input stream.
Let’s study an example. The following code reads the binary file produced by the
previous code. Output of this code is shown in Fig. 15.20.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
int data[7];
FILE* file;
file= fopen("D:\\file.bin", "rb");
if (file == NULL)
{
printf("Error opening file.\n");
return 1;
}
The following code shows how to write and read a structure to a binary file.
Output of this code is shown in Fig. 15.21.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
point p1, p2, p3, p4;
p1.x = 0;
p1.y = 0;
p2.x = 1;
p2.y = 1;
p3.x = 2;
p3.y = 2;
p4.x = 3;
p4.y = 3;
FILE* file1;
file1= fopen("D:\\file.bin", "wb");
if (file1 == NULL)
{
printf("Error opening file.\n");
return 1;
}
FILE* file2;
file2 = fopen("D:\\file.bin", "rb");
point p5;
for (int i = 0; i < 4; i++)
{
fread(&p5, sizeof(point), 1, file2);
printf("p%i.x=%d ", i+1, p5.x);
printf("p%i.y=%d\n", i+1, p5.y);
}
fclose(file2);
return 0;
}
15.13 Reading from Binary Files 293
You can use the following code as well. Output of this code is shown in Fig. 15.22.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
main(void)
{
point p1, p2, p3, p4;
p1.x = 0;
p1.y = 0;
p2.x = 1;
p2.y = 1;
p3.x = 2;
p3.y = 2;
p4.x = 3;
p4.y = 3;
FILE* file1;
file1= fopen("D:\\file.bin", "wb+");
if (file1 == NULL)
{
printf("Error opening file.\n");
return 1;
}
rewind(file1);
point p5;
for (int i = 0; i < 4; i++)
{
fread(&p5, sizeof(point), 1, file1);
printf("p%i.x=%d ", i+1, p5.x);
printf("p%i.y=%d\n", i+1, p5.y);
}
fclose(file1);
return 0;
}
294 15 File Processing
15.14 Error Handling
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main()
{
FILE* fh;
printf("errno before any error: %d\n", errno);
fh = fopen("xyz.txt", "r");
if (fh == NULL)
{
printf("errno after: %d\n", errno);
printf("Error Message: %s\n", strerror(errno));
}else{
fclose(fh);
}
return 0;
}
You can use the perror as well. The prototype of this function is void perror(const
char* str). It prints a descriptive error message to stderr. First, the string str is
printed, followed by a colon, then a space.
Following is an example. Output of this example is shown in Fig. 15.24.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main()
{
FILE* fh;
printf("errno before any error: %d\n", errno);
fh = fopen("xyz.txt", "r");
if (fh == NULL)
{
printf("errno after: %d\n", errno);
perror("Error Message");
//printf("Error Message: %s\n", strerror(errno));
}else{
fclose(fh);
}
return 0;
}
Further Readings
1. Deitel P, Deitel H (2022) C how to program: with case studies in applications and systems
programming, 9th edn. Pearson, London
2. Hart JM (2010) Windows system programming. Addison-Wesley, Upper Saddle River
Chapter 16
Useful Functions to Work with Files
and Directories
16.1 Introduction
This chapter introduces some useful functions to work with files and directories.
The following code copies C:\test.txt to D:\copy.txt. This code reads the source file
(C:\test.txt) character by character and copies it to the destination (D:\copy.txt) file.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
FILE* file;
FILE* copy;
char c;
while ((c = fgetc(file)) != EOF)
fputc(c, copy);
fclose(file);
fclose(copy);
printf("Files are copied.");
return(0);
}
In the previous section, the addresses of source and destination files are put in the
source code. In this section, the addresses of source and destination files are taken
from the command line (see Sect. 7.4 in Chap. 7). The following code takes the
source and destination addresses from the command line.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
if (argc != 3)
{
printf("Argument number error.\n");
return 1;
};
char c;
while ((c = fgetc(file)) != EOF)
fputc(c, copy);
fclose(file);
fclose(copy);
printf("Files are copied.");
return(0);
}
Let’s test the code. Click the Project> Project Properties (Fig. 16.1) and give the
source and destination paths (Fig. 16.2).
16.3 Copying .txt Files (II) 299
Now you can press F5, and see the output of the code.
You can use the CopyFileA function (defined in Windows.h header file) to copy a
binary or text file. The following code shows how to use this function. It will not
overwrite the destination file if it already exists. For instance, assume that you want
to copy C:\ExistingFile.txt to D:\NewFile.txt and D:\NewFile.txt already exists. The
following code does not overwrite the D:\NewFile.txt.
16.5 Copying Files with CopyFileA Function (II) 301
#include <stdio.h>
#include <Windows.h>
int main()
{
//see https://bit.ly/3k32iRO
return 0;
}
int main()
{
//see https://bit.ly/3k32iRO
return 0;
}
In the previous section, the addresses of source and destination files are put in the
source code. In this section, the addresses of source and destination files are taken
from the command line (see Sect. 7.4 in Chap. 7). The following code takes the
source and destination addresses from the command line.
#include <stdio.h>
#include <Windows.h>
if (flag)
printf("Copy successful.\n");
else
printf("Error! File already exists. Existing destination file leaved
unchanged.\n");
return 0;
}
302 16 Useful Functions to Work with Files and Directories
Let’s test the file. Click the Project> Project1 Properties (Fig. 16.4) and give the
source and destination addresses (Fig. 16.5). Press F5 to test the code.
16.6 Rename a File
int main() {
int ret;
char oldname[] = "d:\\file.txt";
char newname[] = "d:\\newfile.txt";
if (ret == 0) {
printf("File renamed successfully");
}
else {
printf("Error: unable to rename the file");
}
return(0);
}
16.7 Remove a File
int main()
{
int result;
result=remove("d:\\io.txt");
if (result == 0) {
printf("File deleted successfully");
}
else {
printf("Error: unable to delete the file");
}
return 0;
}
int main()
{
BOOL flag=DeleteFileA("d:\\NewTest.txt");
if (flag)
printf("Delete successful...\n");
else
printf("Error! Such a file doesn't exists!\n");
return 0;
}
304 16 Useful Functions to Work with Files and Directories
The following code requires the dirent library. This library can be downloaded from
GitHub (https://github.com/tronkko/dirent). After downloading the files, you need
to copy them into the include folder of Visual Studio. Click the Project> Project1
Properties (Fig. 16.6) and study the External Include Directories (Fig. 16.7) to find
the address of include folder.
The following code prints the contents of current working directory. Output of
this code is shown in Fig. 16.8.
// see https://bit.ly/3XGy5qj
// see https://github.com/tronkko/dirent
// see https://bit.ly/3vUwS2r
#define _CRT_SECURE_NO_WARNINGS
#include <dirent.h>
int main()
{
DIR* directory;
struct dirent* entry;
directory = opendir(".");// opendir(".") opens the current working directory
// directory = opendir("c:\\") opens the c:\
if (directory == NULL)
{
printf("Error opening directory");
return 1;
}
Let’s study another example. The following code adds a label to each item so you
can see whether it is a file or directory. Output of this code is shown in Fig. 16.9.
// see https://bit.ly/3XGy5qj
// see https://github.com/tronkko/dirent
// see https://bit.ly/3vUwS2r
#define _CRT_SECURE_NO_WARNINGS
#include <dirent.h>
int main()
{
DIR* directory;
struct dirent* entry;
directory = opendir(".");
if (directory == NULL)
{
printf("Error opening directory");
return 1;
}
if (closedir(directory) == -1)
{
printf("Error closing directory.\n");
return 1;
}
return(0);
}
16.9 Obtaining the Address of Current Working Directory 307
The following code used the _getcwd function (which is defined in the direct.h
header file) to print the current working directory. Sample output of this code is
shown in Fig. 16.10.
#include <stdio.h>
#include <direct.h>
int main()
{
char buffer[1024];
return 0;
}
You can use the _chdir function to change the current working directory. Following
code is an example. Output of this code is shown in Fig. 16.11.
int main()
{
char buffer[1024];
return 0;
}
16.11 Making Directories
You can make a directory with the aid of _mkdir function. Following code is an
example. Output of this code is shown in Fig. 16.12.
16.12 Removing Directories 309
#include <stdio.h>
#include <direct.h>
int main()
{
int result;
result = _mkdir("C:\\test");
if (result == 0)
printf("Directory created\n");
else
printf("Error creating directory\n");
return 0;
}
16.12 Removing Directories
You can remove an empty directory with the aid of _rmdir function which is defined
in the direct.h header file. The following code removes the empty c:\test directory.
Output of this code is shown in Fig. 16.13.
#include <stdio.h>
#include <direct.h>
int main()
{
int result;
if (result == -1)
{
printf("Remove directory failed.\n");
return 1;
}
else
printf("Directory removed successfully");
return 0;
}
310 16 Useful Functions to Work with Files and Directories
You cannot remove a directory if it is not empty or is in use. The following code
gives suitable messages on these cases.
#include <stdio.h>
#include <direct.h>
#include <errno.h>
int main()
{
int result;
if (result == -1)
{
printf("Remove directory failed.\n");
if (errno == ENOENT)
printf("Path not found.");
else if (errno == ENOTEMPTY)
printf("Directory is not empty");
else if (errno == EACCES)
printf("Directory is in use");
return 1;
}
else
printf("Directory removed successfully");
return 0;
}
Further Reading
17.1 Introduction
Modern computers have some USB ports. A cheap USB-to-serial converter can be
used to convert the USB protocol into simple serial protocol. A virtual serial port is
made when a USB-to-serial converter is connected to a USB port.
This chapter shows how you can transfer data with that virtual serial port made
by USB-to-serial converter. In this chapter, we will use an Arduino UNO board to
send and receive data. The Arduino UNO has an onboard USB-to-serial converter.
Therefore, there is no need for any external USB-to-serial converter.
In this section, we will use the Arduino board as a sender. The Arduino board is con-
nected to port COM 3 (Fig. 17.1). It sends the “Hello from Arduino…” string with
9600 bps to COM 3.
© The Author(s), under exclusive license to Springer Nature Switzerland AG 2023 311
F. Asadi, Essentials of C Programming with Microsoft® Visual Studio®,
https://doi.org/10.1007/978-3-031-35711-4_17
312 17 Serial Communication in C
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("Hello from Arduino...");
delay(1000);
}
The following code opens the COM 3 with baud rate of 9600 bps. It reads the
data from serial port (using ReadFile function) and shows the received data on the
computer screen. Output of this code is shown in Fig. 17.3.
314 17 Serial Communication in C
#include<windows.h>
#include<stdio.h>
int main()
{
HANDLE hComm;
hComm = CreateFileA("\\\\.\\COM3", // Port name
GENERIC_READ | GENERIC_WRITE, // Read/Write
0, // No Sharing
NULL, // No Security
OPEN_EXISTING, // Open existing port only
0, // Non Overlapped I/O
NULL); // Null for Comm Devices
if (hComm == INVALID_HANDLE_VALUE)
printf("Error in opening serial port\n");
else
printf("opening serial port successful\n");
DCB dcbSerialParams = { 0 };
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
DWORD dwEventMask;
SetCommMask(hComm, EV_RXCHAR); // configuring windows for reception
WaitCommEvent(hComm, &dwEventMask, NULL); // waiting for the reception
int i = 0;
DWORD NoBytesRead;
char TempChar;
char SerialBuffer[256];
do {
ReadFile(hComm, &TempChar, sizeof(TempChar), &NoBytesRead, NULL);//reads the
serial port
SerialBuffer[i] = TempChar;
i++;
} while (NoBytesRead > 0);
return 0;
}
17.3 Writing to the Serial Port 315
In this section, we will use the Arduino board as receiver. The Arduino board is con-
nected to port COM 3 (Fig. 17.4). It receives a command from the computer. When
the command is “on,” “ON,” or “On,” the onboard LED of Arduino is turned on.
When the command is “off,” “OFF,” or “Off,” the onboard LED of Arduino is
turned off.
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(LED_BUILTIN,OUTPUT);
}
void loop() {
if (Serial.available()>0){
String inputCommand=Serial.readString();
Serial.println((String)"Entered command: "+inputCommand);
if (inputCommand=="on" ||inputCommand=="ON"||inputComman
d=="On")
{
digitalWrite(LED_BUILTIN,HIGH);
}
if (inputCommand=="off"||inputCommand=="OFF"||inputComman
d=="Off")
{
digitalWrite(LED_BUILTIN,LOW);
}
}
}
17.3 Writing to the Serial Port 317
The following code opens the COM 3 with baud rate of 9600 bps. It takes a com-
mand from the user and sends the string to the serial port (using WriteFile function).
Sample output of this code is shown in Fig. 17.6.
318 17 Serial Communication in C
#define _CRT_SECURE_NO_WARNINGS
#include<windows.h>
#include<stdio.h>
#include<string.h>
int main()
{
HANDLE hComm;
if (hComm == INVALID_HANDLE_VALUE)
printf("Error in opening serial port\n");
else
printf("opening serial port successful\n");
DCB dcbSerialParams = { 0 };
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
dcbSerialParams.BaudRate = CBR_9600;
dcbSerialParams.ByteSize = DATABITS_8;
dcbSerialParams.Parity = NOPARITY;
dcbSerialParams.StopBits = ONESTOPBIT;
SetCommState(hComm, &dcbSerialParams); // configuring the port according to dcb
structures
DWORD dNoOFBytestoWrite;
DWORD dNoOfBytesWritten = 0;
return 0;
}
Further Readings 319
Further Readings
1. https://bit.ly/3H5huqi
2. Asadi F (2022) Essential circuit analysis using NI Multisim™ and MATLAB®. Springer,
Cham. https://doi.org/10.1007/978-3-030-89850-2
3. Asadi F (2022) Essential circuit analysis using Proteus®. Springer. https://doi.
org/10.1007/978-981-19-4353-9
4. Asadi F (2022) Essential circuit analysis using LTspice®. Springer. https://doi.
org/10.1007/978-3-031-09853-6
5. Asadi F (2022) Electric and electronic circuit simulation using TINA-TI®. River Publishers.
https://doi.org/10.13052/rp-9788770226851
6. Asadi F (2022) Electric circuit analysis with EasyEDA. Springer. https://doi.
org/10.1007/978-3-031-00292-2
7. Asadi F (2021) Power electronics circuit analysis with PSIM®. De Gruyter. https://doi.
org/10.1515/9783110740653
8. Asadi F (2022) Simulation of power electronics circuits with MATLAB®/Simulink®: design,
analyze, and prototype power electronics. Apress. https://doi.org/10.1007/978-1-4842-8220-5
9. Asadi F, Eguchi K (2021) Electronic measurement: a practical approach. Springer. https://doi.
org/10.1007/978-3-031-02021-6
10. Asadi F, Eguchi K (2019) Simulation of power electronics converters Using PLECS®.
Academic Press. https://doi.org/10.1016/C2018-0-02253-7
11. Asadi F (2023) Analog electronic circuits laboratory manual. Springer. https://doi.
org/10.1007/978-3-031-25122-1
12. Asadi F (2023) Electric circuits laboratory manual. Springer. https://doi.
org/10.1007/978-3-031-24552-7
Chapter 18
Graphical User Interface
18.1 Introduction
You can use the Visual Studio to make programs with graphical user interfaces
(GUI). In this chapter, you will learn how to make a simple program with graphical
user interface. See the references at the end of this chapter to learn more about this
subject.
Select the File> New> Project and select the CLR Empty Project (.NET Framework)
(Fig. 18.1). Then give a desired name for the project and save it in the desired path
(Fig. 18.2).
© The Author(s), under exclusive license to Springer Nature Switzerland AG 2023 321
F. Asadi, Essentials of C Programming with Microsoft® Visual Studio®,
https://doi.org/10.1007/978-3-031-35711-4_18
322 18 Graphical User Interface
Right click on the Source Files in the Solution Explorer window (Fig. 18.3) and
select the Add> New Item (Fig. 18.4). If the Solution Explorer window is hidden,
click the View> Solution Explorer (Fig. 18.5) to show it.
After clicking the Add> New Item (Fig. 18.4), the Add New Item window
appears on the screen. Select the Windows Form (Fig. 18.6) and save it with
MyForm.h name.
After clicking the Add button in Fig. 18.6, the window shown in Fig. 18.7 appears
on the screen. Close this window using the X button (Fig. 18.7).
Double click on the MyForm.h to open the GUI design environment (Fig. 18.8).
If design environment (Fig. 18.9) is not shown after double clicking the MyForm.h,
close the solution using the File> Close Solution, reopen it and double click the
MyForm.h.
Select a button, two text boxes, and a label from the toolbox and design the GUI
shown in Fig. 18.10. We want to design a program that takes two numbers from the
text boxes and add them together. The result is shown in the label.
Click on the label box to select it. The Text property of label1 is filled with
“label1” string (Fig. 18.11). Clear the “label1” (Fig. 18.12) and press the Enter but-
ton to apply the changes.
Click on the button1 (Fig. 18.10) and change its Text property to “Calc”
(Fig. 18.13). Now the GUI looks like Fig. 18.14.
You will receive an error (Fig. 18.15) if you try to run the code. The error mes-
sage in Fig. 18.15 tells us that our program does not have any entry point. Let’s
define the entry point of the code.
Click the Project> FirstGuiProject Properties (Fig. 18.16) and select the Windows
SubSystem (Fig. 18.17).
18.2 Making a Simple GUI Project 329
Enter main to the Entry Point box (Fig. 18.18) and click the OK button.
[STAThread]
void main(array<String^>^ args) {
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
FirstGuiProject::MyForm form;
Application::Run(%form);
}
Now you can run the code by pressing F5 and the error shown in Fig. 18.15 will
not stop you.
Let’s continue. It is time to write the code to add two numbers together. Double
click on MyForm.h (Fig. 18.22). This opens the designed user interface. Right click
on the form and click the View Code (Fig. 18.23).
332 18 Graphical User Interface
Double click on the Calc button and enter the following code (Fig. 18.25):
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
double a = System::Convert::ToDouble(textBox1->Text,
System::Globalization::CultureInfo::InvariantCulture);
double b = System::Convert::ToDouble(textBox2->Text,
System::Globalization::CultureInfo::InvariantCulture);
double c = a + b;
label1->Text = System::Convert::ToString(c);
}
Run the program and test it. Enter two numbers to the text boxes and click the
Calc button. Two numbers will be added together and the result will be shown
(Fig. 18.26).
Further Readings
1. https://bit.ly/3wRyjPR
2. https://bit.ly/3KQqQak
Index
A E
Address-of operator, 141 Enumeration, 35–37
Arrays in C, 75 Error handling in C, 294, 295
Arrow operator, 164–166, 169 exit function, 134, 135
asctime function, 248–249 Exponential function in C, 187
atexit function, 134–136 extern keyword, 122–123
atof function, 221–222
atoi function, 221
F
fgets function, 206, 287–288
B Fibonacci sequence, 103–105
Binary file in C, 275, 289–294 for loop, 51–65, 82, 83, 206
Binary search in C, 268–273 fprintf function, 279–281
Bitwise operation in C, 199–200 fseek function, 281–283
Break command, 64–65 ftell function, 279
Bubble sort in C, 253–259
G
C getc function, 288–289
calloc function, 87–88 getch function, 239–240
CLR project, 321 gmtime function, 245–247
COM port, 311, 313, 315, 317 Graphical user interface (GUI), 321–333
Conditional ternary operator in C, 42–43
Constants in C, 34, 35
Continue command, 65–66 H
CopyFileA function, 300–303 Hyperbolic function in C, 185–187
C program comments, 16
I
D if command, 39–41
Dereferencing operator, 143 if-else command, 41–42
do-while loop, 51, 64, 70–74 Insertion sort in C, 259–262
© The Editor(s) (if applicable) and The Author(s), under exclusive license to 335
Springer Nature Switzerland AG 2024
F. Asadi, Essentials of C Programming with Microsoft® Visual Studio®,
https://doi.org/10.1007/978-3-031-35711-4
336 Index
U
P Unions in C, 155–169
Pointer arithmetic, 145–146 User defined functions in C, 80
Pointers in C, 75, 77–78, 141–153
Power function in C, 181
V
Variables in C, 17, 19–22, 33–35, 40, 43, 53,
Q 75, 92, 97, 108, 142, 146, 147, 155,
Quick sort in C, 253, 262–264, 266 158, 159, 166, 222
Visual Studio, viii, 1–17, 125, 180, 191,
304, 321
R void pointers, 152–153
Reading the mouse pointer, 136–138
Reading the serial port, 311–313
Recursive function, 104 W
Remove a file in C, 303–304 while loop, 51, 64, 66–67, 70, 216
Remove directory in C, 309 Writing to the serial port, 315–319