Tutorial How to start programming in C++ (Part 5 of 5)

JM Security

Level 31
Verified
Joined
Apr 12, 2015
Messages
2,038
#1
Hi all.

Previous article here: [Tutorial] How to start programming in C++ (Part 4)

Ok... Let's start! I want to start the part 5 of the tutorial with an example:

Acquired a string formed of at least two words and a Word, replaces the second word of the string with the word captured by input.

#include <iostream>

#include <string>

using namespace std;



int main ()

{

string where,put; //string to be processed and the string to insert

int start, end;//word boundary spaces positions to be replaced

int howmany; //How many characters to delete



cout < < "given a string and a word in input" < < endl

< < "puts it in place of the second word of the string";



cout "\n\nInsert the string to be processed"; < <

getline (cin, where);

cout "Word to insert" < <;

getline (cin, put);



//sites search containing the second word



beginning = where. find (' '); /*1*/

end = where. find (' all ', start + 1); /*2*/



//Delete a word, inserting new



How many = -1 (end-start); /*3*/

where = where. erase (begin + 1 how many); /*4*/

where = where. insert (start + 1, put); /*5*/



"new string" cout < < < < endl < < where < < endl;



return 0;

}


In 1 it finds the position of the first space and 2 the second to isolate the word you want to delete.

In 3 calculate the number of characters to delete. Remember, for counting, that the positions are counted from 0.

The message erase launched at where, in 4, has the effect of eliminating from the string a certain amount of

characters. You must specify, as parameters, the location from where to erase (the next to the first space: start

+ 1) and the number of characters to delete. The result of the operation is deposited back into where.

Delete the characters, you can enter in the string the new word. This provides the insert method of the 5, invoked to where. As parameters you specify the starting position of insertion and the string to be inserted. Also in this case the result is a new string, but the program requires that changes be made in the string of departure and, therefore, as in the above statement, the result is assigned to where.

The program also works when the string is composed of a single word. In this case you replace that word.

Multiple choice: switch-case construct

It may be necessary, during a programme, change the following processing on multiple conditions. Could be, for example, the different values that can take a variable. Exist in C++ a construct to encode multiple choice.

Syntactically the structure looks like this:

switch (expression)

case value:

user's instruction

case value:

user's instruction

...

