前言

介绍一些 C/C++ 标准库和可移植操作系统接口(Portable Operating System Interface,缩写为 POSIX)。

C/C++ Reference: https://cplusplus.com/reference/

操作系统:Ubuntu 20.04.4 LTS

下面是各个章节的快速索引:

  1. C Library

  2. Containers

  3. Input/Output Stream Library

  4. Atomics and threading library

  5. Miscellaneous headers

  6. C++ 语法

  7. 计算机基础

  8. 常用的 C++ 内置函数

参考文档

  1. 可移植操作系统接口

  2. C/C++ Reference

  3. <cstdio> (stdio.h)

  4. fopen

  5. fclose

  6. fputc

  7. rewind

  8. fscanf

  9. fwrite

  10. fread

  11. <cstring> (string.h)

  12. strcmp

  13. <string>

  14. std::to_string

  15. puts

  16. fputs

  17. 右移运算符

  18. exp

  19. calloc

  20. memcpy

  21. memset

  22. free

  23. atof

  24. atoi

  25. memcmp

  26. <algorithm>

  27. sort

  28. fabs

  29. c_str

  30. rand

  31. ASCII

  32. cout

  33. pair

  34. begin

  35. fprintf

  36. fgetc

  37. feof

  38. cerr

  39. min

  40. std::map::operator[]

  41. std::vector::operator[]

  42. size

  43. size

  44. clear

  45. clear

  46. count

  47. resize

  48. operator=

  49. push_back

  50. fseek

  51. strtok

  52. scanf

  53. std::array::begin

  54. std::transform

  55. const修饰成员函数

  56. ASCII 码表

  57. std::is_same

  58. std::tie

  59. std::ignore

  60. std::remove_reference

  61. std::boolalpha, std::noboolalpha

  62. std::make_tuple

  63. std::tuple_sizestd::tuple

  64. std::accumulate

  65. acos

  66. std::distance

  67. std::exception::what

  68. std::advance

  69. std::next

  70. std::multiplies

  71. std::find, std::find_if, std::find_if_not

  72. std::list<T,Allocator>::splice

  73. std::partition

C Library

<cmath> (math.h)

<cmath> (math.h): https://cplusplus.com/reference/cmath/

<cmath> (math.h): C numerics library.

Trigonometric functions

  • acos: Compute arc cosine (function)

acos

acos: https://cplusplus.com/reference/cmath/acos/

double acos (double x);

Compute arc cosine

Returns the principal value of the arc cosine of x, expressed in radians.

In trigonometrics, arc cosine is the inverse operation of cosine.

Header <tgmath.h> provides a type-generic macro version of this function.

Parameters

x

Value whose arc cosine is computed, in the interval [-1,+1].

If the argument is out of this interval, a domain error occurs.

Return Value

Principal arc cosine of x, in the interval [0,pi] radians.

One radian is equivalent to 180/PI degrees.

If a domain error occurs, the global variable errno is set to EDOM.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* acos example */
#include <stdio.h> /* printf */
#include <math.h> /* acos */

#define PI 3.14159265

int main ()
{
double param, result;
param = 0.5;
result = acos (param) * 180.0 / PI;
printf ("The arc cosine of %f is %f degrees.\n", param, result);
return 0;
}
输出
1
The arc cosine of 0.500000 is 60.000000 degrees.

Exponential and logarithmic functions

  • exp: Compute exponential function (function)

exp

exp: https://cplusplus.com/reference/cmath/exp/

double exp (double x);

Compute exponential function

Returns the base-e exponential function of x, which is e raised to the power x:exx: e^x.

Parameters

x

  1. Value of the exponent.

Return Value

Exponential value of x.

Example

1
2
3
4
5
6
7
8
9
10
11
12
/* exp example */
#include <stdio.h> /* printf */
#include <math.h> /* exp */

int main ()
{
double param, result;
param = 5.0;
result = exp (param);
printf ("The exponential value of %f is %f.\n", param, result );
return 0;
}
输出
1
The exponential value of 5.000000 is 148.413159.

Other functions

  • fabs: Compute absolute value (function)

fabs

fabs: https://cplusplus.com/reference/cmath/fabs/

double fabs (double x);

Compute absolute value

Returns the absolute value of x: |x|.

Parameters

x

  1. Value whose absolute value is returned.

Return Value

The absolute value of x.

Example

1
2
3
4
5
6
7
8
9
10
/* fabs example */
#include <stdio.h> /* printf */
#include <math.h> /* fabs */

int main ()
{
printf ("The absolute value of 3.1416 is %f\n", fabs (3.1416) );
printf ("The absolute value of -10.6 is %f\n", fabs (-10.6) );
return 0;
}
输出
1
2
The absolute value of 3.1416 is 3.141600
The absolute value of -10.6 is 10.600000

<cstdio> (stdio.h)

<cstdio> (stdio.h): https://cplusplus.com/reference/cstdio/

<cstdio> (stdio.h): C library to perform Input/Output operations.

File access

  • fopen: Open file (function)

  • fclose: Close file (function)

fopen

fopen: https://cplusplus.com/reference/cstdio/fopen/

FILE * fopen ( const char * filename, const char * mode );

打开文件

Opens the file whose name is specified in the parameter filename and associates it with a stream that can be identified in future operations by the FILE pointer returned.

The operations that are allowed on the stream and how these are performed are defined by the mode parameter.

The returned pointer can be disassociated from the file by calling fclose or freopen. All opened files are automatically closed on normal program termination.

参数

filename

  1. C string containing the name of the file to be opened.

  2. Its value can include a path.

mode

C string containing a file access mode. It can be:

  • "r" -> read: Open file for input operations. The file must exist.

  • "w" -> write: Create an empty file for output operations. If a file with the same name already exists, its contents are discarded and the file is treated as a new empty file.

  • "a" -> append: Open file for output at the end of a file. Output operations always write data at the end of the file, expanding it. Repositioning operations (fseek, fsetpos, rewind) are ignored. The file is created if it does not exist.

  • "r+" -> read/update: Open a file for update (both for input and output). The file must exist.

  • "w+" -> write/update: Create an empty file and open it for update (both for input and output). If a file with the same name already exists its contents are discarded and the file is treated as a new empty file.

  • "a+" -> append/update: Open a file for update (both for input and output) with all output operations writing data at the end of the file. Repositioning operations (fseek, fsetpos, rewind) affects the next input operations, but output operations move the position back to the end of file. The file is created if it does not exist.


With the mode specifiers above the file is open as a text file. In order to open a file as a binary file, a "b" character has to be included in the mode string. This additional "b" character can either be appended at the end of the string (thus making the following compound modes: “rb”, “wb”, “ab”, “r+b”, “w+b”, “a+b”) or be inserted between the letter and the “+” sign for the mixed modes (“rb+”, “wb+”, “ab+”).


For files open for update (those which include a "+" sign), on which both input and output operations are allowed, the stream shall be flushed (fflush) or repositioned (fseek, fsetpos, rewind) before a reading operation that follows a writing operation. The stream shall be repositioned (fseek, fsetpos, rewind) before a writing operation that follows a reading operation(whenever that operation did not reach the end-of-file).

返回值

If the file is successfully opened, the function returns a pointer to a FILE object that can be used to identify the stream on future operations.

Otherwise, a null pointer is returned.

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
/* fopen example */
#include <stdio.h>
int main ()
{
FILE * pFile;
pFile = fopen ("myfile.txt","w");
if (pFile!=NULL)
{
fputs ("fopen example",pFile);
fclose (pFile);
}
return 0;
}

fclose

fclose: https://cplusplus.com/reference/cstdio/fclose/

int fclose ( FILE * stream );

关闭文件

Closes the file associated with the stream and disassociates it.

All internal buffers associated with the stream are disassociated from it and flushed: the content of any unwritten output buffer is written and the content of any unread input buffer is discarded.

Even if the call fails, the stream passed as parameter will no longer be associated with the file nor its buffers.

参数

stream

Pointer to a FILE object that specifies the stream to be closed.

返回值

If the stream is successfully closed, a zero value is returned.

On failure, EOF is returned.

例子

1
2
3
4
5
6
7
8
9
10
/* fclose example */
#include <stdio.h>
int main ()
{
FILE * pFile;
pFile = fopen ("myfile.txt","wt");
fprintf (pFile, "fclose example");
fclose (pFile);
return 0;
}

This simple code creates a new text file, then writes a sentence to it, and then closes it.

Formatted input/output

  • fprintf: Write formatted data to stream (function)

  • fscanf: Read formatted data from stream (function)

  • scanf: Read formatted data from stdin (function)

fprintf

fprintf: https://cplusplus.com/reference/cstdio/fprintf/

int fprintf ( FILE * stream, const char * format, ... );

Write formatted data to stream

Writes the C string pointed by format to the stream. If format includes format specifiers (subsequences beginning with %), the additional arguments following format are formatted and inserted in the resulting string replacing their respective specifiers.

After the format parameter, the function expects at least as many additional arguments as specified by format.

Parameters

stream

  1. Pointer to a FILE object that identifies an output stream.

format

C string that contains the text to be written to the stream.

It can optionally contain embedded format specifiers that are replaced by the values specified in subsequent additional arguments and formatted as requested.

A format specifier follows this prototype:

%[flags][width][.precision][length]specifier

Return Value

On success, the total number of characters written is returned.

If a writing error occurs, the error indicator (ferror) is set and a negative number is returned.

If a multibyte character encoding error occurs while writing wide characters, errno is set to EILSEQ and a negative number is returned.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* fprintf example */
#include <stdio.h>

int main ()
{
FILE * pFile;
int n;
char name [100];

pFile = fopen ("myfile.txt","w");
for (n=0 ; n<3 ; n++)
{
puts ("please, enter a name: ");
gets (name);
fprintf (pFile, "Name %d [%-10.10s]\n",n+1,name);
}
fclose (pFile);

return 0;
}

This example prompts 3 times the user for a name and then writes them to myfile.txt each one in a line with a fixed length (a total of 19 characters + newline).

Two format tags are used:

%d : Signed decimal integer

%-10.10s : left-justified (-), minimum of ten characters (10), maximum of ten characters (.10), string (s).

Assuming that we have entered John, Jean-Francois and Yoko as the 3 names, myfile.txt would contain:

1
2
3
Name 1 [John      ] 
Name 2 [Jean-Franc]
Name 3 [Yoko ]

fscanf

fscanf: https://cplusplus.com/reference/cstdio/fscanf/

int fscanf ( FILE * stream, const char * format, ... );

Read formatted data from stream

Reads data from the stream and stores them according to the parameter format into the locations pointed by the additional arguments.

The additional arguments should point to already allocated objects of the type specified by their corresponding format specifier within the format string.

Parameters

stream

  1. Pointer to a FILE object that identifies the input stream to read data from.

format

C string that contains a sequence of characters that control how characters extracted from the stream are treated:

  • Whitespace character: the function will read and ignore any whitespace characters encountered before the next non-whitespace character (whitespace characters include spaces, newline and tab characters). A single whitespace in the format string validates any quantity of whitespace characters extracted from the stream (including none).

  • Non-whitespace character, except format specifier (%): Any character that is not either a whitespace character (blank, newline or tab) or part of a format specifier (which begin with a % character) causes the function to read the next character from the stream, compare it to this non-whitespace character and if it matches, it is discarded and the function continues with the next character of format. If the character does not match, the function fails, returning and leaving subsequent characters of the stream unread.

  • Format specifiers: A sequence formed by an initial percentage sign (%) indicates a format specifier, which is used to specify the type and format of the data to be retrieved from the stream and stored into the locations pointed by the additional arguments.


A format specifier for fscanf follows this prototype:

%[*][width][length]specifier

Where the specifier character at the end is the most significant component, since it defines which characters are extracted, their interpretation and the type of its corresponding argument:

specifier Description Characters extracted
i, u Integer Any number of digits, optionally preceded by a sign (+ or -). Decimal digits assumed by default (0-9), but a 0 prefix introduces octal digits (0-7), and 0x hexadecimal digits (0-f).
d Decimal integer Any number of decimal digits (0-9), optionally preceded by a sign (+ or -).
o Octal integer Any number of octal digits (0-7), optionally preceded by a sign (+ or -).
x Hexadecimal integer Any number of hexadecimal digits (0-9, a-f, A-F), optionally preceded by 0x or 0X, and all optionally preceded by a sign (+ or -).
f, e, g, a Floating point number A series of decimal digits, optionally containing a decimal point, optionally preceeded by a sign (+ or -) and optionally followed by the e or E character and a decimal integer. Implementations complying with C99 also support hexadecimal floating-point format when preceded by 0x or 0X.
c Character The next character. If a width other than 1 is specified, the function reads exactly width characters and stores them in the successive locations of the array passed as argument. No null character is appended at the end.
s String of characters Any number of non-whitespace characters, stopping at the first whitespace character found. A terminating null character is automatically added at the end of the stored sequence.
p Pointer address A sequence of characters representing a pointer.
[characters] Scanset Any number of the characters specified between the brackets.
[^characters] Negated scanset Any number of characters none of them specified as characters between the brackets.
n Count No input is consumed. The number of characters read so far from stream is stored in the pointed location.
% % A % followed by another % matches a single %.

Except for n, at least one character shall be consumed by any specifier. Otherwise the match fails, and the scan ends there.

The format specifier can also contain sub-specifiers: asterisk (*), width and length (in that order), which are optional and follow these specifications:

sub-specifier description
* An optional starting asterisk indicates that the data is to be read from the stream but ignored (i.e. it is not stored in the location pointed by an argument).
width Specifiesthe maximum number of characters to be read in the current reading operation (optional).
length One of hh, h, l, ll, j, z, t, L (optional). This alters the expected type of the storage pointed by the corresponding argument.
length\specifiers d i u o x f e g a c s [] [^] p n
(none) int* unsigned int* float* char* void** int*
hh signed char* unsigned char* signed char*
h short int* unsigned short int* short int*
l long int* unsigned long int* double* wchar_t* long int*
ll long long int* unsigned long long int* long long int*
j intmax_t* uintmax_t* intmax_t*
z size_t* size_t* size_t*
t ptrdiff_t* ptrdiff_t* ptrdiff_t*
L long double*

… (additional arguments)

Depending on the format string, the function may expect a sequence of additional arguments, each containing a pointer to allocated storage where the interpretation of the extracted characters is stored with the appropriate type.

There should be at least as many of these arguments as the number of values stored by the format specifiers. Additional arguments are ignored by the function.

These arguments are expected to be pointers: to store the result of a fscanf operation on a regular variable, its name should be preceded by the reference operator (&).

Return Value

On success, the function returns the number of items of the argument list successfully filled. This count can match the expected number of items or be less (even zero) due to a matching failure, a reading error, or the reach of the end-of-file.

If a reading error happens or the end-of-file is reached while reading, the proper indicator is set (feof or ferror). And, if either happens before any data could be successfully read, EOF is returned.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* fscanf example */
#include <stdio.h>

int main ()
{
char str [80];
float f;
FILE * pFile;

pFile = fopen ("myfile.txt","w+");
fprintf (pFile, "%f %s", 3.1416, "PI");
rewind (pFile);
fscanf (pFile, "%f", &f);
fscanf (pFile, "%s", str);
fclose (pFile);
printf ("I have read: %f and %s \n",f,str);
return 0;
}

This sample code creates a file called myfile.txt and writes a float number and a string to it. Then, the stream is rewinded and both values are read with fscanf.

输出
1
I have read: 3.141600 and PI

scanf

scanf: https://cplusplus.com/reference/cstdio/scanf/

int scanf ( const char * format, ... );

Read formatted data from stdin

Reads data from stdin and stores them according to the parameter format into the locations pointed by the additional arguments.

