C++ data types and function design learning records

1. C++ type conversion principles

        When mixed operations involving multiple types of data appear in an expression, type conversion is often required. Type conversion in expressions is divided into two types: implicit conversion and explicit conversion, but only implicit conversion is summarized here.

        Implicit conversion is divided into two categories: arithmetic conversion and other implicit type conversions. Other implicit type conversions mainly include array conversion to pointer, pointer conversion, Boolean type conversion, constant conversion, etc. [1]. Among them, if the operand types involved in the operation are inconsistent in arithmetic operations and relational operations, the compilation system will automatically convert the data (implicit conversion). The basic principle of this conversion islow type data conversion It is high type data [2].

1 implicit conversion

1.1 Arithmetic conversion

        May May possible when possible in 1 May possible in May 11th in May Category height/low order (Yū-low-supreme):char-short- int-unsigned-long -unsigned long-float -double.

        ② If one operand is an unsigned type and the other operand is a signed type, and the unsigned type is not smaller than the signed type, then the signed operand is converted to unsigned. It should be noted that if the signed type is a negative number, the negative number will be converted into a positive number according to "modulo tending to negative infinity".

        ③Based on ②, if the signed type is larger than the unsigned type, the conversion depends on the number of bytes represented by the machine on the type, such as int, long.

        [Note: The ISO C++ standard does not clearly stipulate the number of bytes and value range of each data type. It only stipulates that the order of the number of bytes between them satisfies: (signed/unsigned) char ≤ (unsigned) short ≤ ( unsigned)int ≤ (unsigned)long】

1.2 Other implicit type conversions

1.2.1 Convert array to pointer

        In most expressions that use arrays, the array is automatically converted into a pointer to the first element of the array, such as function parameter expressions, etc. However, the above implicit conversion will not occur when an array reference is used as a parameter of the decltype keyword, when the address character is &, when acting on sizeof, or when acting on typeid.

1.2.2 Pointer conversion

        The constant integer value 0 or the literal value nullptr can be converted to any pointer type; a pointer to any non-constant can be converted to void*; a pointer to any object can be converted to const void*.

1.2.3 Boolean type conversion

        If the value of the pointer or arithmetic type is 0, the conversion result is false; otherwise, the conversion result is true.

1.2.4 Constant conversion

        The pointer that is allowed to point to a very small -scale type is allowed to be converted into pointers that are pointing to the corresponding constant type, which is the same for reference.

2. Operator precedence and associativity

Picture source: C++ language programming / edited by Zheng Li and Dong Yuan

3. Function Basics

(1) Basic concepts

        Automatic object: For objects corresponding to ordinary local variables, the object is created when the control path of the function passes through the variable definition statement, and is destroyed when it reaches the end of the block where the definition is located. it. We call objects that exist only during the execution of a block as automatic objects ("block" refers to the program block contained in "{}").

        Local static object: The local static object is initialized when the execution path of the program passes the object definition statement for the first time, and is not destroyed until the program terminates. During this period, even if the object is It will not be affected if the function ends execution (Create a local static object, that is, define the local variable as a static type).

        Parameter passing of function: ①The type of formal parameter determines the way the formal parameter and actual parameter interact. If the formal parameter is a reference type, it will be bound to the corresponding actual parameter. At this time, the corresponding actual parameter is passed by referenceor< a i=4>The function is called by reference; otherwise, when the value of the actual parameter is copied to the formal parameter, the formal parameter and the actual parameter are two independent objects. At this time)array does not allow copying, and array parameters cannot be used in value transfer mode. (It should be noted that The function is called by valueorThe actual parameters are passed by value

                                    ② When the initialization of the actual parameters will be ignored on the top of the top, the top layer is ignored. That is, when the formal parameter has a top-level const, it is okay to pass it a constant object or a non-const object.

        Function overloading : If several functions in the same scope have the same name but different formal parameter lists, we call it an overloaded function. For overloaded functions, they should be in formal parameter number or formal parameter type< a i=5> (two functions are not allowed to have all other elements the same except the return type).

        Inline function: Request the compiler to expand the function at the call point if possible (define an inline function, that is, add the inline flag before the function). Generally speaking, the inlining mechanism is used to optimize functions that are small in size, have direct processes, and are called frequently. (Additional understanding:Calling a function is generally slower than finding the value of an equivalent expression. On most machines, a function call actually contains a Series work)

        Function pointer: The function pointer points to a function rather than an object. Like other pointers, function pointers point to a specific type. The type of a function is determined by its return type and formal parameter type , regardless of the function name.

        tuple type (standard library special type): tuple is a template similar to pair. Different tuple types have different member types, but a tuple can have any number of members. The number of members of each specific tuple type is fixed, but the number of members of one tuple type can be different from that of another tuple type. The main purpose of tuple is to combine some data into a single object without defining a new data structure to represent it.

Picture source: C++ Primer Chinese version: 5th edition/(U.S.) Lippman, S.B., (U.S.) Lajoie, J., (U.S.) Moo, B.E.; Wang Gang, Translated by Yang Jufeng.

(2) Experimental practice

1. Top-level const reference (constant reference) formal parameters affect practice

Experimental basic code:

# include<iostream>
# include<string>

using namespace std;

// 打印出字母串内包含的大写字母,并将大写字母改写为小写字母
// 注:该展示原始代码报错,左值*b不可修改
void ToUpper(const string &str)
{
	for (auto b = str.begin(); b != str.end(); ++b)
		if (isupper(*b))
		{
			cout << *b << endl;
			*b = tolower(*b);
		}
	return;
}

int main()
{
	const string test_string = "AppLe";
	cout << "原始测试数据:AppLe" << endl;
	ToUpper(test_string);
	cout << "测试后数据:" + test_string << endl;
	return 0;
}

Experimental results chart:

Experimental conclusion notes:

        ​ ​ ​ Try to use constant references without changing the incoming data. The reasons are: 1. Defining the formal parameters that the function will not change as ordinary references can easily lead to misunderstanding, that is, the function can modify the value of its actual parameters; 2. Using ordinary references instead of constant references will greatly limit the actual parameters that the function can accept. Type, as shown in Figure 6 and Figure 7.

2. Simple design method for multiple return value functions

Experimental code:

# include<iostream>
# include<string>
# include<vector>

using namespace std;

// 同类型多值返回
// 返回A大写字母开头的单词
vector<string> F1_Msame(const vector<string> wordList)
{
	vector<string> A_List;
	for (const string word : wordList)
		if (*(word.begin()) == 'A')
			A_List.push_back(word);
	return A_List;
}


int main()
{
	// 测试数据
	vector<string> test_data = {"bar","A","crush","brush","Apple","view","Aka"};
	vector<string> result = F1_Msame(test_data);
	for (auto w : result)
		cout << w << "   ";
	return 0;
}
# include<iostream>
# include<string>
# include<vector>
# include<tuple>

using namespace std;

// 不同类型多值返回
// 返回每一个A大写字母开头的单词与它所对应的索引值
vector<tuple<string, size_t>> F2_Mdiff(const vector<string> wordList)
{
	vector<tuple<string, size_t>> Aidx_List;
	for (size_t i = 0; i != wordList.size(); ++i)
		if (wordList[i][0] == 'A')
			Aidx_List.push_back(make_tuple(wordList[i],i));
	return Aidx_List;
}


int main()
{
	// 测试数据
	vector<string> test_data = {"bar","A","crush","brush","Apple","view","Aka"};
	vector<tuple<string, size_t>> result = F2_Mdiff(test_data);
	for (tuple<string, size_t> w : result)
		cout << "(" << get<0>(w) << ','<< get<1>(w) << ')' <<endl;
	return 0;
}

Experimental results chart:

Experimental Notes:

Ⅰ The literal value contained in double quotes "" is the string char*, and the literal value contained in single quotes "" is the character char;

Ⅱ The new C++11 standard stipulates that functions can return a list of values ​​surrounded by curly braces {}. The list returned here is used to initialize the temporary that represents the function return. If the list is empty, the temporary performs value initialization; otherwise, the value returned is determined by the function's return type.

3. Function pointer practice (Exercise 6.54/Exercise 6.55/Exercise 6.56)

Experimental code:

# include<iostream>
# include<vector>

using namespace std;


// 函数一:对两个int类型进行加法运算
int intAdd(int a,int b)
{
	int c = a + b;
	return c;
}

// 函数二:对两个int类型进行减法运算
int intSub(int a, int b)
{
	int c = a - b;
	return c;
}

// 函数三:对两个int类型进行乘法运算
int intPro(int a, int b)
{
	int c = a * b;
	return c;
}

// 函数四:对两个int类型进行除法运算
int intDiv(int a, int b)
{
	int c = 0;
	if (b == 0)
		throw runtime_error("除数不能为零!");
	else
		c = a / b;
	return c;
}


int main()
{
	vector<int (*)(int, int)> FuncCalList = {intAdd,intSub,intPro,intDiv};
	for (auto Fptr : FuncCalList)
		cout << Fptr(2, 4) << endl;
	return 0;
}

Experimental results chart:

Experimental Notes:

Ⅰ When the function name is used as a value, the function is automatically converted into a pointer;

Ⅱ You can directly use the pointer to the function to call the function without dereferencing the pointer in advance;

References:

[1] C++ Primer Chinese version: 5th edition/(U.S.) Lippman, S.B., (U.S.) Lajoie, J., (U.S.) Moo, B.E.; Wang Gang, Translated by Yang Jufeng. —Beijing: Electronic Industry Press, 2013.9. (Chapter 4 - Expressions, Chapter 6 - Functions)

[2] C++ Language Programming / Zheng Li, Dong Yuan eds.—5th edition.—Beijing: Tsinghua University Press, 2020.11. (Chapter 3-Function)

Debug reference:

[3] C++ does not allow the use of incomplete type specifications-CSDN Blog

Guess you like

Origin blog.csdn.net/Jcb1906824038/article/details/134972504