[default: user's instruction]


In the various case statements is a list of values that can take on expression and affecting for processing.

Evaluates the given expression, if the value does not match any of those specified by the instruction included in the default clause if exists. It should be borne in mind that the main difference compared to an if, consists in the fact that, in the alternative, if the various blocks are. The various existing cases act instead by labels: If the expression takes a specified value to a case, statements are run from that point on. The value specified in the case ultimately takes the entry-point function in structure.

If you want to restrict the statements to execute those specified in case that tests the value searched for, you need to insert the break statement that performs a jump and continues processing the statement following the closure of the facility.

To clarify the operation of the facility is a program that counts the parentheses of an algebraic expression.

/* Count various types of brackets contained in an expression

algebraic (does not distinguish between open and close parentheses)

*/



#include <iostream>

#include <string>

using namespace std;



int main ()

{

string espress; string with algebraic expression

string:: iterator it; process for string scanning/* 1 */

int pargraf, parquad, partond; various counters parentheses



//acquisition expression as string



"algebraic \nExpression; cout < <

getline (cin, espress);



//search for parentheses in the expression



pargraf = parquad = partond = 0;



for (it = espress. begin (); it! = espress.end (); it ++) {/* 2 */



switch (* it) {/* 3 */

case ' {':; case '} ':/* 4 */

pargraf ++;

break; /*5*/

case '[':; case ']': /*4*/

parquad ++;

break; /*5*/

case ' (':; case ') ':/* 4 */

partond ++;

break; /*5*/

}

}



//presentation of results



cout < pargraf "\nnumber of { } =" < < < < < endl;

cout < parquad "Square =" < < < < < endl;

cout < < partond "Round =" < < < < endl;



return 0;

}


In 1 declaring a iterator for the sequential scan of the string. The Declaration and how this iterator is

identical to that used previously to scan a carrier.

The cycle that begins with 2 deals with linear scan string: I'll explore all the characters that make it up. The string is treated as a vector of characters.

In the line labeled 3 specifies the expression to be evaluated: * it that is the character of the algebraic

expression that you get deferenziando the iterator.

In rows with tag 4 you review the cases open bracket or parenthesis. The individual values are followed by the statement anything (the only character, and, since processing continues from that point on, whether it's opening parenthesis that parenthesis you get to update the respective counter.

In rows with 5 label hangs program execution otherwise, for example, a brace as well as a brace would be counted as square and round, a bracket would be counted as tonda. Note that, even if there are two instructions,parentheses are not used to delimit the block: switch-case operation provides for the continuation of the processing with the next statement. The last break statement is included only for consistency with the other cases. Also if you were to add a default statement, the program would continue to give consistent results without need for the part to be inserted.

Vectors of strings

The first proposed program takes care to check if some words captured by input, can be found in a dictionary. The dictionary is an array of strings that contains all words that are part of it and that are acquired from input.

#include <iostream>

#include <string>

#include <vector>



using namespace std;



int main ()

{

vector <string> vocab; /*1*/

vector <string>:: iterator it, pos; process for scanning and searching

string stinp,//var for input in vector

parcerc; //search word in the vocabulary

int i;

bool continues;



//Captures words to be inserted in the dictionary



continue = true; /*2*/

for (i = 0;; i ++) {

the "\nword" cout < < < < < "(enter to finish)"; <

getline (cin, stinp);



If (! stinp. empty ())/* 3 */

vocab. push_back (stinp);

else

continue = false; /*4*/

}





//Captures your search word



cout < < "\n\nword to search for (enter to finish)";

getline (cin, parcerc);



While (! parcerc. empty ()) {/* 5 */



//Search for the word



POS = vocab.end ();

for (it = vocab. begin (); it! = vocab.end (); it ++) {/* 6 */

If (* it == parcerc) {/* 7 */

POS = us;

break; /*8*/

}

}



If (pos! = vocab.end ())

cout "\nWord found, position < < < < pos-vocab. begin ();

else

"\nWord not found" cout < <;



//Next word search



cout < < "\n\nWord to search for (enter to finish)";

getline (cin, parcerc);

}



return 0;

}


In 1 declares vocab as a vector of strings.

The cycle of acquisition of words in your vocabulary, is controlled by the value of the Boolean variable (2). If

the input is empty (3), the value is set to false (4) and the loop terminates.

Also the loop for input of words to search for (5) behaves similarly: If the string is empty, the processing ends.

The only difference with the previous cycle is that, here, you do not see a word count.

In cycle 6 vocabulary is scanned in search, if any, to match the searched string (7). If the word is present in

the vocabulary the 8 deals with force quit the loop. It is useless to continue scanning the vocabulary words.

The second proposed program extracts from a text all words that make it up and place it into a vector:

#include <iostream>

#include <string>

#include <vector>

using namespace std;



int main ()

{

string text, extracted; //text processing, word extracted

vector <string> token; //words extracted

vector <string>:: iterator it;

int start, end,//pos boundary Word spaces

lword;

bool continues;



cout < < "extract all the words in a text" < < endl;

cout "\nText" < <;

getline (cin, text);



//Extracting words (Word enclosed by spaces)

//between two words there is only one space



continue = true;

Start = -1; /*1*/

While (continued) {



end = text. find (' all ', start + 1); /*2*/



//last word



If (end == -1) {/* 3 */

continue = false;

end = text. length (); /*4*/

}



//Extracting Word



lword = -1 (end-start); /*5*/

extracted = text.substr (start + 1, lword); /*6*/

token. push_back (extracted); /*7*/



start = end; /*8*/

}



//List words



cout "\nWords: " < < < < endl;



for (it = token. begin (); it! = token.end; ++ it)

cout < < * en < < endl;



return 0;

}


We start by initializing the variable start processing (1) which will be the location, the space that precedes the word, from which to start the search space that delimits the end of the word to be extracted (2). The word is delimited by spaces that are in the start position and end position (2). The pair of values contained in these variables, is used to calculate the amount of characters that make up the word.

If you have arrived at the end of the text to be processed (3 control), as well as make false the loop control condition in order to close its processing, is assigned at the end of the text length (4). It's as if you should reach the end in space after the last character of the text.

The length of the word, and thus the amount of characters you want to extract, is calculated in 5. Character extraction is carried out by the substr method invoked for the text string, pass in the location from which to draw (the one after the location of the space that precedes the word) and the number of characters to extract (6).

The word is then (7) inserted into a vector.

8 allocation aims to move ahead in the search for the next word, by assigning as a starting point for research, the end point of the previous processing.

The procedural paradigm

Building a program: top-down development


A paradigm is "a set of scientific ideas collectively agreed to make sense of the world of phenomena" (T.S. Khun).

Apply a paradigm means applying a technique to write good programs. In this and the following paragraphs will be exposed on procedural paradigm which can be summarised as follows: "give a desired procedures; you are using better algorithms. "

Often, especially in complex problems, that same sequence of instructions that appear in the same form in several parts of the same program or that is used in multiple programs. Abstract data processing algorithms affect that can be adapted to seemingly different problems (from the it perspective two issues are different if they require different processing and not if they treat different things). As an example regarding other disciplines just think, for example, geometry: computing the area of a surface varies according to the different geometric form and not to the nature of the object. The area of a banknote or a marble slab is calculated the same way as in both cases of rectangles. The development concerning the calculation of the area of a rectangle will recur in the computing problems of marble blocks as well as in computing problems of sheets to print banknotes.

To save unnecessary work of rewriting existing code, programming languages include the use of subprograms.

Essentially a subprogram is a program that performs a function.

The use of subroutines is not just limited to labor saving of rewriting some code, but it is also a tool that can address complex problems reducing them to a set of problems to fix gradually lower. All this allows the programmer more control over the program itself by hiding in the resolution phase of the individual subprogramme, other parts in such a way as to isolate the individual aspects of the problem to be solved.

This is the process of preparation for subsequent refinements (or top-down). When the complexity of the problem grows, it becomes difficult to take account simultaneously of all aspects involved, down to the smallest detail, and take all decisions of realization: in that case it will be necessary to proceed by trial and error, i.e. to decompose the problem into simpler problems early. In this way we will address the resolution of initial problem considering in a first approximation, by other programs to lower hierarchical level, aspects of the same problem.

You will then each of under-problems in a similar way.

Ultimately it begins by specifying the sequence of progress for the solution of the problem proposed even if, at this early stage, may lack the details of realization: it is assumed that these details already exist. The program, in this first draft, will contain, in addition to the usual control structures, even complex operations which have to be further specified. Through the examination of a single work phase, it can still provide for complex actions but will cover, for how it was derived, a part of the initial problem. By iterating the proceedings, you will consider programs that involve increasingly limited parts of the initial problem. Thus solving a complex problem was traced back to resolution of more simple problems (as many are the tasks provided for in the original processing).

The next decomposition process is not fixed unambiguously: depends strongly on the subjectivity of the programmer. There are no rules about the amount of pieces that break down the program. There are some general guidelines that suggest to limit the single segment sufficiently in that the code does not exceed the screen of a video so that it covers, with the look, the entire or nearly listing and limit the individual segment a few actions so that it is easier to isolate errors. In addition the subprogram must be isolated from the context in which it operates, i.e. must have within it everything it needs and does not refer to particular data present in the main program. This leads to some definite advantages:

The subprogram is easily exportable. If breaking out of other programs you see that you need to use the same processing you can reuse the subprogram. It is clear that for this to be possible the subprogram must not reference contexts which in this case may be different. In addition, if the subprogram performs one operation you will have more opportunities to insert it into new elaborations.

The program maintenance is simplified by the fact that, by doing a single subprogram elaboration and, having within it all that is needed, if there is an error in processing this is completely isolated in the subprogram itself and thus more easily traceable.

If you need to change a portion of the program, this can be done easily: just replace only the subprogram that performs processing to edit. The rest of the program is not affected by the change made.

The use of subprograms ready for the construction of a new program leads to a development methodology that is commonly referred to as bottom-up because it represents an approach opposite to that described so far. We start from the existing subroutines that are assembled together with new to build new processing.

Communications between subprograms

Following the procedure for subsequent decompositions you get to the end of a main program that coordinates the actions of a number of subprograms to arrive at the expected result. The main program calls in a certain order the subprograms (Lance executing statements that are part of it); each subprogramme over which can also be called the caller of an additional subprogramme. Finish the subprogram execution resumes in the caller, from the statement following the call.

You can tell that all the subprograms are part of an organic whole: everyone contributes, for part of its
jurisdiction, to a final processing that is set by the main program. Final processing request is the result of cooperation of the individual parts; each subprogramme (System Unit) receives its input (defined as the sum of the information necessary for the performance of their duties) by the calling subprogram and returns their output (defined as the sum of the information produced within it). These, in turn, could provide inputs for an additional subprogramme.

To ensure as much as possible the portability and independence of subprograms, structured languages distinguish variables according to the visibility (scope). In relation to the visibility variables are divided into two main families:

Global variables visible from all subprogrammes. All subprograms can use them and modify them. Are pretty much common heritage.

Local variables are only visible from the subprogram that declares them. The other subprogrammes, even if called, I do not have access to these variables. The local variable is defined in the subprogram and is usable here. If you call a subprogram caller's variables are masked (not accessible) and will continue to be seen when the call ends and you are returned to the caller. The caller's environment (the set of variables and their values) at this point will be restored exactly as it was before the call.

As mentioned several times would need to use as little as possible (almost deleting) global variables to minimize dependence on context by the subprogramme.

However, processing, covering common data requires that the calling program is in a position to communicate with called. Either exist of the calling conventions of conventions that allow the caller to communicate parameters which will represent the inputs on which will operate the callee. On the other hand the callee will need to return to the caller of the parameters that will contain the results of their processing and can be handled later. These conventions are generally known as passing parameters.

Passing parameters can be done in two ways:

It says that a parameter is passed by value (from the caller to the callee) if the caller tells the called the value that is contained in that moment, in a variable. The callee will set up its own local variable in which you copied it. The callee can operate on that value, it can also change it but those changes will affect only the local copy on which you are working. Once the subprogramme the local variable disappears along with the value that contains the caller's variable is restored and the value that it contained before the call to the subprogram.

It says that a parameter is passed by reference or by address if the caller tells the called the memory address of
a particular variable. The callee can use a different name for the variable, but the memory location to which it refers are always the same. You simply set a different reference the same memory locations: any changes you make will affect the original variable, although the new name ceases to exist at the end of the subroutine.

To synthesize just about what pass by value and what to reference, it can be said that the inputs of a subprogram are passed by value while the outputs are passed by reference. The inputs of a subprogram are useful at the same to make their own calculations while the outputs are the products of their processing should be made available to the caller.

Visibility and namespace

The application of functional paradigm leads to build libraries containing functions that deal with the

elaborations concerning families of problems. Libraries expand the potential of language: the instruments made available by standard language, you can add all the features that are used to facilitate the resolution of a given issue. Just include the library in the program that you intend to use and this is a procedure that is adopted from writing your first program, when it is stated the desire to use functions, for example, iostream.

Multiple libraries can lead to ambiguity if, for example, there are the same names in multiple libraries. C++, to resolve problems of this kind, provides the namespace, that delimit the visibility of names declared in them.

#include <iostream>

using namespace std; /*1*/



John namespace {/* 2 */

int a = 5;

};

Frank namespace {/* 3 */

int a = 10;

int b = 8;

};



int main ()

{

cout:: endl to < < John < <; /*4*/

Frank:: a cout < < < < endl; /*5*/

cout Frank:: b < < < < endl; /*6*/



return 0;

}


The Declaration of 1 makes all the names in namespace std. Available libraries in C++ (iostream, string, vector, etc.) have names (cin, cout, etc ...) are included in this namespace.

In 2 John declares that contains within it a variable which is changed to a different value from that assumed by a variable with the same name, declared in the namespace Frank (3).

In 4 you request printing of variable a is defined in the namespace John. Operator::, operator visibility, allows you to specify which namespace must be sought the variable a. Without this operator, the compiler would generate an error: it is not defined, in the main, any variable.

The value printed as a result of the execution of 5 is different from the previous, since here we are referring to a variable defined in namespace test2.

You could add a line like:

using namespace John;



and, in this case, it was not necessary to use the default visibility on 4.

#include <iostream>

using namespace std;



John {namespace

int a = 5;

};

Frank {namespace

int a = 10;

int b = 8;

};



using namespace John; /*1*/

using namespace Frank; /*1*/



int main ()

{

cout:: endl to < < John < <; /*2*/

Frank:: a cout < < < < endl; /*2*/

cout < < b < < endl; /*3*/



return 0;

}


You can do so, as in 1, to make available two namespace names, and hence have the ability to access the content without needing to specify the default visibility:: but, in this case, this possibility can only be exploited if the 3. In the other two cases of use (2) you must specify the namespace because the reference is ambiguous. This would also be the nature of the error highlighted by the compiler, if you do not use the default visibility: the variable is defined in both the namespace and the compiler cannot decide which refer. In general it can be convenient to use a using namespace statement to the standard libraries of language but specify the visibility in all other cases.

If the same namespace is defined more than once, each new definition expands the previous one: all variables are defined within a single namespace even if you state at different times.

Types of subprograms

In the preceding paragraphs has been spoken of generically subprograms because it wanted to highlight the common

properties. In General a distinction is made between two types of subprograms:

The functions. Are subroutines which return a value to the calling program. The call to a function produces, come back when this last has completed its processing, a value that can be assigned to a variable and functions are used mainly to the right of the assignment.

The procedures. Are subroutines that do not return a value; dealing with one stage of processing

It should be noted that the first does not exhaust the communications between subprogrammes. From what has been said in fact, it might seem that all communication between caller and callee they sell out, at best (functions) in a single value. In fact the communication is played mostly on passing parameters, then a procedure can change multiple variables: just get to reference those variables.

In the C++ programming language every subprogram has a name and the subprograms are called by specifying its name and scope of vision.

Functions in C++: The return statement

In C++ all subprogrammes are functions. In order to simulate the procedures that do not return any value type void. The void type or undefined type is used by C++ whenever the return value of a function should not be taken into account. In practice procedures in C++ are functions that return a void.

Construction and use of a function, can be summarized in three stages:

The prototype for the function. It is common to declare it at the beginning of the program, before the definition of the main function, or in any case prior to the calling function. The general structure of the prototype of a function is:

return-type function-name (Declaration parameter types);





The prototype represents the interface of the function: how many parameters need to function to perform their tasks and their type. Specifies how to use the function: the return type provides indication about the type of variable that should be assigned the value returned by the function, the amount with the type specification indicates the number of variables/values, and that type must be specified as parameters to use properly the function.

Prototypes were introduced to allow the compiler to check the quantity and types of parameters: knowing in advance, in fact, at the time of the call, you can determine if the parameters passed are congruent with those expected. For this reason in the prototype do not need to specify the name of the parameters (bug in the local variables of the function): only the amount and type are indispensable.

In the construction of complex programs happen to use many functions. In this case the functions can be grouped into libraries and their prototypes grouped in header files (header files). You have got to use libraries of functions from the outset. For example are what cout are functions (actually they are objects, but this will be explained later) contained in a system library that is included, at the time of compilation, in our program. These functions are defined in namespace std iostream header that is included at the beginning of the program.

The function call. Is simply to specify where it is necessary to use the processing provided by function, the name of the function itself, possibly preceded by the visibility and the namespace in which it is defined, and the list of passed parameters. The calling program can use the value returned by the function, in which case the function name will appear, for example, in an expression. The caller can also overlook the return value even though it is not of type void. Just use the function without assign its return value.

The function definition that is the list of operations carried out by the function itself. The definition begins by specifying the type of value returned just after you specify the name chosen as desired by the programmer and in line with the rules of choosing the name of variables, then follows the list of parameters and finally local declarations and instructions as well as the following diagram where is highlighted also the writing style:

returned-type function-name (parameters)

{

statements and instructions

}


The first line of the definition differs from the prototype to the fact that, here, there are local variable declarations and, in addition, the line does not end with semicolon but is followed by a block which contains the instructions contained in the function. The Declaration of the parameters follows, in principle, the rules of defining variables used in the other examples treated before, except for: the parameters are separated by commas for each type you can declare one variable. Is not possible with a single type to declare multiple parameters, you must repeat the type declaration

If the parameter is passed by value his statement reflects that of the generic declaration of a variable. If the parameter is passed by reference type must be followed by the character & as in the example:

int function (int first, float & seconds)

{

...

};


The definitions of functions may be written at any point in the program which will run as a result of the call, and then would have no importance on physical place where are allocated. However, the common coding conventions that function definitions are coded after the main.

Among the instructions in the function definition particularly important the return statement is used to return the value to the caller. The syntax of the plan to specify the keyword return a constant value or a type-compatible variable-returned by the function.

Example:

return 5; Returns to the caller the value 5

return a; Returns to the caller the value held in variable




If the function returns void type the return statement is missing.

It does not matter that the definitions of all functions used in a program to follow the order in which they are called though, in the interests of clarity and readability, it should be so and you track the order specified before. In any case the function with the name main (which is a reserved name) is executed first when the program starts, no matter where it is placed, and the functions are executed in the order in which they are called.

Accordingly, as required by the syntax can be observed, moreover, that main is a function that returns an integer value. This is all part of a conception of the functions inherited from C language: a function always returns a value that indicates the correct conclusion of the processing (0 value or other value if you are having problems).

And this is also why in C all subprogrammes are functions.


Previous article here: [Tutorial] How to start programming in C++ (Part 4)

Suggested books:
"C++: The Ultimate Beginner's Guide!" (by Andrew Johanse) or "Jumping into C++" (by Alex Allain).


EDIT:

Example of top-down program:

#include <iostream>/* 1 */

#include <vector>/* 1 */

using namespace std;



//prototypes



int main ()

{

vector <int> numbers,//vector to process/* 2 */

par; //subset of peers



"extraction of subset:" cout < < < < endl

< < "given a sequence of positive integers" < < endl

"communicates the subset of peers" < < < < endl;



//input numbers to be processed



//extracting subset of peers



//output subset equal



return 0;

}
Thanks for reading ;)
 
Last edited:
L

LabZero

Guest
#2
C++ is a language for object-oriented programming and it is an ideal platform to realize projects by supporting the abstraction of the problems.
This allows you to develop software according to design patterns using ready libraries and can be integrated with the projects.
C++ derives from C (personally appreciate the ability to code at low-level) allowing you to write programs of all sizes and using stack framework at high level, or work at a low level by integrating assembly instructions.

Good job.:)
 

JM Security

Level 31
Verified
Joined
Apr 12, 2015
Messages
2,038
#4
C++ is a language for object-oriented programming and it is an ideal platform to realize projects by supporting the abstraction of the problems.
This allows you to develop software according to design patterns using ready libraries and can be integrated with the projects.
C++ derives from C (personally appreciate the ability to code at low-level) allowing you to write programs of all sizes and using stack framework at high level, or work at a low level by integrating assembly instructions.

Good job.:)
Yes, I also think that C++ is a really good and obviously fast language, because it is a low-level language, so usually it doesn't take enormous time to compute operations. But, I also I think there are other languages, which I like a lot, that don't take a lot of time to compute specific operations, for example Fortran, C#, VB .Net; even if C# and VB .Net aren't low-level languages; but they are advanced programming language.

@frogboy Thanks bro, really appreciated ;)