The additional arguments should point to already allocated objects of the type specified by their corresponding format specifier within the format string.

Parameters

format

A format specifier for scanf follows this prototype:

%[*][width][length]specifier

… (additional arguments)

Depending on the format string, the function may expect a sequence of additional arguments, each containing a pointer to allocated storage where the interpretation of the extracted characters is stored with the appropriate type.

There should be at least as many of these arguments as the number of values stored by the format specifiers. Additional arguments are ignored by the function.

These arguments are expected to be pointers: to store the result of a scanf operation on a regular variable, its name should be preceded by the reference operator (&).

Return Value

On success, the function returns the number of items of the argument list successfully filled. This count can match the expected number of items or be less (even zero) due to a matching failure, a reading error, or the reach of the end-of-file.

If a reading error happens or the end-of-file is reached while reading, the proper indicator is set (feof or ferror). And, if either happens before any data could be successfully read, EOF is returned.

If an encoding error happens interpreting wide characters, the function sets errno to EILSEQ.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* scanf example */
#include <stdio.h>

int main ()
{
char str [80];
int i;

printf ("Enter your family name: ");
scanf ("%79s",str);
printf ("Enter your age: ");
scanf ("%d",&i);
printf ("Mr. %s , %d years old.\n",str,i);
printf ("Enter a hexadecimal number: ");
scanf ("%x",&i);
printf ("You have entered %#x (%d).\n",i,i);

return 0;
}

This example demonstrates some of the types that can be read with scanf:

1
2
3
4
5
Enter your family name: Soulie
Enter your age: 29
Mr. Soulie , 29 years old.
Enter a hexadecimal number: ff
You have entered 0xff (255).

Character input/output

  • fgetc: Get character from stream (function)

  • fputc: Write character to stream (function)

  • fputs: Write string to stream (function)

  • puts: Write string to stdout (function)

fgetc

fgetc: https://cplusplus.com/reference/cstdio/fgetc/

int fgetc ( FILE * stream );

Get character from stream

Returns the character currently pointed by the internal file position indicator of the specified stream. The internal file position indicator is then advanced to the next character.

If the stream is at the end-of-file when called, the function returns EOF and sets the end-of-file indicator for the stream (feof).

If a read error occurs, the function returns EOF and sets the error indicator for the stream (ferror).

fgetc and getc are equivalent, except that getc may be implemented as a macro in some libraries.

Parameters

stream

  1. Pointer to a FILE object that identifies an input stream.

Return Value

On success, the character read is returned (promoted to an int value).

The return type is int to accommodate for the special value EOF, which indicates failure:

  1. If the position indicator was at the end-of-file, the function returns EOF and sets the eof indicator (feof) of stream.

  2. If some other reading error happens, the function also returns EOF, but sets its error indicator (ferror) instead.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/* fgetc example: money counter */
#include <stdio.h>
int main ()
{
FILE * pFile;
int c;
int n = 0;
pFile=fopen ("myfile.txt","r");
if (pFile==NULL) perror ("Error opening file");
else
{
do {
c = fgetc (pFile);
if (c == '$') n++;
} while (c != EOF);
fclose (pFile);
printf ("The file contains %d dollar sign characters ($).\n",n);
}
return 0;
}

This program reads an existing file called myfile.txt character by character and uses the n variable to count how many dollar characters ($) the file contains.

fputc

fputc: https://cplusplus.com/reference/cstdio/fputc/

int fputc ( int character, FILE * stream );

将字符写入流

Writes a character to the stream and advances the position indicator.

The character is written at the position indicated by the internal position indicator of the stream, which is then automatically advanced by one.

参数

character

  1. The int promotion of the character to be written.

  2. The value is internally converted to an unsigned char when written.

stream

  1. Pointer to a FILE object that identifies an output stream.

返回值

On success, the character written is returned.

If a writing error occurs, EOF is returned and the error indicator (ferror) is set.

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* fputc example: alphabet writer */
#include <stdio.h>

int main ()
{
FILE * pFile;
char c;

pFile = fopen ("alphabet.txt","w");
if (pFile!=NULL) {

for (c = 'A' ; c <= 'Z' ; c++)
fputc ( c , pFile );

fclose (pFile);
}
return 0;
}

This program creates a file called alphabet.txt and writes ABCDEFGHIJKLMNOPQRSTUVWXYZ to it.

fputs

fputs: https://cplusplus.com/reference/cstdio/fputs/

int fputs ( const char * str, FILE * stream );

Write string to stream

Writes the C string pointed by str to the stream.

The function begins copying from the address specified (str) until it reaches the terminating null character (‘\0’). This terminating null-character is not copied to the stream.

Notice that fputs not only differs from puts in that the destination stream can be specified, but also fputs does not write additional characters, while puts appends a newline character at the end automatically.

Parameters

str

  1. C string with the content to be written to stream.

stream

  1. Pointer to a FILE object that identifies an output stream.

Return Value

On success, a non-negative value is returned.

On error, the function returns EOF and sets the error indicator (ferror).

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* fputs example */
#include <stdio.h>

int main ()
{
FILE * pFile;
char sentence [256];

printf ("Enter sentence to append: ");
fgets (sentence,256,stdin);
pFile = fopen ("mylog.txt","a");
fputs (sentence,pFile);
fclose (pFile);
return 0;
}

This program allows to append a line to a file called mylog.txt each time it is run.

puts

puts: https://cplusplus.com/reference/cstdio/puts/

int puts ( const char * str );

Write string to stdout

Writes the C string pointed by str to the standard output (stdout) and appends a newline character ('\n').

The function begins copying from the address specified (str) until it reaches the terminating null character (‘\0’). This terminating null-character is not copied to the stream.

Notice that puts not only differs from fputs in that it uses stdout as destination, but it also appends a newline character at the end automatically (which fputs does not).

Parameters

str

  1. C string to be printed.

Return Value

On success, a non-negative value is returned.

On error, the function returns EOF and sets the error indicator (ferror).

Example

1
2
3
4
5
6
7
8
/* puts example : hello world! */
#include <stdio.h>

int main ()
{
char string [] = "Hello world!";
puts (string);
}
输出
1
Hello world!

Direct input/output

  • fread: Read block of data from stream (function)

  • fwrite: Write block of data to stream (function)

fread

fread: https://cplusplus.com/reference/cstdio/fread/

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

Read block of data from stream

Reads an array of count elements, each one with a size of size bytes, from the stream and stores them in the block of memory specified by ptr.

The position indicator of the stream is advanced by the total amount of bytes read.

The total amount of bytes read if successful is (size*count).

Parameters

ptr

  1. Pointer to a block of memory with a size of at least (size*count) bytes, converted to a void*.

size

  1. Size, in bytes, of each element to be read. size_t is an unsigned integral type.

count

  1. Number of elements, each one with a size of size bytes. size_t is an unsigned integral type.

stream

  1. Pointer to a FILE object that specifies an input stream.

Return Value

The total number of elements successfully read is returned.

If this number differs from the count parameter, either a reading error occurred or the end-of-file was reached while reading. In both cases, the proper indicator is set, which can be checked with ferror and feof, respectively.

If either size or count is zero, the function returns zero and both the stream state and the content pointed by ptr remain unchanged.

size_t is an unsigned integral type.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* fread example: read an entire file */
#include <stdio.h>
#include <stdlib.h>

int main () {
FILE * pFile;
long lSize;
char * buffer;
size_t result;

pFile = fopen ( "myfile.bin" , "rb" );
if (pFile==NULL) {fputs ("File error",stderr); exit (1);}

// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);

// allocate memory to contain the whole file:
buffer = (char*) malloc (sizeof(char)*lSize);
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

// copy the file into the buffer:
result = fread (buffer,1,lSize,pFile);
if (result != lSize) {fputs ("Reading error",stderr); exit (3);}

/* the whole file is now loaded in the memory buffer. */

// terminate
fclose (pFile);
free (buffer);
return 0;
}

This code loads myfile.bin into a dynamically allocated memory buffer, which can be used to manipulate the content of a file as an array.

输出
1
File error 

fwrite

fwrite: https://cplusplus.com/reference/cstdio/fwrite/

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

Write block of data to stream

Writes an array of count elements, each one with a size of size bytes, from the block of memory pointed by ptr to the current position in the stream.

The position indicator of the stream is advanced by the total number of bytes written.

Internally, the function interprets the block pointed by ptr as if it was an array of (size*count) elements of type unsigned char, and writes them sequentially to stream as if fputc was called for each byte.

Parameters

ptr

  1. Pointer to the array of elements to be written, converted to a const void*.

size

  1. Size in bytes of each element to be written. size_t is an unsigned integral type.

count

  1. Number of elements, each one with a size of size bytes. size_t is an unsigned integral type.

stream

  1. Pointer to a FILE object that specifies an output stream.

Return Value

The total number of elements successfully written is returned.

If this number differs from the count parameter, a writing error prevented the function from completing. In this case, the error indicator (ferror) will be set for the stream.

If either size or count is zero, the function returns zero and the error indicator remains unchanged.

size_t is an unsigned integral type.

Example

1
2
3
4
5
6
7
8
9
10
11
12
/* fwrite example : write buffer */
#include <stdio.h>

int main ()
{
FILE * pFile;
char buffer[] = { 'x' , 'y' , 'z' };
pFile = fopen ("myfile.bin", "wb");
fwrite (buffer , sizeof(char), sizeof(buffer), pFile);
fclose (pFile);
return 0;
}

A file called myfile.bin is created and the content of the buffer is stored into it. For simplicity, the buffer contains char elements but it can contain any other type.

sizeof(buffer) is the length of the array in bytes (in this case it is three, because the array has three elements of one byte each).

File positioning

  • fseek: Reposition stream position indicator (function)

  • rewind: Set position of stream to the beginning (function)

fseek

fseek: https://cplusplus.com/reference/cstdio/fseek/

int fseek ( FILE * stream, long int offset, int origin );

Reposition stream position indicator

Sets the position indicator associated with the stream to a new position.

For streams open in binary mode, the new position is defined by adding offset to a reference position specified by origin.

For streams open in text mode, offset shall either be zero or a value returned by a previous call to ftell, and origin shall necessarily be SEEK_SET.

If the function is called with other values for these arguments, support depends on the particular system and library implementation (non-portable).

The end-of-file internal indicator of the stream is cleared after a successful call to this function, and all effects from previous calls to ungetc on this stream are dropped.

On streams open for update (read+write), a call to fseek allows to switch between reading and writing.

Parameters

stream

  1. Pointer to a FILE object that identifies the stream.

offset

  1. Binary files: Number of bytes to offset from origin.

  2. Text files: Either zero, or a value returned by ftell.

origin

Position used as reference for the offset. It is specified by one of the following constants defined in <cstdio> exclusively to be used as arguments for this function:

Constant Reference position
SEEK_SET Beginning of file
SEEK_CUR Current position of the file pointer
SEEK_END End of file *

* Library implementations are allowed to not meaningfully support SEEK_END (therefore, code using it has no real standard portability).

Return Value

  1. If successful, the function returns zero.

  2. Otherwise, it returns non-zero value.

  3. If a read or write error occurs, the error indicator (ferror) is set.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
/* fseek example */
#include <stdio.h>

int main ()
{
FILE * pFile;
pFile = fopen ( "example.txt" , "wb" );
fputs ( "This is an apple." , pFile );
fseek ( pFile , 9 , SEEK_SET );
fputs ( " sam" , pFile );
fclose ( pFile );
return 0;
}

After this code is successfully executed, the file example.txt contains:

1
This is a sample.

rewind

rewind: https://cplusplus.com/reference/cstdio/rewind/

void rewind ( FILE * stream );

Set position of stream to the beginning

Sets the position indicator associated with stream to the beginning of the file.

The end-of-file and error internal indicators associated to the stream are cleared after a successful call to this function, and all effects from previous calls to ungetc on this stream are dropped.

On streams open for update (read+write), a call to rewind allows to switch between reading and writing.

Parameters

stream

  1. Pointer to a FILE object that identifies the stream.

Return Value

none

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* rewind example */
#include <stdio.h>

int main ()
{
int n;
FILE * pFile;
char buffer [27];

pFile = fopen ("myfile.txt","w+");
for ( n='A' ; n<='Z' ; n++)
fputc ( n, pFile);
rewind (pFile);
fread (buffer,1,26,pFile);
fclose (pFile);
buffer[26]='\0';
puts (buffer);
return 0;
}

A file called myfile.txt is created for reading and writing and filled with the alphabet. The file is then rewinded, read and its content is stored in a buffer, that then is written to the standard output:

1
ABCDEFGHIJKLMNOPQRSTUVWXYZ

Error-handling

  • feof: Check end-of-file indicator (function)

feof

feof: https://cplusplus.com/reference/cstdio/feof/

int feof ( FILE * stream );

Check end-of-file indicator

Checks whether the end-of-File indicator associated with stream is set, returning a value different from zero if it is.

This indicator is generally set by a previous operation on the stream that attempted to read at or past the end-of-file.

Notice that stream’s internal position indicator may point to the end-of-file for the next operation, but still, the end-of-file indicator may not be set until an operation attempts to read at that point.

This indicator is cleared by a call to clearerr, rewind, fseek, fsetpos or freopen. Although if the position indicator is not repositioned by such a call, the next i/o operation is likely to set the indicator again.

Parameters

stream

  1. Pointer to a FILE object that identifies the stream.

Return Value

A non-zero value is returned in the case that the end-of-file indicator associated with the stream is set.

Otherwise, zero is returned.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* feof example: byte counter */
#include <stdio.h>

int main ()
{
FILE * pFile;
int n = 0;
pFile = fopen ("myfile.txt","rb");
if (pFile==NULL) perror ("Error opening file");
else
{
while (fgetc(pFile) != EOF) {
++n;
}
if (feof(pFile)) {
puts ("End-of-File reached.");
printf ("Total number of bytes read: %d\n", n);
}
else puts ("End-of-File was not reached.");
fclose (pFile);
}
return 0;
}

This code opens the file called myfile.txt, and counts the number of characters that it contains by reading all of them one by one. The program checks whether the end-of-file was reached, and if so, prints the total number of bytes read.

<cstdlib> (stdlib.h)

<cstdlib> (stdlib.h): https://cplusplus.com/reference/cstdlib/

<cstdlib> (stdlib.h): C Standard General Utilities Library.

String conversion

  • atof: Convert string to double (function)

  • atoi: Convert string to integer (function)

atof

atof: https://cplusplus.com/reference/cstdlib/atof/

double atof (const char* str);

Convert string to double

Parses the C string str, interpreting its content as a floating point number and returns its value as a double.

The function first discards as many whitespace characters (as in isspace) as necessary until the first non-whitespace character is found. Then, starting from this character, takes as many characters as possible that are valid following a syntax resembling that of floating point literals, and interprets them as a numerical value. The rest of the string after the last valid character is ignored and has no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str does not form a valid floating-point number as just defined, or if no such sequence exists because either str is empty or contains only whitespace characters, no conversion is performed and the function returns 0.0.

Parameters

str

  1. C-string beginning with the representation of a floating-point number.

Return Value

On success, the function returns the converted floating point number as a double value.

If no valid conversion could be performed, the function returns zero (0.0).

If the converted value would be out of the range of representable values by a double, it causes undefined behavior.

See strtod for a more robust cross-platform alternative when this is a possibility.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* atof example: sine calculator */
#include <stdio.h> /* printf, fgets */
#include <stdlib.h> /* atof */
#include <math.h> /* sin */

int main ()
{
double n,m;
double pi=3.1415926535;
char buffer[256];
printf ("Enter degrees: ");
fgets (buffer,256,stdin);
n = atof (buffer);
m = sin (n*pi/180);
printf ("The sine of %f degrees is %f\n" , n, m);
return 0;
}
输出
1
2
3
Enter degrees: 45
The sine of 45.000000 degrees is 0.707101

