modern_cpp_3-C++ Basic Syntax

Posted by aswini_1978 on Sat, 22 Jan 2022 06:45:58 +0100


Slides of structure 2: Modern C++ for Computer Vision Lecture 2: C++ Basic Syntax (uni-bonn.de)

This part mainly introduces the keywords, entities, entity declarations and definitions, types, variables, naming rules of identifiers, expressions, if else structures, switch structures, while loops, for loops, arithmetic expressions, conditional expressions, self increasing and self decreasing in C + +

if(STATEMENT){
	//...
}
else{
	//...
}

switch(STATEMENT){
	case 1: EXPRESIONS;break;
	case 2: EXPRESIONS;break;
}

while(STATEMENT){
	//...
}

for(int i=0;i<10;i++){
	//...
}

Spooler alert (supplementary)

1. For loop in C + + 17 and python 3 Comparison of for loops in X

In the latest C++ 17 standard, the new writing method of for loop is compared with that in Python:

//Pythonic Implementation
my_dict = {'a':27,'b':3}
for key,value in my_dict.items():
	print(key,"has value",value)
// Implementaion in c++ 17
std::map<char,int> my_dict{{'a',27},{'b',3}}
for (const auto&[key,value]:my_dict)
{
    std::cout<<"has value"<<value<<std::endl;
}

It can be seen that the new standard has Python taste, but the implementation of C + + is 15 times faster than Python:

2. Built-in types

For the "Out of the box" type in C + + (Out of the box), you can refer to Fundamental types - cppreference.com

int a = 10;
auto b = 10.1f ; // Automatic type [float]
auto c = 10; //Automatic type [int]
auto d = 10.0 ; // Automatic type [double]
std::array<int,3> arr={1,2,3}; // Array of intergers

The automatic type here is also a bit like Python.

3. C-style strings are evil

C + + can be programmed in C style like other types in C:

#include<cstring>
#include<iostream>

int main(){
    const char source[] = "Copy this";
    char dest[5];
    std::cout<<source<<std::endl;
    std::strcpy(dest,source);
    std::cout<<dest<<std::endl;
    //Source is const, no problem right
    std::cout<<source<<std::endl;
    return 0;
}

You may think that the source is const char type and should not be changed, but the result is unexpected. This is the so-called "C-style strings are evil", so it is more recommended to use Strings type. There is this

Several precautions:

  1. #std::string can be used after include < string >
  2. string type implements operator overloading and can be spliced with +;
  3. You can check whether STR is empty through str.empty();
  4. It can be combined with I/O streams to play tricks

For example, in the above example, we use the string type in C + +:

#include<iostream>
#include<string>

int main(){
    const std::string source{"Copy this"};
    std::string dest = source;
    std::cout << source << '\n';
    std::cout<< dest <<'\n';
    return 0;
}

The result of this operation is completely expressed.

Add: why is there such a mistake in the first example? We found std::strcpy Official description , the signature of this function is:

char* strcpy( char* dest, const char* src );

Copies the character string pointed to by src, including the null terminator, to the character array whose first element is pointed to by dest.

The behavior is undefined if the dest array is not large enough. The behavior is undefined if the strings overlap.

Let's take a look at the function prototype of strcpy:

//C language standard library function strcpy is a typical industrial simplest implementation.
//Return value: the address of the target string.
//The ANSI-C99 standard does not define exceptions, so the return value is determined by the implementer, usually NULL.
//Parameters: des is the target string and source is the original string.

char* strcpy(char* des,const char* source)
{
    char* r=des;
    assert((des != NULL) && (source != NULL));
    while((*r++ = *source++)!='\0');
    return des;
}
//while((*des++=*source++)); Explanation: the assignment expression returns the left operand, so the loop stops after assignment '\ 0'.

In fact, it's not a language problem here. Both source and dest are located in the stack area and adjacent to each other in memory. Therefore, DeST's memory overflows into source, overwriting the previous part of source and adding \ 0. The location information of both is as follows:

+--------+
...
+--------+
| src[2] |   <--- -0x5
+--------+
| src[1] |   <--- -0x6
+--------+
| src[0] |   <--- -0x7
+--------+
| dest[3]|   <--- -0x8
+--------+
| dest[2]|   <--- -0x9
+--------+
| dest[1]|   <--- -0xa
+--------+
| dest[0]|   <--- -0xb
+--------+

How to avoid buffer Overflow caused by insufficient memory space pointed to by dest?

Here is an official example. In order to avoid unpredictable behavior caused by insufficient dest length, the length of src is adjusted according to the length of src:

#include <iostream>
#include <cstring>
#include <memory>
 
int main()
{
    const char* src = "Take the test.";
//  src[0] = 'M'; // can't modify string literal
    auto dst = std::make_unique<char[]>(std::strlen(src)+1); // +1 for the null terminator
    std::strcpy(dst.get(), src);
    dst[0] = 'M';
    std::cout << src << '\n' << dst.get() << '\n';
}

Of course, you can also use more secure strncpy or strcpy_s.

4. Any variables can be const

It's worth noting that any type can be declared const as long as you're sure it won't change.

Google style names constants with camelCase and starts with the lowercase letter k, for example:

const float kImportantFloat = 20.0f;
const int kSomeInt = 20;
const std::string kHello = "Hello";

Add: Google style names variables in snake_case, and all of them are lowercase letters, such as some_var.

Variable reference is also a very common usage, which is faster and less code than copying data, but sometimes we use const to avoid unwanted changes.

5. I/O streams

#Include < iostream > to use I/O stream

Here are the commonly used String streams:

  1. Standard output cerr and cout
  2. Standard input cin
  3. File streams fsstream, i fstream and ofstream
  4. String stringstream can convert the combination of int, double, string and other types into string, or decompose strings into int, double, string, etc.

6. Program input parameters

C + + allows parameters to be passed to binary files. For example, the main function can receive parameters:

int main(int argc,cahr const *argv[])

Where argc represents the number of input parameters and argv is the array of input strings. By default, the former is equal to 1 and the latter is equal to "< binary_path >"

Topics: C++ Back-end