Exceptions (C++)

No-throw guarantee: this function never throws exceptions.

If str does not point to a valid C-string, or if the converted value would be out of the range of values representable by a double, it causes undefined behavior.

atoi

atoi: https://cplusplus.com/reference/cstdlib/atoi/

int atoi (const char * str);

Convert string to integer

Parses the C-string str interpreting its content as an integral number, which is returned as a value of type int.

The function first discards as many whitespace characters (as in isspace) as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many base-10 digits as possible, and interprets them as a numerical value.

The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed and zero is returned.

Parameters

str

  1. C-string beginning with the representation of an integral number.

Return Value

On success, the function returns the converted integral number as an int value.

If the converted value would be out of the range of representable values by an int, it causes undefined behavior.

See strtol for a more robust cross-platform alternative when this is a possibility.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/* atoi example */
#include <stdio.h> /* printf, fgets */
#include <stdlib.h> /* atoi */

int main ()
{
int i;
char buffer[256];
printf ("Enter a number: ");
fgets (buffer, 256, stdin);
i = atoi (buffer);
printf ("The value entered is %d. Its double is %d.\n",i,i*2);
return 0;
}
输出
1
2
3
Enter a number: 73
The value entered is 73. Its double is 146.

Exceptions (C++)

No-throw guarantee: this function never throws exceptions.

If str does not point to a valid C-string, or if the converted value would be out of the range of values representable by an int, it causes undefined behavior.

Pseudo-random sequence generation

  • rand: Generate random number (function)

rand

rand: https://cplusplus.com/reference/cstdlib/rand/

int rand (void);

Generate random number

Returns a pseudo-random integral number in the range between 0 and RAND_MAX.

This number is generated by an algorithm that returns a sequence of apparently non-related numbers each time it is called. This algorithm uses a seed to generate the series, which should be initialized to some distinctive value using function srand.

RAND_MAX is a constant defined in <cstdlib>.

A typical way to generate trivial pseudo-random numbers in a determined range using rand is to use the modulo of the returned value by the range span and add the initial value of the range:

1
2
3
v1 = rand() % 100;         // v1 in the range 0 to 99
v2 = rand() % 100 + 1; // v2 in the range 1 to 100
v3 = rand() % 30 + 1985; // v3 in the range 1985-2014

Notice though that this modulo operation does not generate uniformly distributed random numbers in the span (since in most cases this operation makes lower numbers slightly more likely).

C++ supports a wide range of powerful tools to generate random and pseudo-random numbers (see <random> for more info).

Parameters

(none)

Return Value

An integer value between 0 and RAND_MAX.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* rand example: guess the number */
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h> /* time */

int main ()
{
int iSecret, iGuess;

/* initialize random seed: */
srand (time(NULL));

/* generate secret number between 1 and 10: */
iSecret = rand() % 10 + 1;

do {
printf ("Guess the number (1 to 10): ");
scanf ("%d",&iGuess);
if (iSecret<iGuess) puts ("The secret number is lower");
else if (iSecret>iGuess) puts ("The secret number is higher");
} while (iSecret!=iGuess);

puts ("Congratulations!");
return 0;
}

In this example, the random seed is initialized to a value representing the current time (calling time) to generate a different value every time the program is run.

可能的输出
1
2
3
4
5
6
Guess the number (1 to 10): 5
The secret number is higher
Guess the number (1 to 10): 8
The secret number is lower
Guess the number (1 to 10): 7
Congratulations!

Dynamic memory management

  • calloc: Allocate and zero-initialize array (function)

  • free: Deallocate memory block (function)

calloc

calloc: https://cplusplus.com/reference/cstdlib/calloc/

void* calloc (size_t num, size_t size);

Allocate and zero-initialize array

Allocates a block of memory for an array of num elements, each of them size bytes long, and initializes all its bits to zero.

The effective result is the allocation of a zero-initialized memory block of (num*size) bytes.

If size is zero, the return value depends on the particular library implementation (it may or may not be a null pointer), but the returned pointer shall not be dereferenced.

Parameters

num

  1. Number of elements to allocate.

size

  1. Size of each element.

size_t is an unsigned integral type.

Return Value

On success, a pointer to the memory block allocated by the function.

The type of this pointer is always void*, which can be cast to the desired type of data pointer in order to be dereferenceable.

If the function failed to allocate the requested block of memory, a null pointer is returned.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* calloc example */
#include <stdio.h> /* printf, scanf, NULL */
#include <stdlib.h> /* calloc, exit, free */

int main ()
{
int i,n;
int * pData;
printf ("Amount of numbers to be entered: ");
scanf ("%d",&i);
pData = (int*) calloc (i,sizeof(int));
if (pData==NULL) exit (1);
for (n=0;n<i;n++)
{
printf ("Enter number #%d: ",n+1);
scanf ("%d",&pData[n]);
}
printf ("You have entered: ");
for (n=0;n<i;n++) printf ("%d ",pData[n]);
free (pData);
return 0;
}

This program simply stores numbers and then prints them out. But the number of items it stores can be adapted each time the program is executed because it allocates the needed memory during runtime.

Data races

Only the storage referenced by the returned pointer is modified. No other storage locations are accessed by the call.

If the function reuses the same unit of storage released by a deallocation function (such as free or realloc), the functions are synchronized in such a way that the deallocation happens entirely before the next allocation.

free

free: https://cplusplus.com/reference/cstdlib/free/

void free (void* ptr);

Deallocate memory block

A block of memory previously allocated by a call to malloc, calloc or realloc is deallocated, making it available again for further allocations.

If ptr does not point to a block of memory allocated with the above functions, it causes undefined behavior.

If ptr is a null pointer, the function does nothing.

Notice that this function does not change the value of ptr itself, hence it still points to the same (now invalid) location.

Parameters

ptr

  1. Pointer to a memory block previously allocated with malloc, calloc or realloc.

Return Value

none

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
/* free example */
#include <stdlib.h> /* malloc, calloc, realloc, free */

int main ()
{
int * buffer1, * buffer2, * buffer3;
buffer1 = (int*) malloc (100*sizeof(int));
buffer2 = (int*) calloc (100,sizeof(int));
buffer3 = (int*) realloc (buffer2,500*sizeof(int));
free (buffer1);
free (buffer3);
return 0;
}

This program has no output. It just demonstrates some ways to allocate and free dynamic memory using the C stdlib functions.

Data races

Only the storage referenced by ptr is modified. No other storage locations are accessed by the call.

If the function releases a unit of storage that is reused by a call to allocation functions (such as calloc or malloc), the functions are synchronized in such a way that the deallocation happens entirely before the next allocation.

Exceptions (C++)

No-throw guarantee: this function never throws exceptions.

If ptr does not point to a memory block previously allocated with malloc, calloc or realloc, and is not a null pointer, it causes undefined behavior.

<cstring> (string.h)

<cstring> (string.h): https://cplusplus.com/reference/cstring/

<cstring> (string.h): C Strings.

Copying

  • memcpy: Copy block of memory (function)

memcpy

memcpy: https://cplusplus.com/reference/cstring/memcpy/

void * memcpy ( void * destination, const void * source, size_t num );

Copy block of memory

Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.

The underlying type of the objects pointed to by both the source and destination pointers are irrelevant for this function; The result is a binary copy of the data.

The function does not check for any terminating null character in source - it always copies exactly num bytes.

To avoid overflows, the size of the arrays pointed to by both the destination and source parameters, shall be at least num bytes, and should not overlap (for overlapping memory blocks, memmove is a safer approach).

Parameters

destination

  1. Pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*.

source

  1. Pointer to the source of data to be copied, type-casted to a pointer of type const void*.

num

  1. Number of bytes to copy.

  2. size_t is an unsigned integral type.

Return Value

destination is returned.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* memcpy example */
#include <stdio.h>
#include <string.h>

struct {
char name[40];
int age;
} person, person_copy;

int main ()
{
char myname[] = "Pierre de Fermat";

/* using memcpy to copy string: */
memcpy ( person.name, myname, strlen(myname)+1 );
person.age = 46;

/* using memcpy to copy structure: */
memcpy ( &person_copy, &person, sizeof(person) );

printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );

return 0;
}
输出
1
person_copy: Pierre de Fermat, 46 

Comparison

  • memcmp: Compare two blocks of memory (function)

  • strcmp: Compare two strings (function)

memcmp

memcmp: https://cplusplus.com/reference/cstring/memcmp/

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

Compare two blocks of memory

Compares the first num bytes of the block of memory pointed by ptr1 to the first num bytes pointed by ptr2, returning zero if they all match or a value different from zero representing which is greater if they do not.

Notice that, unlike strcmp, the function does not stop comparing after finding a null character.

Parameters

ptr1

  1. Pointer to block of memory.

ptr2

  1. Pointer to block of memory.

num

  1. Number of bytes to compare.

Return Value

Returns an integral value indicating the relationship between the content of the memory blocks:

return value indicates
<0 the first byte that does not match in both memory blocks has a lower value in ptr1 than in ptr2 (if evaluated as unsigned char values)
0 the contents of both memory blocks are equal
>0 the first byte that does not match in both memory blocks has a greater value in ptr1 than in ptr2 (if evaluated as unsigned char values)

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* memcmp example */
#include <stdio.h>
#include <string.h>

int main ()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";

int n;

n=memcmp ( buffer1, buffer2, sizeof(buffer1) );

if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);
else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);
else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);

return 0;
}
输出
1
2
'DWgaOtP12df0' is greater than 'DWGAOTP12DF0'.

DWgAOtp12Df0 is greater than DWGAOTP12DF0 because the first non-matching character in both words are 'g' and 'G' respectively, and 'g' (103) evaluates as greater than 'G' (71).

strcmp

strcmp: https://cplusplus.com/reference/cstring/strcmp/

int strcmp ( const char * str1, const char * str2 );

Compare two strings

Compares the C string str1 to the C string str2.

This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached.

This function performs a binary comparison of the characters.

Parameters

str1

  1. C string to be compared.

str2

  1. C string to be compared.

Return Value

Returns an integral value indicating the relationship between the strings:

return value indicates
<0 the first character that does not match has a lower value in ptr1 than in ptr2
0 the contents of both strings are equal
>0 the first character that does not match has a greater value in ptr1 than in ptr2

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <string.h>

int main ()
{
char key[] = "apple";
char buffer[80];
do {
printf ("Guess my favorite fruit? ");
fflush (stdout);
scanf ("%79s",buffer);
} while (strcmp (key,buffer) != 0);
puts ("Correct answer!");
return 0;
}
输出
1
2
3
Guess my favourite fruit? orange
Guess my favourite fruit? apple
Correct answer!

Searching

  • strtok: Split string into tokens (function)

strtok

strtok: https://cplusplus.com/reference/cstring/strtok/

char * strtok ( char * str, const char * delimiters );

Split string into tokens

A sequence of calls to this function split str into tokens, which are sequences of contiguous characters separated by any of the characters that are part of delimiters.

On a first call, the function expects a C string as argument for str, whose first character is used as the starting location to scan for tokens. In subsequent calls, the function expects a null pointer and uses the position right after the end of the last token as the new starting location for scanning.

To determine the beginning and the end of a token, the function first scans from the starting location for the first character not contained in delimiters (which becomes the beginning of the token). And then scans starting from this beginning of the token for the first character contained in delimiters, which becomes the end of the token. The scan also stops if the terminating null character is found.

This end of the token is automatically replaced by a null-character, and the beginning of the token is returned by the function.

Once the terminating null character of str is found in a call to strtok, all subsequent calls to this function (with a null pointer as the first argument) return a null pointer.

The point where the last token was found is kept internally by the function to be used on the next call (particular library implementations are not required to avoid data races).

Parameters

str

  1. C string to truncate.

  2. Notice that this string is modified by being broken into smaller strings (tokens).

  3. Alternativelly, a null pointer may be specified, in which case the function continues scanning where a previous successful call to the function ended.

delimiters

  1. C string containing the delimiter characters.

  2. These can be different from one call to another.

Return Value

  1. If a token is found, a pointer to the beginning of the token.

  2. Otherwise, a null pointer.

  3. A null pointer is always returned when the end of the string (i.e., a null character) is reached in the string being scanned.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* strtok example */
#include <stdio.h>
#include <string.h>

int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
输出
1
2
3
4
5
Splitting string "- This, a sample string." into tokens:
This
a
sample
string

Other

  • memset: Fill block of memory (function)

memset

memset: https://cplusplus.com/reference/cstring/memset/

void * memset ( void * ptr, int value, size_t num );

Fill block of memory

Sets the first num bytes of the block of memory pointed by ptr to the specified value (interpreted as an unsigned char).

Parameters

ptr

  1. Pointer to the block of memory to fill.

value

  1. Value to be set. The value is passed as an int, but the function fills the block of memory using the unsigned char conversion of this value.

num

  1. Number of bytes to be set to the value.

  2. size_t is an unsigned integral type.

Return Value

ptr is returned.

Example

1
2
3
4
5
6
7
8
9
10
11
/* memset example */
#include <stdio.h>
#include <string.h>

int main ()
{
char str[] = "almost every programmer should know memset!";
memset (str,'-',6);
puts (str);
return 0;
}
输出
1
2
------ every programmer should know memset!

Containers

<array>

<array>: https://cplusplus.com/reference/array/

<array>: Array header (header).

array

Iterators:

  • begin: Return iterator to beginning (public member function)

std::array::begin

std::array::begin: https://cplusplus.com/reference/array/array/begin/

1
iterator begin() noexcept;const_iterator begin() const noexcept;

Return iterator to beginning

Returns an iterator pointing to the first element in the array container.

Notice that, unlike member array::front, which returns a reference to the first element, this function returns a random access iterator pointing to it.

In zero-sized arrays, this function returns the same as array::end, but the returned iterator should not be dereferenced.

Parameters

none

Return Value

An iterator to the beginning of the sequence.

If the array object is const-qualified, the function returns a const_iterator. Otherwise, it returns an iterator.

Member types iterator and const_iterator are random access iterator types (pointing to an element and to a const element, respectively).

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// array::begin example
#include <iostream>
#include <array>

int main ()
{
std::array<int,5> myarray = { 2, 16, 77, 34, 50 };

std::cout << "myarray contains:";
for ( auto it = myarray.begin(); it != myarray.end(); ++it )
std::cout << ' ' << *it;
std::cout << '\n';

return 0;
}
输出
1
myarray contains: 2 16 77 34 50

Complexity

Constant.

Iterator validity

No changes.

Data races

No contained elements are accessed by the call, but the iterator returned can be used to access or modify elements. Concurrently accessing or modifying different elements is safe.

Exception safety

No-throw guarantee: this member function never throws exceptions.

The copy construction or assignment of the returned iterator is also guaranteed to never throw.

<map>

<map>: https://cplusplus.com/reference/map/

<map>: Map header (header).

map

Capacity:

  • size: Return container size (public member function)

Element access:

  • operator[]: Access element (public member function)

Modifiers:

  • clear: Clear content (public member function)

Operations:

  • count: Count elements with a specific key (public member function)

std::map::size

std::map::size: https://cplusplus.com/reference/map/map/size/

1
size_type size() const noexcept;

Return container size

Returns the number of elements in the map container.

Parameters

none

Return Value

The number of elements in the container.

Member type size_type is an unsigned integral type.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// map::size
#include <iostream>
#include <map>

int main ()
{
std::map<char,int> mymap;
mymap['a']=101;
mymap['b']=202;
mymap['c']=302;

std::cout << "mymap.size() is " << mymap.size() << '\n';

return 0;
}
输出
1
mymap.size() is 3

Complexity

Constant.

Iterator validity

No changes.

Data races

  1. The container is accessed.

  2. No elements are accessed: concurrently accessing or modifying them is safe.

Exception safety

No-throw guarantee: this member function never throws exceptions.

std::map::operator[]

std::map::operator[]: https://cplusplus.com/reference/map/map/operator[]/

1
mapped_type& operator[] (const key_type& k);mapped_type& operator[] (key_type&& k);

Access element

If k matches the key of an element in the container, the function returns a reference to its mapped value.

If k does not match the key of any element in the container, the function inserts a new element with that key and returns a reference to its mapped value. Notice that this always increases the container size by one, even if no mapped value is assigned to the element (the element is constructed using its default constructor).

A similar member function, map::at, has the same behavior when an element with the key exists, but throws an exception when it does not.

A call to this function is equivalent to:

1
(*((this->insert(make_pair(k,mapped_type()))).first)).

Parameters

k

  1. Key value of the element whose mapped value is accessed.

  2. Member type key_type is the type of the keys for the elements stored in the container, defined in map as an alias of its first template parameter (Key).

  3. If an rvalue (second version), the key is moved instead of copied when a new element is inserted.

Return Value

A reference to the mapped value of the element with a key value equivalent to k.

Member type mapped_type is the type of the mapped values in the container, defined in map as an alias of its second template parameter (T).

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// accessing mapped values
#include <iostream>
#include <map>
#include <string>

int main ()
{
std::map<char,std::string> mymap;

mymap['a']="an element";
mymap['b']="another element";
mymap['c']=mymap['b'];

std::cout << "mymap['a'] is " << mymap['a'] << '\n';
std::cout << "mymap['b'] is " << mymap['b'] << '\n';
std::cout << "mymap['c'] is " << mymap['c'] << '\n';
std::cout << "mymap['d'] is " << mymap['d'] << '\n';

std::cout << "mymap now contains " << mymap.size() << " elements.\n";

return 0;
}

Notice how the last access (to element 'd') inserts a new element in the map with that key and initialized to its default value (an empty string) even though it is accessed only to retrieve its value. Member function map::find does not produce this effect.

输出
1
2
3
4
5
mymap['a'] is an element
mymap['b'] is another element
mymap['c'] is another element
mymap['d'] is
mymap now contains 4 elements.

Complexity

Logarithmic in size.

Iterator validity

No changes.

Data races

  1. The container is accessed, and potentially modified.

  2. The function accesses an element and returns a reference that can be used to modify its mapped value. Concurrently accessing other elements is safe.

  3. If the function inserts a new element, concurrently iterating ranges in the container is not safe.

Exception safety

  1. Strong guarantee: if an exception is thrown, there are no changes in the container.

  2. If a new element is inserted and allocator_traits::construct cannot construct an element with k and a default-constructed mapped_type (or if mapped_type is not default constructible), it causes undefined behavior.

std::map::clear

std::map::clear: https://cplusplus.com/reference/map/map/clear/

1
void clear() noexcept;

Clear content

Removes all elements from the map container (which are destroyed), leaving the container with a size of 0.

Parameters

none

Return Value

none

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// map::clear
#include <iostream>
#include <map>

int main ()
{
std::map<char,int> mymap;

mymap['x']=100;
mymap['y']=200;
mymap['z']=300;

std::cout << "mymap contains:\n";
for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
std::cout << it->first << " => " << it->second << '\n';

mymap.clear();
mymap['a']=1101;
mymap['b']=2202;

std::cout << "mymap contains:\n";
for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
std::cout << it->first << " => " << it->second << '\n';

return 0;
}
输出
1
2
3
4
5
6
7
mymap contains:
x => 100
y => 200
z => 300
mymap contains:
a => 1101
b => 2202

Complexity

Linear in size (destructions).

Iterator validity

All iterators, pointers and references related to this container are invalidated.

Data races

  1. The container is modified.

  2. All contained elements are modified.

Exception safety

No-throw guarantee: this member function never throws exceptions.

std::map::count

std::map::count: https://cplusplus.com/reference/map/map/count/

1
size_type count (const key_type& k) const;

Count elements with a specific key

Searches the container for elements with a key equivalent to k and returns the number of matches.

Because all elements in a map container are unique, the function can only return 1 (if the element is found) or zero (otherwise).

Two keys are considered equivalent if the container’s comparison object returns false reflexively (i.e., no matter the order in which the keys are passed as arguments).

Parameters

k

  1. Key to search for.

  2. Member type key_type is the type of the element keys in the container, defined in map as an alias of its first template parameter (Key).

Return Value

1 if the container contains an element whose key is equivalent to k, or zero otherwise.

Member type size_type is an unsigned integral type.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// map::count
#include <iostream>
#include <map>

int main ()
{
std::map<char,int> mymap;
char c;

mymap ['a']=101;
mymap ['c']=202;
mymap ['f']=303;

for (c='a'; c<'h'; c++)
{
std::cout << c;
if (mymap.count(c)>0)
std::cout << " is an element of mymap.\n";
else
std::cout << " is not an element of mymap.\n";
}

return 0;
}
输出
1
2
3
4
5
6
7
a is an element of mymap.
b is not an element of mymap.
c is an element of mymap.
d is not an element of mymap.
e is not an element of mymap.
f is an element of mymap.
g is not an element of mymap.

Complexity

Logarithmic in size.

Iterator validity

No changes.

Data races

  1. The container is accessed.

  2. No mapped values are accessed: concurrently accessing or modifying elements is safe.

Exception safety

Strong guarantee: if an exception is thrown, there are no changes in the container.

<vector>

<vector>: https://cplusplus.com/reference/vector/

<vector>: Vector header (header).

vector

  • operator=: Assign content (public member function)

Capacity:

  • size: Return size (public member function)

  • resize: Change size (public member function)

Element access:

  • operator[]: Access element (public member function)

Modifiers:

  • push_back: Add element at the end (public member function)

  • clear: Clear content (public member function)

std::vector::operator=

std::vector::operator=: https://cplusplus.com/reference/vector/vector/operator=/

1
2
3
4
5
6
copy (1)	
vector& operator= (const vector& x);
move (2)
vector& operator= (vector&& x);
initializer list (3)
vector& operator= (initializer_list<value_type> il);

Assign content

Assigns new contents to the container, replacing its current contents, and modifying its size accordingly.

C++11

The copy assignment (1) copies all the elements from x into the container (with x preserving its contents).

The move assignment (2) moves the elements of x into the container (x is left in an unspecified but valid state).

The initializer list assignment (3) copies the elements of il into the container.

The container preserves its current allocator, except if the allocator traits indicate that x’s allocator should propagate. This allocator is used (through its traits) to allocate and deallocate storage if a reallocation happens, and to construct or destroy elements, if needed.

Any elements held in the container before the call are either assigned to or destroyed.

Parameters

x

  1. A vector object of the same type (i.e., with the same template parameters, T and Alloc).

il

  1. An initializer_list object. The compiler will automatically construct such objects from initializer list declarators.

  2. Member type value_type is the type of the elements in the container, defined in vector as an alias of its first template parameter (T).

Return Value

*this

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// vector assignment
#include <iostream>
#include <vector>

int main ()
{
std::vector<int> foo (3,0);
std::vector<int> bar (5,0);

bar = foo;
foo = std::vector<int>();

std::cout << "Size of foo: " << int(foo.size()) << '\n';
std::cout << "Size of bar: " << int(bar.size()) << '\n';
return 0;
}
输出
1
2
Size of foo: 0
Size of bar: 3

Complexity

Linear in size.

Iterator validity

All iterators, references and pointers related to this container before the call are invalidated.

In the move assignment, iterators, pointers and references referring to elements in x are also invalidated.

Data races

  1. All copied elements are accessed.

  2. The move assignment (2) modifies x.

  3. The container and all its elements are modified.

Exception safety

  1. Basic guarantee: if an exception is thrown, the container is in a valid state.

  2. If allocator_traits::construct is not supported with the appropriate arguments for the element constructions, or if value_type is not copy assignable (or move assignable for (2)), it causes undefined behavior.

std::vector::size

std::vector::size: https://cplusplus.com/reference/vector/vector/size/

1
size_type size() const noexcept;

Return size

Returns the number of elements in the vector.

This is the number of actual objects held in the vector, which is not necessarily equal to its storage capacity.

Parameters

none

Return Value

  1. The number of elements in the container.

  2. Member type size_type is an unsigned integral type.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// vector::size
#include <iostream>
#include <vector>

int main ()
{
std::vector<int> myints;
std::cout << "0. size: " << myints.size() << '\n';

for (int i=0; i<10; i++) myints.push_back(i);
std::cout << "1. size: " << myints.size() << '\n';

myints.insert (myints.end(),10,100);
std::cout << "2. size: " << myints.size() << '\n';

myints.pop_back();
std::cout << "3. size: " << myints.size() << '\n';

return 0;
}
输出
1
2
3
4
0. size: 0
1. size: 10
2. size: 20
3. size: 19

Complexity

Constant.

Iterator validity

No changes.

Data races

  1. The container is accessed.

  2. No contained elements are accessed: concurrently accessing or modifying them is safe.

Exception safety

No-throw guarantee: this member function never throws exceptions.

std::vector::resize

std::vector::resize: https://cplusplus.com/reference/vector/vector/resize/

1
void resize (size_type n);void resize (size_type n, const value_type& val);

Change size

Resizes the container so that it contains n elements.

If n is smaller than the current container size, the content is reduced to its first n elements, removing those beyond (and destroying them).

If n is greater than the current container size, the content is expanded by inserting at the end as many elements as needed to reach a size of n. If val is specified, the new elements are initialized as copies of val, otherwise, they are value-initialized.

If n is also greater than the current container capacity, an automatic reallocation of the allocated storage space takes place.

Notice that this function changes the actual content of the container by inserting or erasing elements from it.

Parameters

n

  1. New container size, expressed in number of elements.

  2. Member type size_type is an unsigned integral type.

val

  1. Object whose content is copied to the added elements in case that n is greater than the current container size.

  2. If not specified, the default constructor is used instead.

  3. Member type value_type is the type of the elements in the container, defined in vector as an alias of the first template parameter (T).

Return Value

none

If a reallocation happens, the storage is allocated using the container’s allocator, which may throw exceptions on failure (for the default allocator, bad_alloc is thrown if the allocation request does not succeed).

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// resizing vector
#include <iostream>
#include <vector>

int main ()
{
std::vector<int> myvector;

// set some initial content:
for (int i=1;i<10;i++) myvector.push_back(i);

myvector.resize(5);
myvector.resize(8,100);
myvector.resize(12);

std::cout << "myvector contains:";
for (int i=0;i<myvector.size();i++)
std::cout << ' ' << myvector[i];
std::cout << '\n';

return 0;
}
输出
1
myvector contains: 1 2 3 4 5 100 100 100 0 0 0 0

Complexity

  1. Linear on the number of elements inserted/erased (constructions/destructions).

  2. If a reallocation happens, the reallocation is itself up to linear in the entire vector size.

Iterator validity

  1. In case the container shrinks, all iterators, pointers and references to elements that have not been removed remain valid after the resize and refer to the same elements they were referring to before the call.

  2. If the container expands, the end iterator is invalidated and, if it has to reallocate storage, all iterators, pointers and references related to this container are also invalidated.

Data races

  1. The container is modified.

  2. If a reallocation happens, all contained elements are modified.

  3. Otherwise, none of the elements before n is accessed, and concurrently accessing or modifying them is safe.

Exception safety

  1. If n is less than or equal to the size of the container, the function never throws exceptions (no-throw guarantee).

  2. If n is greater and a reallocation happens, there are no changes in the container in case of exception (strong guarantee) if the type of the elements is either copyable or no-throw moveable.

  3. Otherwise, if an exception is thrown, the container is left with a valid state (basic guarantee).

std::vector::operator[]

std::vector::operator[]: https://cplusplus.com/reference/vector/vector/operator[]/

1
reference operator[] (size_type n);const_reference operator[] (size_type n) const;

Access element

Returns a reference to the element at position n in the vector container.

A similar member function, vector::at, has the same behavior as this operator function, except that vector::at is bound-checked and signals if the requested position is out of range by throwing an out_of_range exception.

Portable programs should never call this function with an argument n that is out of range, since this causes undefined behavior.

Parameters

n

  1. Position of an element in the container.

  2. Notice that the first element has a position of 0 (not 1).

  3. Member type size_type is an unsigned integral type.

Return Value

  1. The element at the specified position in the vector.

  2. If the vector object is const-qualified, the function returns a const_reference. Otherwise, it returns a reference.

  3. Member types reference and const_reference are the reference types to the elements of the container (see vector member types).

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// vector::operator[]
#include <iostream>
#include <vector>

int main ()
{
std::vector<int> myvector (10); // 10 zero-initialized elements

std::vector<int>::size_type sz = myvector.size();

// assign some values:
for (unsigned i=0; i<sz; i++) myvector[i]=i;

// reverse vector using operator[]:
for (unsigned i=0; i<sz/2; i++)
{
int temp;
temp = myvector[sz-1-i];
myvector[sz-1-i]=myvector[i];
myvector[i]=temp;
}

std::cout << "myvector contains:";
for (unsigned i=0; i<sz; i++)
std::cout << ' ' << myvector[i];
std::cout << '\n';

return 0;
}
输出
1
myvector contains: 9 8 7 6 5 4 3 2 1 0

Complexity

Constant.

Iterator validity

No changes.

Data races

  1. The container is accessed (neither the const nor the non-const versions modify the container).

  2. The reference returned can be used to access or modify elements. Concurrently accessing or modifying different elements is safe.

Exception safety

  1. If the container size is greater than n, the function never throws exceptions (no-throw guarantee).

  2. Otherwise, the behavior is undefined.

std::vector::push_back

std::vector::push_back: https://cplusplus.com/reference/vector/vector/push_back/

1
2
void push_back (const value_type& val);
void push_back (value_type&& val);

Add element at the end

Adds a new element at the end of the vector, after its current last element. The content of val is copied (or moved) to the new element.

This effectively increases the container size by one, which causes an automatic reallocation of the allocated storage space if -and only if- the new vector size surpasses the current vector capacity.

Parameters

val

  1. Value to be copied (or moved) to the new element.

  2. Member type value_type is the type of the elements in the container, defined in vector as an alias of its first template parameter (T).

Return Value

none

If a reallocation happens, the storage is allocated using the container's allocator, which may throw exceptions on failure (for the default allocator, bad_alloc is thrown if the allocation request does not succeed).

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// vector::push_back
#include <iostream>
#include <vector>

int main ()
{
std::vector<int> myvector;
int myint;

std::cout << "Please enter some integers (enter 0 to end):\n";

do {
std::cin >> myint;
myvector.push_back (myint);
} while (myint);

std::cout << "myvector stores " << int(myvector.size()) << " numbers.\n";

return 0;
}

The example uses push_back to add a new element to the vector each time a new integer is read.

Complexity

Constant (amortized time, reallocation may happen).

If a reallocation happens, the reallocation is itself up to linear in the entire size.

Iterator validity

  1. If a reallocation happens, all iterators, pointers and references related to the container are invalidated.

  2. Otherwise, only the end iterator is invalidated, and all iterators, pointers and references to elements are guaranteed to keep referring to the same elements they were referring to before the call.

Data races

  1. The container is modified.

  2. If a reallocation happens, all contained elements are modified.

  3. Otherwise, no existing element is accessed, and concurrently accessing or modifying them is safe.

Exception safety

  1. If no reallocations happen, there are no changes in the container in case of exception (strong guarantee).

  2. If a reallocation happens, the strong guarantee is also given if the type of the elements is either copyable or no-throw moveable.

  3. Otherwise, the container is guaranteed to end in a valid state (basic guarantee).

  4. If allocator_traits::construct is not supported with val as argument, it causes undefined behavior.

std::vector::clear

std::vector::clear: https://cplusplus.com/reference/vector/vector/clear/

1
void clear() noexcept;

Clear content

Removes all elements from the vector (which are destroyed), leaving the container with a size of 0.

A reallocation is not guaranteed to happen, and the vector capacity is not guaranteed to change due to calling this function. A typical alternative that forces a reallocation is to use swap:

1
vector<T>().swap(x);   // clear x reallocating

Parameters

none

Return Value

none

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// clearing vectors
#include <iostream>
#include <vector>

int main ()
{
std::vector<int> myvector;
myvector.push_back (100);
myvector.push_back (200);
myvector.push_back (300);

std::cout << "myvector contains:";
for (unsigned i=0; i<myvector.size(); i++)
std::cout << ' ' << myvector[i];
std::cout << '\n';

myvector.clear();
myvector.push_back (1101);
myvector.push_back (2202);

std::cout << "myvector contains:";
for (unsigned i=0; i<myvector.size(); i++)
std::cout << ' ' << myvector[i];
std::cout << '\n';

return 0;
}
输出
1
2
myvector contains: 100 200 300
myvector contains: 1101 2202

Complexity

  1. Linear in size (destructions).

  2. This may be optimized to constant complexity for trivially-destructible types (such as scalar or PODs), where elements need not be destroyed.

Iterator validity

All iterators, pointers and references related to this container are invalidated.

Data races

  1. The container is modified.

  2. All contained elements are modified.

Exception safety

No-throw guarantee: this member function never throws exceptions.

Input/Output Stream Library

<iostream>

<iostream>: https://cplusplus.com/reference/iostream/

<iostream>: Standard Input / Output Streams Library.

Narrow characters (char)

  • cout: Standard output stream (object)

  • cerr: Standard output stream for errors (object)

std::cout

std::cout: https://cplusplus.com/reference/iostream/cout/

extern ostream cout;

Standard output stream

Object of class ostream that represents the standard output stream oriented to narrow characters (of type char). It corresponds to the C stream stdout.

The standard output stream is the default destination of characters determined by the environment. This destination may be shared with more standard objects (such as cerr or clog).

As an object of class ostream, characters can be written to it either as formatted data using the insertion operator (operator<<) or as unformatted data, using member functions such as write.

The object is declared in header <iostream> with external linkage and static duration: it lasts the entire duration of the program.


cout is not tied to any other output stream.

By default, cout is synchronized with stdout.

A program should not mix output operations on cout with output operations on wcout (or with other wide-oriented output operations on stdout): Once an output operation has been performed on either, the standard output stream acquires an orientation (either narrow or wide) that can only be safely changed by calling freopen on stdout.

std::cerr

std::cerr: https://cplusplus.com/reference/iostream/cerr/

extern ostream cerr;

Standard output stream for errors

Object of class ostream that represents the standard error stream oriented to narrow characters (of type char). It corresponds to the C stream stderr.

The standard error stream is a destination of characters determined by the environment. This destination may be shared by more than one standard object (such as cout or clog).

As an object of class ostream, characters can be written to it either as formatted data using the insertion operator (operator<<) or as unformatted data, using member functions such as write.

The object is declared in header <iostream> with external linkage and static duration: it lasts the entire duration of the program.


cerr is not tied to any other output stream.

By default, cerr is synchronized with stderr.

A program should not mix output operations on cerr with output operations on wcerr or wclog (or with other wide-oriented output operations on stderr): Once an output operation has been performed on either, the standard error stream acquires an orientation (either narrow or wide) that can only be safely changed by calling freopen on stderr.

Atomics and threading library

Miscellaneous headers

<algorithm>

<algorithm>: https://cplusplus.com/reference/algorithm/

<algorithm>: Standard Template Library: Algorithms.

Modifying sequence operations

  • transform: Transform range (function template)

std::transform

std::transform: https://cplusplus.com/reference/algorithm/transform/

1
2
3
4
unary operation(1)	
template <class InputIterator, class OutputIterator, class UnaryOperation> OutputIterator transform (InputIterator first1, InputIterator last1, OutputIterator result, UnaryOperation op);
binary operation(2)
template <class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperation> OutputIterator transform (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryOperation binary_op);

Transform range

Applies an operation sequentially to the elements of one (1) or two (2) ranges and stores the result in the range that begins at result.

(1) unary operation:

Applies op to each of the elements in the range [first1,last1) and stores the value returned by each operation in the range that begins at result.

(2) binary operation:

Calls binary_op using each of the elements in the range [first1,last1) as first argument, and the respective argument in the range that begins at first2 as second argument. The value returned by each call is stored in the range that begins at result.

The behavior of this function template is equivalent to:

1
2
3
4
5
6
7
8
9
10
template <class InputIterator, class OutputIterator, class UnaryOperator>
OutputIterator transform (InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperator op)
{
while (first1 != last1) {
*result = op(*first1); // or: *result=binary_op(*first1,*first2++);
++result; ++first1;
}
return result;
}

The function allows for the destination range to be the same as one of the input ranges to make transformations in place.

Parameters

first1, last1

Input iterators to the initial and final positions of the first sequence. The range used is [first1,last1), which contains all the elements between first1 and last1, including the element pointed to by first1 but not the element pointed to by last1.

first2

Input iterator to the initial position of the second range. The range includes as many elements as [first1,last1).

result

Output iterator to the initial position of the range where the operation results are stored. The range includes as many elements as [first1,last1).

op

Unary function that accepts one element of the type pointed to by InputIterator as argument, and returns some result value convertible to the type pointed to by OutputIterator.

This can either be a function pointer or a function object.

binary_op

Binary function that accepts two elements as argument (one of each of the two sequences), and returns some result value convertible to the type pointed to by OutputIterator.

This can either be a function pointer or a function object.


Neither op nor binary_op should directly modify the elements passed as its arguments: These are indirectly modified by the algorithm (using the return value) if the same range is specified for result.

Return Value

An iterator pointing to the element that follows the last element written in the result sequence.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// transform algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::transform
#include <vector> // std::vector
#include <functional> // std::plus

int op_increase (int i) { return ++i; }

int main () {
std::vector<int> foo;
std::vector<int> bar;

// set some values:
for (int i=1; i<6; i++)
foo.push_back (i*10); // foo: 10 20 30 40 50

bar.resize(foo.size()); // allocate space

std::transform (foo.begin(), foo.end(), bar.begin(), op_increase);
// bar: 11 21 31 41 51

// std::plus adds together its two arguments:
std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), std::plus<int>());
// foo: 21 41 61 81 101

std::cout << "foo contains:";
for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';

return 0;
}
输出
1
foo contains: 21 41 61 81 101

Complexity

Linear in the distance between first1 and last1: Performs one assignment and one application of op (or binary_op) per element.

Data races

The objects in the range [first1,last1) (and eventually those in the range beginning at first2) are accessed (each object is accessed exactly once).

The objects in the range beginning at result are modified.

Exceptions

Throws if any of the function calls, the assignments or the operations on iterators throws.

Note that invalid arguments cause undefined behavior.

Sorting

  • sort: Sort elements in range (function template)

std::sort

std::sort: https://cplusplus.com/reference/algorithm/sort/

1
2
3
4
default (1)	
template <class RandomAccessIterator> void sort (RandomAccessIterator first, RandomAccessIterator last);
custom (2)
template <class RandomAccessIterator, class Compare> void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

Sort elements in range

Sorts the elements in the range [first,last) into ascending order.

The elements are compared using operator< for the first version, and comp for the second.

Equivalent elements are not guaranteed to keep their original relative order (see stable_sort).

Parameters

first, last

  1. Random-access iterators to the initial and final positions of the sequence to be sorted. The range used is [first,last), which contains all the elements between first and last, including the element pointed by first but not the element pointed by last.

  2. RandomAccessIterator shall point to a type for which swap is properly defined and which is both move-constructible and move-assignable.

comp

  1. Binary function that accepts two elements in the range as arguments, and returns a value convertible to bool. The value returned indicates whether the element passed as first argument is considered to go before the second in the specific strict weak ordering it defines.

  2. The function shall not modify any of its arguments.

  3. This can either be a function pointer or a function object.

Return Value

none.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// sort algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::sort
#include <vector> // std::vector

bool myfunction (int i,int j) { return (i<j); }

struct myclass {
bool operator() (int i,int j) { return (i<j);}
} myobject;

int main () {
int myints[] = {32,71,12,45,26,80,53,33};
std::vector<int> myvector (myints, myints+8); // 32 71 12 45 26 80 53 33

// using default comparison (operator <):
std::sort (myvector.begin(), myvector.begin()+4); //(12 32 45 71)26 80 53 33

// using function as comp
std::sort (myvector.begin()+4, myvector.end(), myfunction); // 12 32 45 71(26 33 53 80)

// using object as comp
std::sort (myvector.begin(), myvector.end(), myobject); //(12 26 32 33 45 53 71 80)

// print out content:
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';

return 0;
}
可能的输出
1
myvector contains: 12 26 32 33 45 53 71 80

Complexity

On average, linearithmic in the distance between first and last: Performs approximately N*log2(N) (where N is this distance) comparisons of elements, and up to that many element swaps (or moves).

Data races

The objects in the range [first,last) are modified.

Min/max

  • min: Return the smallest (function template)

std::min

std::min: https://cplusplus.com/reference/algorithm/min/

1
2
3
4
5
6
default (1)	
template <class T> const T& min (const T& a, const T& b);
custom (2)
template <class T, class Compare> const T& min (const T& a, const T& b, Compare comp);
initializer list (3)
template <class T> T min (initializer_list<T> il);template <class T, class Compare> T min (initializer_list<T> il, Compare comp);

Return the smallest

Returns the smallest of a and b. If both are equivalent, a is returned.

The versions for initializer lists (3) return the smallest of all the elements in the list. Returning the first of them if these are more than one.

The function uses operator< (or comp, if provided) to compare the values.

The behavior of this function template (C++98) is equivalent to:

1
2
3
template <class T> const T& min (const T& a, const T& b) {
return !(b<a)?a:b; // or: return !comp(b,a)?a:b; for version (2)
}

Parameters

a, b

  1. Values to compare.

comp

  1. Binary function that accepts two values of type T as arguments, and returns a value convertible to bool. The value returned indicates whether the element passed as first argument is considered less than the second.

  2. The function shall not modify any of its arguments.

  3. This can either be a function pointer or a function object.

il

  1. An initializer_list object.

  2. These objects are automatically constructed from initializer list declarators.

T shall support being compared with operator<.

Return Value

The lesser of the values passed as arguments.

Example

1
2
3
4
5
6
7
8
9
10
11
// min example
#include <iostream> // std::cout
#include <algorithm> // std::min

int main () {
std::cout << "min(1,2)==" << std::min(1,2) << '\n';
std::cout << "min(2,1)==" << std::min(2,1) << '\n';
std::cout << "min('a','z')==" << std::min('a','z') << '\n';
std::cout << "min(3.14,2.72)==" << std::min(3.14,2.72) << '\n';
return 0;
}
输出
1
2
3
4
min(1,2)==1
min(2,1)==1
min('a','z')==a
min(3.14,2.72)==2.72

Complexity

Linear in one less than the number of elements compared (constant for (1) and (2)).

<iterator>

<iterator>: https://cplusplus.com/reference/iterator/

<iterator>: Iterator definitions (header).

Iterator operations

  • begin: Iterator to beginning (function template)

std::begin

std::begin: https://cplusplus.com/reference/iterator/begin/

1
2
3
4
container (1)	
template <class Container> auto begin (Container& cont) -> decltype (cont.begin());template <class Container> auto begin (const Container& cont) -> decltype (cont.begin());
array (2)
template <class T, size_t N> T* begin (T(&arr)[N]);

Iterator to beginning

Returns an iterator pointing to the first element in the sequence:

(1) Container

The function returns cont.begin().

(2) Array

The function returns the array-to-pointer conversion of its argument.

If the sequence is empty, the returned value shall not be dereferenced.

These function templates are defined in multiple headers: Each of these headers includes the generic templates for all container and array types and not simply a specific overload. The headers are: <iterator>, <array>, <deque>, <forward_list>, <list>, <map>, <regex>, <set>, <string>, <unordered_map>, <unordered_set> and <vector>.

Conversely, begin is overloaded (with a different definition) in headers <initializer_list> and <valarray>.

Parameters

cont

  1. An object of a class type for which member begin is defined.

arr

  1. An array.

Return Value

For (1), the same as returned by cont.begin().

For (2), a pointer to the first element in the array.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// std::begin / std::end example
#include <iostream> // std::cout
#include <vector> // std::vector, std::begin, std::end

int main () {
int foo[] = {10,20,30,40,50};
std::vector<int> bar;

// iterate foo: inserting into bar
for (auto it = std::begin(foo); it!=std::end(foo); ++it)
bar.push_back(*it);

// iterate bar: print contents:
std::cout << "bar contains:";
for (auto it = std::begin(bar); it!=std::end(bar); ++it)
std::cout << ' ' << *it;
std::cout << '\n';

return 0;
}
输出
1
bar contains: 10 20 30 40 50

Data races

The argument is accessed but not modified.

None of the elements in the sequence are accessed by the call, but the iterator returned can be used to access or modify them.

<string>

<string>: https://cplusplus.com/reference/string/

<string>: Strings.

string

  • c_str: Get C string equivalent (public member function)

std::string::c_str

std::string::c_str: https://cplusplus.com/reference/string/string/c_str/

const char* c_str() const;

Get C string equivalent

Returns a pointer to an array that contains a null-terminated sequence of characters (i.e., a C-string) representing the current value of the string object.

This array includes the same sequence of characters that make up the value of the string object plus an additional terminating null-character ('\0') at the end.

Parameters

none

Return Value

A pointer to the c-string representation of the string object’s value.

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// strings and c-strings
#include <iostream>
#include <cstring>
#include <string>

int main ()
{
std::string str ("Please split this sentence into tokens");

char * cstr = new char [str.length()+1];
std::strcpy (cstr, str.c_str());

// cstr now contains a c-string copy of str

char * p = std::strtok (cstr," ");
while (p!=0)
{
std::cout << p << '\n';
p = std::strtok(NULL," ");
}

delete[] cstr;
return 0;
}
输出
1
2
3
4
5
6
Please
split
this
sentence
into
tokens

Convert to strings

  • to_string: Convert numerical value to string (function)

std::to_string

std::to_string: https://cplusplus.com/reference/string/to_string/

string to_string (int val);string to_string (long val);string to_string (long long val);string to_string (unsigned val);string to_string (unsigned long val);string to_string (unsigned long long val);string to_string (float val);string to_string (double val);string to_string (long double val);

Convert numerical value to string

Returns a string with the representation of val.

Parameters

val

  1. Numerical value.

Return Value

A string object containing the representation of val as a sequence of characters.

Example

1
2
3
4
5
6
7
8
9
10
11
12
// to_string example
#include <iostream> // std::cout
#include <string> // std::string, std::to_string

int main ()
{
std::string pi = "pi is " + std::to_string(3.1415926);
std::string perfect = std::to_string(1+2+4+7+14) + " is a perfect number";
std::cout << pi << '\n';
std::cout << perfect << '\n';
return 0;
}
可能的输出
1
2
pi is 3.141593
28 is a perfect number

<utility>

<utility>: https://cplusplus.com/reference/utility/

<utility>: Utility components (header).

Types

  • pair: Pair of values (class template)

std::pair

std::pair: https://cplusplus.com/reference/utility/pair/

1
template <class T1, class T2> struct pair;

Pair of values

This class couples together a pair of values, which may be of different types (T1 and T2). The individual values can be accessed through its public members first and second.

Pairs are a particular case of tuple.

Template parameters

T1

Type of member first, aliased as first_type.

T2

Type of member second, aliased as second_type.

Member types

member type definition notes
first_type The first template parameter (T1) Type of member first.
second_type The second template parameter (T2) Type of member second.

Member variables

member variable definition
first The first value in the pair
second The second value in the pair

C++ 语法

移位运算符

C++ 中,移位运算符有双目移位运算符:<<(左移)和 >>(右移)。

左移运算是将一个二进制位的操作数按指定移动的位数左移位移出位被丢弃,右边的空位一律补 0

右移运算是将一个二进制位的操作数按指定移动的位数右移动移出位被丢弃,左边移出的空位或者一律补 0,或者补符号位,这由不同的机器而定。在使用补码作为机器数的机器中,正数的符号位为 0,负数的符号位为 1右移对于无符号类型强制补 0,对于有符号类型续补符号位

常函数和常对象

源教程链接: https://blog.csdn.net/qq_63610563/article/details/124088619 .

  • 常函数: 成员函数后加 const 后, 称这个函数为常函数.

    • 常函数内不可以修改成员属性;

    • 成员属性声明时加关键字 mutable 后, 在常函数中可以修改.

  • 常对象: 声明对象前加 const, 称该对象为常对象.

    • 常对象只能调用常函数.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>
using namespace std;

class person
{
public:
void show()const
{
m_A = 100;
}
int m_A;
};

int main()
{
person p;
p.show();
system("pause");
return 0;
}

第7行报错, 因为 m_A 其实为 this->m_A, this 指针的本质是指针常量, 指向是不可改的, 包括 this=NULL 也是不行的. 要变成可修改的值, 需要把第 11 行改为 mutable int m_A.

不加 const, this 的本意:person* const this, 不可以改 this 的指向,可以改指向的变量的值.

第 7 行加 const, this 的本意:const person* const this, 不可以修改 this 的指向, 也不可以修改指向的变量的值.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<iostream>
using namespace std;

class person
{
public:
void show()const
{
this->m_B = 100;
}
int m_A;
mutable int m_B;
};

int main()
{
const person p//在对象前加const,变常对象
p.m_A = 100;//报错
p.m_B = 100;//正确
system("pause");
return 0;
}

第 18 行报错的原因如上例所说,常对象的成员属性也不可以修改,要加 mutable.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
using namespace std;

class person
{
public:
void show()
{ }
};

int main()
{
const person p//在对象前加const,变常对象
p.show();
system("pause");
return 0;
}

第 14 行报错, 因为常对象只能调用常函数, 而 show() 不是常函数.

计算机基础

ASCII

ASCII (American Standard Code for Information Interchange):美国信息交换标准代码是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语其他西欧语言。它是最通用的信息交换标准,并等同于国际标准 ISO/IEC 646。ASCII第一次以规范标准的类型发表是在 1967 年,最后一次更新则是在 1986 年,到目前为止共定义了 128 个字符。

ASCII 码表

原教程地址: https://zh.cppreference.com/w/cpp/language/ascii .

下列码表含有全部 128 个 ASCII 十进制 (dec) 、八进制 (oct) 、十六进制 (hex) 及字符 (ch) 编码。

dec oct hex ch dec oct hex ch dec oct hex ch dec oct hex ch
0 0 00 NUL (空) 32 40 20 (空格) 64 100 40 @ 96 140 60 `
1 1 01 SOH (标题开始) 33 41 21 ! 65 101 41 A 97 141 61 a
2 2 02 STX (正文开始) 34 42 22 " 66 102 42 B 98 142 62 b
3 3 03 ETX (正文结束) 35 43 23 # 67 103 43 C 99 143 63 c
4 4 04 EOT (传送结束) 36 44 24 $ 68 104 44 D 100 144 64 d
5 5 05 ENQ (询问) 37 45 25 % 69 105 45 E 101 145 65 e
6 6 06 ACK (确认) 38 46 26 & 70 106 46 F 102 146 66 f
7 7 07 BEL (响铃) 39 47 27 ' 71 107 47 G 103 147 67 g
8 10 08 BS (退格) 40 50 28 ( 72 110 48 H 104 150 68 h
9 11 09 HT (横向制表) 41 51 29 ) 73 111 49 I 105 151 69 i
10 12 0a LF (换行) 42 52 2a * 74 112 4a J 106 152 6a j
11 13 0b VT (纵向制表) 43 53 2b + 75 113 4b K 107 153 6b k
12 14 0c FF (换页) 44 54 2c , 76 114 4c L 108 154 6c l
13 15 0d CR (回车) 45 55 2d - 77 115 4d M 109 155 6d m
14 16 0e SO (移出) 46 56 2e . 78 116 4e N 110 156 6e n
15 17 0f SI (移入) 47 57 2f / 79 117 4f O 111 157 6f o
16 20 10 DLE (退出数据链) 48 60 30 0 80 120 50 P 112 160 70 p
17 21 11 DC1 (设备控制1) 49 61 31 1 81 121 51 Q 113 161 71 q
18 22 12 DC2 (设备控制2) 50 62 32 2 82 122 52 R 114 162 72 r
19 23 13 DC3 (设备控制3) 51 63 33 3 83 123 53 S 115 163 73 s
20 24 14 DC4 (设备控制4) 52 64 34 4 84 124 54 T 116 164 74 t
21 25 15 NAK (反确认) 53 65 35 5 85 125 55 U 117 165 75 u
22 26 16 SYN (同步空闲) 54 66 36 6 86 126 56 V 118 166 76 v
23 27 17 ETB (传输块结束) 55 67 37 7 87 127 57 W 119 167 77 w
24 30 18 CAN (取消) 56 70 38 8 88 130 58 X 120 170 78 x
25 31 19 EM (媒介结束) 57 71 39 9 89 131 59 Y 121 171 79 y
26 32 1a SUB (替换) 58 72 3a : 90 132 5a Z 122 172 7a z
27 33 1b ESC (退出) 59 73 3b ; 91 133 5b [ 123 173 7b {
28 34 1c FS (文件分隔符) 60 74 3c < 92 134 5c \ 124 174 7c |
29 35 1d GS (组分隔符) 61 75 3d = 93 135 5d ] 125 175 7d }
30 36 1e RS (记录分隔符) 62 76 3e > 94 136 5e ^ 126 176 7e ~
31 37 1f US (单元分隔符) 63 77 3f ? 95 137 5f _ 127 177 7f DEL (删除)

注意:在 Unicode 中, ASCII 字符块被称作 U+0000…U+007F 基础拉丁( Basic Latin )。

example:

1
2
3
4
5
6
7
8
9
10
#include <iostream>
int main()
{
std::cout << "Printable ASCII:\n";
for (char i = 32; i < 127; ++i) {
std::cout << i << ' ';
if (i % 16 == 15)
std::cout << '\n';
}
}

可能的输出:

1
2
3
4
5
6
7
Printable ASCII:
! " # $ % & ' ( ) * + , - . /
0 1 2 3 4 5 6 7 8 9 : ; < = > ?
@ A B C D E F G H I J K L M N O
P Q R S T U V W X Y Z [ \ ] ^ _
` a b c d e f g h i j k l m n o
p q r s t u v w x y z { | } ~

常用的 C++ 内置函数

std::numeric_limits<T>::infinity

API 地址: https://en.cppreference.com/w/cpp/types/numeric_limits/infinity .

1
2
3
4
static T infinity() throw();
(until C++11)
static constexpr T infinity() noexcept;
(since C++11)

Returns the special value “positive infinity”, as represented by the floating-point type T. Only meaningful if std::numeric_limits<T>::has_infinity == true. In IEEE 754, the most common binary representation of floating-point numbers, the positive infinity is the value with all bits of the exponent set and all bits of the fraction cleared.

Return value

T std::numeric_limits<T>::infinity()
/* non-specialized */ T()
bool false
char 0
signed char 0
unsigned char 0
wchar_t 0
char8_t (C++20) 0
char16_t (C++11) 0
char32_t (C++11) 0
short 0
unsigned short 0
int 0
unsigned int 0
long 0
unsigned long 0
long long (C++11) 0
unsigned long long (C++11) 0
float HUGE_VALF
double HUGE_VAL
long double HUGE_VALL

Example

1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <limits>
int main()
{
double max = std::numeric_limits<double>::max();
double inf = std::numeric_limits<double>::infinity();

if(inf > max)
std::cout << inf << " is greater than " << max << '\n';
}

Output:

1
inf is greater than 1.79769e+308

std::is_same

API 地址: https://zh.cppreference.com/w/cpp/types/is_same .

在标头 <type_traits> 定义

(C++11 起)

1
2
template< class T, class U >
struct is_same;

TU 指名同一类型(考虑 const/volatile 限定),则提供等于 true 的成员常量 value 。否则 valuefalse

满足交换律,即对于任何二个类型 TUis_same<T, U>::value == true 当且仅当 is_same<U, T>::value == true

添加 is_sameis_same_v (C++17 起) 的特化的程序行为未定义。

辅助变量模板

(C++17 起)

1
2
template< class T, class U >
inline constexpr bool is_same_v = is_same<T, U>::value;

继承自 std::integral_constant

成员常量

  • value[静态]: 若 TU 是同一类型则为 true ,否则为 false (公开静态成员常量)

成员函数

  • operator bool: 转换对象为 bool ,返回 value (公开成员函数)

  • operator(): (C++14), 返回 value (公开成员函数)

成员类型

类型 定义
value_type bool
type std::integral_constant<bool, value>

可能的实现

1
2
3
4
5
template<class T, class U>
struct is_same : std::false_type {};

template<class T>
struct is_same<T, T> : std::true_type {};

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <type_traits>
#include <cstdint>

void print_separator()
{
std::cout << "-----\n";
}

int main()
{
std::cout << std::boolalpha;

// 一些实现定义状况
std::cout << std::is_same<int, std::int32_t>::value << '\n';
// 若 'int' 为 32 位则通常为 true
std::cout << std::is_same<int, std::int64_t>::value << '\n';
// 若使用 ILP64 数据模型则可能为 true

print_separator();

// 'float' 决非整数类型
std::cout << std::is_same<float, std::int32_t>::value << '\n'; // false

print_separator();

// 'int' 为隐式的 'signed'
std::cout << std::is_same<int, int>::value << "\n"; // true
std::cout << std::is_same<int, unsigned int>::value << "\n"; // false
std::cout << std::is_same<int, signed int>::value << "\n"; // true

print_separator();

// 不同于其他类型, 'char' 既非 'unsigned' 亦非 'signed'
std::cout << std::is_same<char, char>::value << "\n"; // true
std::cout << std::is_same<char, unsigned char>::value << "\n"; // false
std::cout << std::is_same<char, signed char>::value << "\n"; // false
}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
true
false
-----
false
-----
true
false
true
-----
true
false
false

std::tie

API 地址: https://zh.cppreference.com/w/cpp/utility/tuple/tie .

在标头 <tuple> 定义

1
2
3
4
5
6
7
template< class... Types >
std::tuple<Types&...> tie( Types&... args ) noexcept;
(C++11 起)
(C++14 前)
template< class... Types >
constexpr std::tuple<Types&...> tie( Types&... args ) noexcept;
(C++14 起)

创建到其参数或 std::ignore 实例的左值引用的 tuple 。

参数

  • args: 构造 tuple 所用的零或更多左值参数

返回值

含左值引用的 std::tuple 对象。

可能的实现

1
2
3
4
5
template <typename... Args>
constexpr // C++14 起
std::tuple<Args&...> tie(Args&... args) noexcept {
return {args...};
}

注解

std::tie 可用于解包 std::pair ,因为 std::tuple 拥有从 pair 的转换赋值:

1
2
bool result;
std::tie(std::ignore, result) = set.insert(value);

示例

std::tie 能用于引入字典序比较到结构体,或解包 tuple

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <string>
#include <set>
#include <tuple>

struct S {
int n;
std::string s;
float d;
bool operator<(const S& rhs) const
{
// 比较 n 与 rhs.n,
// 然后为 s 与 rhs.s,
// 然后为 d 与 rhs.d
return std::tie(n, s, d) < std::tie(rhs.n, rhs.s, rhs.d);
}
};

int main()
{
std::set<S> set_of_s; // S 为可比较小于 (LessThanComparable)

S value{42, "Test", 3.14};
std::set<S>::iterator iter;
bool inserted;

// 解包 insert 的返回值为 iter 与 inserted
std::tie(iter, inserted) = set_of_s.insert(value);

if (inserted)
std::cout << "Value was inserted successfully\n";
}

输出:

1
Value was inserted successfully

std::ignore

API 地址: https://zh.cppreference.com/w/cpp/utility/tuple/ignore .

在标头 <tuple> 定义

1
2
3
4
5
const /*unspecified*/ ignore;
(C++11 起)
(C++17 前)
inline constexpr /*unspecified*/ ignore;
(C++17 起)

任何值均可赋给而无效果的未指定类型的对象。目的是令 std::tie 在解包 std::tuple 时作为不使用的参数的占位符使用。

可能的实现

1
2
3
4
5
6
7
8
namespace detail {
struct ignore_t {
template <typename T>
constexpr // C++14 起要求
void operator=(T&&) const noexcept {}
};
}
inline constexpr detail::ignore_t ignore; // C++17 前仅 'const'

示例

解包 set.insert() 所返回的 pair ,但只保存布尔值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
#include <set>
#include <tuple>

int main()
{
std::set<std::string> set_of_str;
bool inserted = false;
std::tie(std::ignore, inserted) = set_of_str.insert("Test");
if (inserted) {
std::cout << "Value was inserted successfully\n";
}
}

输出:

1
Value was inserted successfully

std::remove_reference

API 地址: https://zh.cppreference.com/w/cpp/types/remove_reference .

在标头 <type_traits> 定义

1
2
3
template< class T >
struct remove_reference;
(C++11 起)

若类型 T 为引用类型,则提供成员 typedef type ,其为 T 所引用的类型。否则 typeT

添加 remove_reference 的特化的程序行为未定义。

成员类型

名称 定义
type T 所引用的类型,或若 T 不是引用则为 T

辅助类型

1
2
3
template< class T >
using remove_reference_t = typename remove_reference<T>::type;
(C++14 起)

可能的实现

1
2
3
template< class T > struct remove_reference      {typedef T type;};
template< class T > struct remove_reference<T&> {typedef T type;};
template< class T > struct remove_reference<T&&> {typedef T type;};

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream> // std::cout
#include <type_traits> // std::is_same

template<class T1, class T2>
void print_is_same() {
std::cout << std::is_same<T1, T2>() << '\n';
}

int main() {
std::cout << std::boolalpha;

print_is_same<int, int>();
print_is_same<int, int &>();
print_is_same<int, int &&>();

print_is_same<int, std::remove_reference<int>::type>();
print_is_same<int, std::remove_reference<int &>::type>();
print_is_same<int, std::remove_reference<int &&>::type>();
}

输出:

1
2
3
4
5
6
true
false
false
true
true
true

std::boolalpha, std::noboolalpha

API 地址: https://zh.cppreference.com/w/cpp/io/manip/boolalpha

在标头 <ios> 定义

1
2
3
4
std::ios_base& boolalpha( std::ios_base& str );
(1)
std::ios_base& noboolalpha( std::ios_base& str );
(2)
  1. 启用流 str 中的 boolalpha 标志,如同通过调用 str.setf(std::ios_base::boolalpha)

  2. 禁用流 str 中的 boolalpha 标志,如同通过调用 str.unsetf(std::ios_base::boolalpha)

std::boolalphaI/O 操纵符,故可用如 out << std::boolalpha 的表达式对任何 std::basic_ostream 类型的 out ,或用如 in >> std::boolalpha 的表达式对任何 std::basic_istream 类型的 in 调用。

参数

str - 到 I/O 流的引用

返回值

str (到操纵后的流的引用)

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <sstream>
#include <locale>
#include <iostream>
int main()
{
// boolalpha 输出
std::cout << std::boolalpha
<< "boolalpha true: " << true << '\n'
<< "boolalpha false: " << false << '\n';
std::cout << std::noboolalpha
<< "noboolalpha true: " << true << '\n'
<< "noboolalpha false: " << false << '\n';
// boolalpha 分析
bool b1, b2;
std::istringstream is("true false");
is >> std::boolalpha >> b1 >> b2;
std::cout << '\"' << is.str() << "\" parsed as " << b1 << ' ' << b2 << '\n';
}

输出:

1
2
3
4
5
boolalpha true: true
boolalpha false: false
noboolalpha true: 1
noboolalpha false: 0
"true false" parsed as 1 0

std::make_tuple

API 地址: https://zh.cppreference.com/w/cpp/utility/tuple/make_tuple

在标头 <tuple> 定义

1
2
3
4
template< class... Types >
std::tuple<VTypes...> make_tuple( Types&&... args );
(C++11 起)
(C++14 起为 constexpr)

创建 tuple 对象,从参数类型推导目标类型。

对于每个 Types... 中的 TiVtypes... 中的对应类型 Vistd::decay<Ti>::type ,除非应用 std::decay 对某些类型 X 导致 std::reference_wrapper<X> ,该情况下推导的类型为 X&

参数

args - 构造 tuple 所用的零或更多参数

返回值

含给定值的 std::tuple 对象,如同用 std::tuple<VTypes...>(std::forward<Types>(t)...). 创建

可能的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
template <class T>
struct unwrap_refwrapper
{
using type = T;
};

template <class T>
struct unwrap_refwrapper<std::reference_wrapper<T>>
{
using type = T&;
};

template <class T>
using unwrap_decay_t = typename unwrap_refwrapper<typename std::decay<T>::type>::type;
// 或使用 std::unwrap_ref_decay_t ( C++20 起)

template <class... Types>
constexpr // since C++14
std::tuple<unwrap_decay_t<Types>...> make_tuple(Types&&... args)
{
return std::tuple<unwrap_decay_t<Types>...>(std::forward<Types>(args)...);
}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <tuple>
#include <functional>

std::tuple<int, int> f() // 此函数返回多值
{
int x = 5;
return std::make_tuple(x, 7); // return {x,7}; 于 C++17
}

int main()
{
// 异类 tuple 构造
int n = 1;
auto t = std::make_tuple(10, "Test", 3.14, std::ref(n), n);
n = 7;
std::cout << "The value of t is " << "("
<< std::get<0>(t) << ", " << std::get<1>(t) << ", "
<< std::get<2>(t) << ", " << std::get<3>(t) << ", "
<< std::get<4>(t) << ")\n";

// 返回多值的函数
int a, b;
std::tie(a, b) = f();
std::cout << a << " " << b << "\n";
}

输出:

1
2
The value of t is (10, Test, 3.14, 7, 1)
5 7

std::tuple_size<std::tuple>

API 地址: https://zh.cppreference.com/w/cpp/utility/tuple/tuple_size

在标头 <tuple> 定义

1
2
3
4
template< class... Types >
struct tuple_size< std::tuple<Types...> >
: std::integral_constant<std::size_t, sizeof...(Types)> { };
(C++11 起)

提供对 tuple 中元素数量的访问,作为编译时常量表达式。

继承自 std::integral_constant

成员常量

  • value[静态]: sizeof…(Types) (公开静态成员常量)

成员函数

  • operator std::size_t: 转换对象为 std::size_t ,返回 value (公开成员函数)

  • operator(): (C++14), 返回 value (公开成员函数)

成员类型

类型 定义
value_type std::size_t
type std::integral_constant<std::size_t, value>

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <tuple>

template <class T>
void test(T value)
{
int a[std::tuple_size_v<T>]; // 能用于编译时

std::cout << std::tuple_size<T>{} << ' ' // 或运行时
<< sizeof a << ' '
<< sizeof value << '\n';
}

int main()
{
test(std::make_tuple(1, 2, 3.14));
}

可能的输出:

1
3 12 16

std::accumulate

API 地址: https://zh.cppreference.com/w/cpp/algorithm/accumulate .

在标头 <numeric> 定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(1)
template< class InputIt, class T >
T accumulate( InputIt first, InputIt last, T init );
(C++20 前)
template< class InputIt, class T >
constexpr T accumulate( InputIt first, InputIt last, T init );
(C++20 起)
(2)
template< class InputIt, class T, class BinaryOperation >
T accumulate( InputIt first, InputIt last, T init,
BinaryOperation op );
(C++20 前)
template< class InputIt, class T, class BinaryOperation >
constexpr T accumulate( InputIt first, InputIt last, T init,
BinaryOperation op );
(C++20 起)

计算给定值 init 与给定范围 [first, last) 中元素的和。

  1. 以初始值 init 初始化(具有 T 类型的)累加器 acc,然后按顺序对范围 [first, last) 的每个迭代器 i 通过 acc = acc + *i (C++11 前)acc = std::move(acc) + *i (C++11 起) 进行累加。
  2. 以初始值 init 初始化(具有 T 类型的)累加器 acc,然后按顺序对范围 [first, last) 的每个迭代器 i 通过 acc = op(acc, *i) (C++11 前)acc = op(std::move(acc), *i) (C++11 起) 进行累加。
    如果 op 使涉及范围的任何迭代器(包含尾迭代器)失效,或修改了该范围内的任何元素,那么行为未定义。

参数

  • first, last - 要求和的元素范围

  • init - 和的初值

  • op - 被使用的二元函数对象。该函数的签名应当等价于:Ret fun(const Type1 &a, const Type2 &b); 签名中并不需要有 const &。类型 Type1 必须使得 T 类型的对象能隐式转换到 Type1。类型 Type2 必须使得 InputIt 类型的对象能在解引用后隐式转换到 Type2。 类型 Ret 必须使得 T 类型对象能被赋 Ret 类型值。

类型要求

  • InputIt 必须符合老式输入迭代器 (LegacyInputIterator) 的要求。

  • T 必须符合可复制赋值 (CopyAssignable) 和 可复制构造 (CopyConstructible) 的要求。

返回值

累加后的 acc

注解

std::accumulate 进行左折叠。为进行右折叠,必须逆转二元运算符的参数顺序,并使用逆序迭代器。

最常见的错误

init 的类型上进行 op,这能引入不期望的元素转换,例如 std::accumulate(v.begin(), v.end(), 0)vstd::vector<double> 时会给出错误的结果。

可能的实现

版本一

1
2
3
4
5
6
7
8
9
template<class InputIt, class T>
constexpr // C++20 起
T accumulate(InputIt first, InputIt last, T init)
{
for (; first != last; ++first)
init = std::move(init) + *first; // C++11 起有 std::move

return init;
}

版本二

1
2
3
4
5
6
7
8
9
template<class InputIt, class T, class BinaryOperation>
constexpr // C++20 起
T accumulate(InputIt first, InputIt last, T init, BinaryOperation op)
{
for (; first != last; ++first)
init = op(std::move(init), *first); // C++11 起有 std::move

return init;
}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <vector>
#include <numeric>
#include <string>
#include <functional>

int main()
{
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int sum = std::accumulate(v.begin(), v.end(), 0);
int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());

auto dash_fold = [](std::string a, int b)
{
return std::move(a) + '-' + std::to_string(b);
};

std::string s = std::accumulate(std::next(v.begin()), v.end(),
std::to_string(v[0]), // 用首元素开始
dash_fold);

// 使用逆向迭代器右折叠
std::string rs = std::accumulate(std::next(v.rbegin()), v.rend(),
std::to_string(v.back()), // 用末元素开始
dash_fold);

std::cout << "和:" << sum << '\n'
<< "积:" << product << '\n'
<< "以短横线分隔的字符串:" << s << '\n'
<< "以短横线分隔的字符串(右折叠):" << rs << '\n';
}

输出:

1
2
3
4
和:55
积:3628800
以短横线分隔的字符串:1-2-3-4-5-6-7-8-9-10
以短横线分隔的字符串(右折叠):10-9-8-7-6-5-4-3-2-1

std::distance

API 地址: https://zh.cppreference.com/w/cpp/iterator/distance .

在标头 <iterator> 定义

1
2
3
4
template< class InputIt >
typename std::iterator_traits<InputIt>::difference_type
distance( InputIt first, InputIt last );
(C++17 起为 constexpr)

返回从 first 到 last 的路程。

若 last 不可从 first 通过(可以重复)自增 first 抵达,则行为未定义。

(C++11 前)

若 InputIt 不是老式随机访问迭代器 (LegacyRandomAccessIterator) ,则若 last 不可从 first 通过(可以重复)自增 first 抵达,则行为未定义。 若 InputIt 是老式随机访问迭代器 (LegacyRandomAccessIterator) ,则若 last 不可从 first 抵达且 first 不可从 last 抵达,则行为未定义。

(C++11 起)

参数

  • first - 指向首元素的迭代器

  • last - 指向范围尾的迭代器

类型要求

  • InputIt 必须符合老式输入迭代器 (LegacyInputIterator) 的要求。若 InputIt 额外满足老式随机访问迭代器 (LegacyRandomAccessIterator) 的要求则操作更高效

返回值

从 first 走到 last 所需的自增数。若使用随机访问迭代器且 first 可从 last 抵达,则值可能为负。 (C++11 起)

复杂度

线性。

然而,若 InputIt 额外满足老式随机访问迭代器 (LegacyRandomAccessIterator) 的要求,则复杂度是常数。

可能的实现

参阅 libstdc++ 与 libc++ 中的实现。

版本一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 经由标签派发的实现,移除 constexpr 后可用于 C++98
namespace detail {

template<class It>
constexpr // C++17 起要求
typename std::iterator_traits<It>::difference_type
do_distance(It first, It last, std::input_iterator_tag)
{
typename std::iterator_traits<It>::difference_type result = 0;
while (first != last) {
++first;
++result;
}
return result;
}

template<class It>
constexpr // C++17 起要求
typename std::iterator_traits<It>::difference_type
do_distance(It first, It last, std::random_access_iterator_tag)
{
return last - first;
}

} // namespace detail

template<class It>
constexpr // C++17 起
typename std::iterator_traits<It>::difference_type
distance(It first, It last)
{
return detail::do_distance(first, last,
typename std::iterator_traits<It>::iterator_category());
}

版本二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 经由 constexpr if 的实现,可用于 C++17
template<class It>
constexpr typename std::iterator_traits<It>::difference_type
distance(It first, It last)
{
using category = typename std::iterator_traits<It>::iterator_category;
static_assert(std::is_base_of_v<std::input_iterator_tag, category>);

if constexpr (std::is_base_of_v<std::random_access_iterator_tag, category>)
return last - first;
else {
typename std::iterator_traits<It>::difference_type result = 0;
while (first != last) {
++first;
++result;
}
return result;
}
}

示例

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
std::vector<int> v{ 3, 1, 4 };
std::cout << "distance(first, last) = "
<< std::distance(v.begin(), v.end()) << '\n'
<< "distance(last, first) = "
<< std::distance(v.end(), v.begin()) << '\n';
}

输出:

1
2
distance(first, last) = 3
distance(last, first) = -3

std::exception::what

API 地址: https://zh.cppreference.com/w/cpp/error/exception/what .

1
2
3
4
virtual const char* what() const throw();
(C++11 前)
virtual const char* what() const noexcept;
(C++11 起)

返回解释性字符串。

参数

(无)

返回值

指向拥有解释信息的空终止字符串的指针。该指针保证在获取它的异常对象被销毁前,或在调用该异常对象的非静态成员函数前合法。

std::advance

API 地址: https://zh.cppreference.com/w/cpp/iterator/advance .

在标头 <iterator> 定义

1
2
3
4
5
6
template< class InputIt, class Distance >
void advance( InputIt& it, Distance n );
(C++17 前)
template< class InputIt, class Distance >
constexpr void advance( InputIt& it, Distance n );
(C++17 起)

增加给定的迭代器 it 以 n 个元素的步长。

如果 n 为负,那么迭代器会自减。此时 InputIt 必须满足老式双向迭代器 (LegacyBidirectionalIterator) 的要求,否则行为未定义。

参数

it - 要前进的迭代器

n - it 要前进的元素数

类型要求

  • InputIt 必须符合老式输入迭代器 (LegacyInputIterator) 的要求。

返回值

(无)

复杂度

线性。

然而,如果 InputIt 额外满足老式随机访问迭代器 (LegacyRandomAccessIterator) 的要求,那么复杂度是常数。

注解

如果指定的自增或自减序列要求一个不可自增迭代器(例如尾后迭代器)自增,或不可自减迭代器(例如首迭代器或持有奇异值的迭代器)自减,那么行为未定义。

可能的实现

参阅 libstdc++ 与 libc++ 中的实现。

非 constexpr 版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
namespace detail
{
template<class It>
void do_advance(It& it, typename std::iterator_traits<It>::difference_type n,
std::input_iterator_tag)
{
while (n > 0)
{
--n;
++it;
}
}

template<class It>
void do_advance(It& it, typename std::iterator_traits<It>::difference_type n,
std::bidirectional_iterator_tag)
{
while (n > 0)
{
--n;
++it;
}
while (n < 0)
{
++n;
--it;
}
}

template<class It>
void do_advance(It& it, typename std::iterator_traits<It>::difference_type n,
std::random_access_iterator_tag)
{
it += n;
}
} // namespace detail

template<class It, class Distance>
void advance(It& it, Distance n)
{
detail::do_advance(it, typename std::iterator_traits<It>::difference_type(n),
typename std::iterator_traits<It>::iterator_category());
}

constexpr 版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template<class It, class Distance>
constexpr void advance(It& it, Distance n)
{
using category = typename std::iterator_traits<It>::iterator_category;
static_assert(std::is_base_of_v<std::input_iterator_tag, category>);

auto dist = typename std::iterator_traits<It>::difference_type(n);
if constexpr (std::is_base_of_v<std::random_access_iterator_tag, category>)
it += dist;
else
{
while (dist > 0)
{
--dist;
++it;
}
if constexpr (std::is_base_of_v<std::bidirectional_iterator_tag, category>)
{
while (dist < 0)
{
++dist;
--it;
}
}
}
}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
std::vector<int> v{3, 1, 4};

auto vi = v.begin();
std::advance(vi, 2);
std::cout << *vi << ' ';

vi = v.end();
std::advance(vi, -2);
std::cout << *vi << '\n';
}

输出:

1
4 1

std::next

API 地址: https://zh.cppreference.com/w/cpp/iterator/next .

在标头 <iterator> 定义

1
2
3
4
5
6
7
8
9
10
11
template< class InputIt >
InputIt next(
InputIt it,
typename std::iterator_traits<InputIt>::difference_type n = 1 );
(C++11 起)
(C++17 前)
template< class InputIt >
constexpr InputIt next(
InputIt it,
typename std::iterator_traits<InputIt>::difference_type n = 1 );
(C++17 起)

返回迭代器 it 的第 n 个后继。

参数

it - 迭代器

n - 要前进的元素数

类型要求

  • InputIt 必须符合老式输入迭代器 (LegacyInputIterator) 的要求。

返回值

迭代器 it 的第 n 个后继。

复杂度

线性。

然而,若 InputIt 还满足老式随机访问迭代器 (LegacyRandomAccessIterator) 的要求,则复杂度为常数。

可能的实现

1
2
3
4
5
6
7
8
template<class InputIt>
constexpr // C++17 起
InputIt next(InputIt it,
typename std::iterator_traits<Input>::difference_type n = 1)
{
std::advance(it, n);
return it;
}

注解

尽管表达式 ++c.begin() 通常能编译,然而不保证会这么做: c.begin() 是右值表达式,而无老式输入迭代器 (LegacyInputIterator) 要求指定右值的自增保证进行。尤其是迭代器以指针实现或其 operator++ 为左值引用限定时, ++c.begin() 不能编译,而 std::next(c.begin()) 可以。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
std::vector<int> v{ 3, 1, 4 };

auto it = v.begin();

auto nx = std::next(it, 2);

std::cout << *it << ' ' << *nx << '\n';

// 注意 std::next 在循环中的表现
size_t loop = 0;

while ((std::next(it)) != v.end())
{
if(++loop > 5)
break;
}

std::cout << "loop = " << loop << '\n';
}

输出:

1
2
3 4
loop = 6

std::multiplies

API 地址: https://zh.cppreference.com/w/cpp/utility/functional/multiplies .

在标头 <functional> 定义

1
2
3
4
5
6
template< class T >
struct multiplies;
(C++14 前)
template< class T = void >
struct multiplies;
(C++14 起)

进行乘法的函数对象。等效地在二个 T 类型实例上调用 operator* 。

特化

标准库提供 std::multiplies 在不指定 T 时的特化,这使得参数类型和返回类型留待推导。

multiplies<void> (C++14)

实现 x * y 并推导参数和返回类型的函数对象(类模板特化)(C++14 起)

成员类型

类型 定义
result_type (C++17 中弃用)(C++20 中移除) T
first_argument_type (C++17 中弃用)(C++20 中移除) T
second_argument_type (C++17 中弃用)(C++20 中移除) T

这些成员类型由公开继承 std::binary_function<T, T, T> 获得。(C++11 前)

成员函数

operator() 返回二个参数的积(公开成员函数)

std::multiplies::operator()

1
2
3
4
T operator()( const T& lhs, const T& rhs ) const;
(C++14 前)
constexpr T operator()( const T& lhs, const T& rhs ) const;
(C++14 起)

返回 lhs 与 rhs 的积。

参数

lhs, rhs - 要相乘的值

返回值

lhs * rhs 的结果。

异常

可能抛出实现定义的异常。

可能的实现

1
2
3
4
constexpr T operator()(const T &lhs, const T &rhs) const 
{
return lhs * rhs;
}

std::find, std::find_if, std::find_if_not

API 地址: https://zh.cppreference.com/w/cpp/algorithm/find .

在标头 <algorithm> 定义
(1)
template< class InputIt, class T >
InputIt find( InputIt first, InputIt last, const T& value );
(C++20 前)
template< class InputIt, class T >
constexpr InputIt find( InputIt first, InputIt last, const T& value );
(C++20 起)
template< class ExecutionPolicy, class ForwardIt, class T >

ForwardIt find( ExecutionPolicy&& policy,

                ForwardIt first, ForwardIt last, const T& value );
(2) (C++17 起)
(3)
template< class InputIt, class UnaryPredicate >
InputIt find_if( InputIt first, InputIt last, UnaryPredicate p );
(C++20 前)
template< class InputIt, class UnaryPredicate >
constexpr InputIt find_if( InputIt first, InputIt last, UnaryPredicate p );
(C++20 起)
template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate >

ForwardIt find_if( ExecutionPolicy&& policy,

                   ForwardIt first, ForwardIt last, UnaryPredicate p );
(4) (C++17 起)
(5)
template< class InputIt, class UnaryPredicate >
InputIt find_if_not( InputIt first, InputIt last, UnaryPredicate q );
(C++11 起)
(C++20 前)
template< class InputIt, class UnaryPredicate >
constexpr InputIt find_if_not( InputIt first, InputIt last, UnaryPredicate q );
(C++20 起)
template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate >

ForwardIt find_if_not( ExecutionPolicy&& policy,

                       ForwardIt first, ForwardIt last, UnaryPredicate q );
(6) (C++17 起)

返回指向范围 [first, last) 中满足特定判别标准的首个元素的迭代器(没有这种元素时返回 last):

  • 1) find 搜索等于(用 operator== 比较)value 的元素。

  • 3) find_if 搜索谓词 p 对其返回 true 的元素。

  • 5) find_if_not 搜索谓词 q 对其返回 false 的元素。

  • 2,4,6) 同 (1,3,5),但按照 policy 执行。这些重载只有在 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> (C++20 前)std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> (C++20 起) 是 true 时才会参与重载决议。

参数

first, last - 要检验的元素范围

value - 要与元素比较的值

policy - 所用的执行策略。细节见执行策略。

p - 如果是要求的元素则返回 ​true 的一元谓词。对每个(可为 const 的) VT 类型参数 v ,其中 VT 是 InputIt 的值类型,表达式 p(v) 必须可转换为 bool ,无关乎值类别,而且必须不修改 v 。从而不允许 VT& 类型参数,亦不允许 VT ,除非对 VT 而言移动等价于复制 (C++11 起)。​

q - 如果是要求的元素则返回 ​false 的一元谓词。对每个(可为 const 的) VT 类型参数 v ,其中 VT 是 InputIt 的值类型,表达式 q(v) 必须可转换为 bool ,无关乎值类别,而且必须不修改 v 。从而不允许 VT& 类型参数,亦不允许 VT ,除非对 VT 而言移动等价于复制 (C++11 起)。​

类型要求

-InputIt 必须符合老式输入迭代器 (LegacyInputIterator) 的要求。

-ForwardIt 必须符合老式向前迭代器 (LegacyForwardIterator) 的要求。

-UnaryPredicate 必须符合谓词 (Predicate) 的要求。

返回值

范围 [first, last) 中首个满足以下条件的迭代器 it,或者在没有满足条件的迭代器时返回 last:

  • 1,2) *it == value 是 true

  • 3,4) p(*it) != false 是 true

  • 5,6) q(*it) == false 是 true

复杂度

给定 N 为 std::distance(first, last):

  • 1,2) 最多应用 N 次 operator== 与 value 进行比较

  • 3,4) 最多应用 N 次谓词 p

  • 5,6) 最多应用 N 次谓词 q

异常

拥有名为 ExecutionPolicy 的模板形参的重载按下列方式报告错误:

  • 如果作为算法一部分调用的函数的执行抛出异常,且 ExecutionPolicy 是标准策略之一,那么调用 std::terminate。对于任何其他 ExecutionPolicy,行为由实现定义。

  • 如果算法无法分配内存,那么抛出 std::bad_alloc

可能的实现

find

1
2
3
4
5
6
7
8
9
template<class InputIt, class T>
InputIt find(InputIt first, InputIt last, const T& value)
{
for (; first != last; ++first)
if (*first == value)
return first

return last;
}

find_if

1
2
3
4
5
6
7
8
9
template<class InputIt, class UnaryPredicate>
InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
{
for (; first != last; ++first)
if (p(*first))
return first;

return last;
}

find_if_not

1
2
3
4
5
6
7
8
9
template<class InputIt, class UnaryPredicate>
InputIt find_if_not(InputIt first, InputIt last, UnaryPredicate q)
{
for (; first != last; ++first)
if (!q(*first))
return first;

return last;
}

注解

如果没有 C++11 ,那么 std::find_if_not 的等价版本是以取反的谓词使用 std::find_if

1
2
3
4
5
template<class InputIt, class UnaryPredicate>
InputIt find_if_not(InputIt first, InputIt last, UnaryPredicate q)
{
return std::find_if(first, last, std::not1(q));
}

示例

以下示例在给定的 std::vector 中查找整数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>

int main()
{
std::vector<int> v{1, 2, 3, 4};
int n1 = 3;
int n2 = 5;
auto is_even = [](int i){ return i%2 == 0; };

auto result1 = std::find(begin(v), end(v), n1);
auto result2 = std::find(begin(v), end(v), n2);
auto result3 = std::find_if(begin(v), end(v), is_even);

(result1 != std::end(v))
? std::cout << "v 包含 " << n1 << '\n'
: std::cout << "v 不包含 " << n1 << '\n';

(result2 != std::end(v))
? std::cout << "v 包含 " << n2 << '\n'
: std::cout << "v 不包含 " << n2 << '\n';

(result3 != std::end(v))
? std::cout << "v 包含偶数:" << *result3 << '\n'
: std::cout << "v 不包含偶数\n";
}

输出:

1
2
3
v 包含 3
v 不包含 5
v 包含偶数:2

std::list<T,Allocator>::splice

API 地址: https://zh.cppreference.com/w/cpp/container/list/splice .

std::list<T,Allocator>::splice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void splice( const_iterator pos, list& other );
(1)
void splice( const_iterator pos, list&& other );
(1) (C++11 起)
void splice( const_iterator pos, list& other, const_iterator it );
(2)
void splice( const_iterator pos, list&& other, const_iterator it );
(2) (C++11 起)
void splice( const_iterator pos, list& other,
const_iterator first, const_iterator last);
(3)
void splice( const_iterator pos, list&& other,
const_iterator first, const_iterator last );
(3) (C++11 起)

从一个 list 转移元素给另一个。

不复制或移动元素,仅重指向链表结点的内部指针。get_allocator() != other.get_allocator() 时行为未定义。没有迭代器或引用会失效,指向被移动元素的迭代器保持有效,但现在指代到 *this 中,而非到 other 中。

1) 从 other 转移所有元素到 *this 中。元素被插入到 pos 指向的元素之前。操作后容器 other 变为空。other 与 *this 指代同一对象时行为未定义。

2) 从 other 转移 it 指向的元素到 *this。元素被插入到 pos 指向的元素之前。

3) 从 other 转移范围 [first, last) 中的元素到 *this。元素被插入到 pos 指向的元素之前。pos 是范围 [first,last) 中的迭代器时行为未定义。

参数

pos - 将插入内容到它之前的元素

other - 要从它转移内容的另一容器

it - 要从 other 转移到 *this 的元素

first, last - 要从 other 转移到 *this 的元素范围

返回值

(无)

异常

不抛出。

复杂度

1-2) 常数。

3) 如果 other 与 *this 指代同一对象时是常数,否则与 std::distance(first, last) 成线性。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <list>

std::ostream& operator<<(std::ostream& ostr, const std::list<int>& list)
{
for (auto &i : list)
ostr << " " << i;

return ostr;
}

int main ()
{
std::list<int> list1 = {1, 2, 3, 4, 5};
std::list<int> list2 = {10, 20, 30, 40, 50};

auto it = list1.begin();
std::advance(it, 2);

list1.splice(it, list2);

std::cout << "list1:" << list1 << "\n";
std::cout << "list2:" << list2 << "\n";

list2.splice(list2.begin(), list1, it, list1.end());

std::cout << "list1:" << list1 << "\n";
std::cout << "list2:" << list2 << "\n";
}

输出:

1
2
3
4
list1: 1 2 10 20 30 40 50 3 4 5
list2:
list1: 1 2 10 20 30 40 50
list2: 3 4 5

std::partition

API 地址: https://zh.cppreference.com/w/cpp/algorithm/partition .

在标头 <algorithm> 定义

1
2
3
4
5
6
7
8
9
10
11
template< class ForwardIt, class UnaryPredicate >
ForwardIt partition( ForwardIt first, ForwardIt last, UnaryPredicate p );
(C++20 前)
template< class ForwardIt, class UnaryPredicate >
constexpr ForwardIt partition( ForwardIt first, ForwardIt last,
UnaryPredicate p );
(1) (C++20 起)
template< class ExecutionPolicy, class ForwardIt, class UnaryPredicate >
ForwardIt partition( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last, UnaryPredicate p );
(2) (C++17 起)

1) 重排序范围 [first, last) 中的元素,使得谓词 p 对其返回 true 的元素位于谓词 p 对其返回 false 的元素之前。不保持相对顺序。

2) 同 (1),但按照 policy 执行。此重载只有在 std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> (C++20 前)std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> (C++20 起) 是 true 时才会参与重载决议。

参数

first, last - 要重排序的元素范围

policy - 所用的执行策略。细节见执行策略。

p - 如果元素在顺序中应该在其他元素之前则返回 ​true 的一元谓词。

对每个(可为 const 的) VT 类型参数 v ,其中 VT 是 ForwardIt 的值类型,表达式 p(v) 必须可转换为 bool ,无关乎值类别,而且必须不修改 v 。从而不允许 VT& 类型参数,亦不允许 VT ,除非对 VT 而言移动等价于复制 (C++11 起)。​

类型要求

  • ForwardIt 必须符合值可交换 (ValueSwappable) 和 老式向前迭代器 (LegacyForwardIterator) 的要求。然而,ForwardIt 在满足老式双向迭代器 (LegacyBidirectionalIterator) 的要求时操作会更高效。

  • UnaryPredicate 必须符合谓词 (Predicate) 的要求。

返回值

指向第二组元素中首元素的迭代器。

复杂度

给定 N = std::distance(first, last)

1) 准确应用 N 次 p。在 ForwardIt 满足老式双向迭代器 (LegacyBidirectionalIterator) 的要求时最多交换 N/2 次,否则最多交换 N 次。

2) O(N·log N) 次交换,及应用 O(N) 次 p。

异常

拥有名为 ExecutionPolicy 的模板形参的重载按下列方式报告错误:

  • 如果作为算法一部分调用的函数的执行抛出异常,且 ExecutionPolicy 是标准策略之一,那么调用 std::terminate。对于任何其他 ExecutionPolicy,行为由实现定义。

  • 如果算法无法分配内存,那么抛出 std::bad_alloc。

可能的实现

实现重载 (1) 并兼容 C++11。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template<class ForwardIt, class UnaryPredicate>
ForwardIt partition(ForwardIt first, ForwardIt last, UnaryPredicate p)
{
first = std::find_if_not(first, last, p);
if (first == last)
return first;

for (auto i = std::next(first); i != last; ++i)
{
if (p(*i))
{
std::iter_swap(i, first);
++first;
}
}

return first;
}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
#include <forward_list>

template <class ForwardIt>
void quicksort(ForwardIt first, ForwardIt last)
{
if (first == last)
return;

auto pivot = *std::next(first, std::distance(first, last) / 2);
ForwardIt middle1 = std::partition(first, last, [pivot](const auto& em)
{
return em < pivot;
});
ForwardIt middle2 = std::partition(middle1, last, [pivot](const auto& em)
{
return !(pivot < em);
});

quicksort(first, middle1);
quicksort(middle2, last);
}

int main()
{
std::vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
std::cout << "原来的 vector:\n ";
for (int elem : v)
std::cout << elem << ' ';

auto it = std::partition(v.begin(), v.end(), [](int i){return i % 2 == 0;});

std::cout << "\n划分后的 vector:\n ";
std::copy(std::begin(v), it, std::ostream_iterator<int>(std::cout, " "));
std::cout << " * ";
std::copy(it, std::end(v), std::ostream_iterator<int>(std::cout, " "));

std::forward_list<int> fl = {1, 30, -4, 3, 5, -4, 1, 6, -8, 2, -5, 64, 1, 92};
std::cout << "\n未排序的列表:\n ";
for (int n : fl)
std::cout << n << ' ';
std::cout << '\n';

quicksort(std::begin(fl), std::end(fl));
std::cout << "快速排序后:\n ";
for (int fi : fl)
std::cout << fi << ' ';
std::cout << '\n';
}

输出:

1
2
3
4
5
6
7
8
原来的 vector:
0 1 2 3 4 5 6 7 8 9
划分后的 vector:
0 8 2 6 4 * 5 3 7 1 9
未排序的列表:
1 30 -4 3 5 -4 1 6 -8 2 -5 64 1 92
快速排序后:
-8 -5 -4 -4 1 1 1 2 3 5 6 30 64 92

结语

第二十九篇博文写完,开心!!!!

今天,也是充满希望的一天。