前言
介绍一些 C/C++ 标准库和可移植操作系统接口(Portable Operating System Interface,缩写为 POSIX)。
C/C++ Reference: https://cplusplus.com/reference/ 。
操作系统:Ubuntu 20.04.4 LTS
下面是各个章节的快速索引:
参考文档
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 erroroccurs, the global variable errno is set to EDOM.
Example
/* 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;
}
输出
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: e^x$.
Parameters
x
- Value of the exponent.
Return Value
Exponential value of x.
Example
/* 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;
}
输出
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
- Value whose absolute value is returned.
Return Value
The absolute value of x.
Example
/* 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;
}
输出
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
C stringcontainingthe name of the file to be opened.Its value can
include a path.
mode
C string containing a file access mode. It can be:
"r"->read:Open fileforinput operations. The file must exist."w"->write:Create an empty filefor output operations. If a file withthe same name already exists, its contents arediscardedand the file is treated as a new empty file."a"->append: Open file foroutput 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 fileand open it for update (both for input and output). If a file with the same name already existsits contents are discardedand the file is treated as a new empty file."a+"->append/update: Open a file for update (both for input and output) withall output operations writing data at the end of the file. Repositioning operations (fseek, fsetpos, rewind) affectsthe next input operations, butoutput 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.
例子
/* 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.
例子
/* 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
Pointerto aFILEobject that identifiesan 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
/* 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:
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
Pointertoa FILE objectthat identifiesthe 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 willreadandignoreany whitespace charactersencountered beforethe next non-whitespace character(whitespace charactersincludespaces,newlineandtab 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 characterthat is not eithera whitespace character(blank, newline or tab) or part ofa format specifier(which begin with a % character) causes the function toread the next character from the stream,compare it to this non-whitespace character and if it matches, it isdiscardedand 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 byan initial percentage sign (%) indicates a format specifier, which is used to specifythe typeandformatof the data to be retrieved from the stream andstoredinto 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
/* 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.
输出
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
/* 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:
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
- Pointer to a
FILEobject thatidentifies 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:
If the position indicator was at
the end-of-file, the function returnsEOFandsets the eof indicator (feof) of stream.If
some other reading error happens, the function also returnsEOF, butsets its error indicator (ferror)instead.
Example
/* 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
The
int promotion of the characterto be written.The value is internally converted to
an unsigned charwhen written.
stream
- Pointer to a
FILEobject that identifiesan output stream.
返回值
On success, the character written is returned.
If a writing error occurs, EOF is returned and the error indicator (ferror) is set.
例子
/* 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
C stringwith the content to be written tostream.
stream
Pointer to a FILE objectthat 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
/* 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
C stringto 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
/* puts example : hello world! */
#include <stdio.h>
int main ()
{
char string [] = "Hello world!";
puts (string);
}
输出
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
Pointer to a block of memorywith a size of at least (size*count) bytes, converted to avoid*.
size
Size,in bytes, of each element to be read.size_tis an unsigned integral type.
count
Number of elements, each one witha size of size bytes.size_tis an unsigned integral type.
stream
Pointerto aFILE objectthat 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
/* 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.
输出
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
Pointer to the array of elements to be written, converted to a constvoid*.
size
Size in bytes of each elementto be written.size_tis an unsigned integral type.
count
Number of elements, each one with asizeof size bytes.size_tis an unsigned integral type.
stream
Pointertoa FILE objectthat 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
/* 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
Pointerto aFILEobject that identifies the stream.
offset
Binary files: Number of bytes to offset fromorigin.Text files: Eitherzero, or avaluereturned byftell.
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
If successful, the function returns
zero.Otherwise, it returns
non-zerovalue.If a read or write error occurs, the
error indicator(ferror) is set.
Example
/* 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:
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
Pointertoa FILE objectthat identifies the stream.
Return Value
none
Example
/* 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:
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
Pointerto aFILEobject 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
/* 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
C-stringbeginning with the representation ofa 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
/* 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;
}
输出
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
C-stringbeginning 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
/* 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;
}
输出
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:
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
/* 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.
可能的输出
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
- Number of elements to allocate.
size
- 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
/* 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
Pointerto a memory block previously allocated withmalloc,callocorrealloc.
Return Value
none
Example
/* 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
Pointer to the destination arraywhere the content is to be copied, type-casted to a pointer of typevoid*.
source
Pointer to the source of datato be copied, type-casted to a pointer of type constvoid*.
num
Numberof bytes to copy.size_tis an unsigned integral type.
Return Value
destination is returned.
Example
/* 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;
}
输出
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
Pointerto block of memory.
ptr2
Pointerto block of memory.
num
Number of bytesto 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
/* 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;
}
输出
'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
C stringto be compared.
str2
C stringto 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
#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;
}
输出
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
C stringto truncate.Notice that this string is modified by being broken into smaller strings (tokens).
Alternativelly,
a null pointermay be specified, in which case the function continues scanning where a previous successful call to the function ended.
delimiters
C stringcontainingthe delimiter characters.These can be different from one call to another.
Return Value
If
a tokenis found,a pointer to the beginning of the token.Otherwise,
a null pointer.A null pointeris always returned when the end of the string (i.e.,a null character) is reached in the string being scanned.
Example
/* 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;
}
输出
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
Pointerto the block of memory to fill.
value
Value to be set. The value is passed as anint, but the functionfillsthe block of memory using theunsigned charconversion of thisvalue.
num
Number of bytesto be set to thevalue.size_tis anunsigned integral type.
Return Value
ptr is returned.
Example
/* 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;
}
输出
------ 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/ 。
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
// 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;
}
输出
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/ 。
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
// 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;
}
输出
mymap.size() is 3
Complexity
Constant.
Iterator validity
No changes.
Data races
The container is
accessed.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[]/ 。
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:
(*((this->insert(make_pair(k,mapped_type()))).first)).
Parameters
k
Key value of the elementwhose mapped value is accessed.Member type
key_typeis the type of the keys for the elements stored in the container, defined in map as an alias of its first template parameter (Key).If an
rvalue (second version), the key ismoved instead of copiedwhen 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
// 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.
输出
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
The container is
accessed, andpotentially modified.The function accesses an element and returns a reference that can be used to modify its mapped value. Concurrently accessing other elements is safe.
If the function inserts
a new element, concurrently iterating ranges in the container is not safe.
Exception safety
Strong guarantee:
if an exception is thrown, there are no changes in the container.If a new element is inserted and
allocator_traits::constructcannot construct an element withkand a default-constructedmapped_type(or ifmapped_typeis notdefault constructible), it causesundefined behavior.
std::map::clear
std::map::clear: https://cplusplus.com/reference/map/map/clear/ 。
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
// 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;
}
输出
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
The container is modified.
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/ 。
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
Keyto search for.Member type
key_typeis the type of the element keys in the container, defined inmapas an alias ofits 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
// 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;
}
输出
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
The container is accessed.
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=/ 。
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
- A
vectorobject of the same type (i.e., with the same template parameters,TandAlloc).
il
An
initializer_listobject. The compiler will automatically construct such objects frominitializer listdeclarators.Member type
value_typeis the type of the elements in the container, defined invectoras an alias of its first template parameter (T).
Return Value
*this
Example
// 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;
}
输出
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
All copied elementsare accessed.The
move assignment (2)modifies x.The container and all its elements are modified.
Exception safety
Basic guarantee: if an exception is thrown, the container is in a valid state.If
allocator_traits::constructis not supported with the appropriate arguments for the element constructions, or ifvalue_typeisnot copy assignable(ormove assignablefor (2)), it causesundefined behavior.
std::vector::size
std::vector::size: https://cplusplus.com/reference/vector/vector/size/ 。
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
The number of elementsin the container.Member type
size_typeisan unsigned integral type.
Example
// 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;
}
输出
0. size: 0
1. size: 10
2. size: 20
3. size: 19
Complexity
Constant.
Iterator validity
No changes.
Data races
The container is
accessed.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/ 。
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
New container size, expressed in number of elements.
Member type
size_typeis an unsigned integral type.
val
Objectwhose content is copied to the added elements in case thatnis greater thanthe current container size.If
not specified,the default constructoris used instead.Member type
value_typeis the type of the elements in the container, defined invectoras 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
// 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;
}
输出
myvector contains: 1 2 3 4 5 100 100 100 0 0 0 0
Complexity
Linearon the number of elements inserted/erased (constructions/destructions).If a
reallocationhappens, the reallocation is itself up to linear inthe entire vector size.
Iterator validity
In case the container
shrinks,all iterators,pointersandreferencesto elements that have not been removed remain valid after the resize andrefer to the same elementsthey were referring to before the call.If the container
expands,the end iteratorisinvalidatedand, if it has toreallocate storage, alliterators,pointersandreferencesrelated to this container are alsoinvalidated.
Data races
The container is
modified.If a reallocation happens, all contained elements are modified.
Otherwise, none of the elements before
nis accessed, and concurrently accessing or modifying them issafe.
Exception safety
If
nis less than or equal to the size of the container, the functionneverthrows exceptions (no-throw guarantee).If
nis greater and a reallocation happens, there areno changesin the containerin case of exception(strong guarantee) if the type of the elements is either copyable or no-throw moveable.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[]/ 。
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
Position of an elementin the container.Notice that
the first elementhas a position of0(not1).Member type
size_typeis anunsigned integral type.
Return Value
The element at the specified positionin thevector.If the
vectorobject isconst-qualified, the function returns aconst_reference. Otherwise, it returns areference.Member types
referenceandconst_referenceare the reference types to the elements of the container (seevector member types).
Example
// 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;
}
输出
myvector contains: 9 8 7 6 5 4 3 2 1 0
Complexity
Constant.
Iterator validity
No changes.
Data races
The
containerisaccessed(neither theconstnor thenon-constversions modify the container).The reference returned can be used to
accessormodify elements. Concurrently accessing or modifying different elements issafe.
Exception safety
If the container size is greater than
n, the functionnever throws exceptions(no-throw guarantee).Otherwise, the behavior is undefined.
std::vector::push_back
std::vector::push_back: https://cplusplus.com/reference/vector/vector/push_back/ 。
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
Valueto becopied(ormoved) to the new element.Member type
value_typeis the type of the elements in the container, defined in vector as an alias ofits 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
// 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
If a
reallocationhappens, all iterators, pointers and references related to the container areinvalidated.Otherwise, onlythe end iteratorisinvalidated, 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
The container is
modified.If a
reallocationhappens, all contained elements are modified.Otherwise, no existing element is accessed, and concurrently accessing or modifying them is safe.
Exception safety
If
no reallocationshappen, there areno changesin the container in case of exception (strong guarantee).If a
reallocationhappens, the strong guarantee is also given if the type of the elements is eithercopyableorno-throw moveable.Otherwise, the
containeris guaranteed toend in a valid state(basic guarantee).If
allocator_traits::constructis not supported withvalas argument, it causesundefined behavior.
std::vector::clear
std::vector::clear: https://cplusplus.com/reference/vector/vector/clear/ 。
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:
vector<T>().swap(x); // clear x reallocating
Parameters
none
Return Value
none
Example
// 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;
}
输出
myvector contains: 100 200 300
myvector contains: 1101 2202
Complexity
Linearin size (destructions).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
The container is modified.
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/ 。
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:
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
// 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;
}
输出
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/ 。
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
Random-access iteratorsto the initial and final positions of the sequence to be sorted. The range used is[first,last), which contains all the elements betweenfirstandlast, including the element pointed byfirstbut not the element pointed bylast.RandomAccessIteratorshall point to a type for whichswapis properly defined and which is bothmove-constructibleandmove-assignable.
comp
Binary function that accepts
two elementsin the range as arguments, and returns a value convertible tobool.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.The function
shall not modify any of its arguments.This can either be
a function pointer or a function object.
Return Value
none.
Example
// 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;
}
可能的输出
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/ 。
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:
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
Valuesto compare.
comp
Binary functionthat acceptstwo valuesof typeTas arguments, and returnsa value convertible to bool. The value returnedindicateswhether the element passed asfirst argumentis consideredless thanthe second.The function
shall not modifyany of its arguments.This can either be
a function pointerora function object.
il
An
initializer_listobject.These objects are automatically constructed from
initializer listdeclarators.
T shall support being compared with operator<.
Return Value
The lesser of the values passed as arguments.
Example
// 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;
}
输出
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/ 。
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
- An object of a class type for which member
beginis defined.
arr
- 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
// 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;
}
输出
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
// 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;
}
输出
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
- Numerical value.
Return Value
A string object containing the representation of val as a sequence of characters.
Example
// 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;
}
可能的输出
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/ 。
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, 称该对象为常对象.
- 常对象只能调用常函数.
#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 的指向, 也不可以修改指向的变量的值.
#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.
#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:
#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';
}
}
可能的输出:
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 .
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
#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:
inf is greater than 1.79769e+308
std::is_same
API 地址: https://zh.cppreference.com/w/cpp/types/is_same .
在标头
<type_traits>定义(C++11 起)
template< class T, class U >
struct is_same;
若
T与U指名同一类型(考虑const/volatile限定),则提供等于true的成员常量value。否则value为false。满足交换律,即对于任何二个类型
T与U,is_same<T, U>::value == true当且仅当is_same<U, T>::value == true。添加
is_same或is_same_v(C++17 起) 的特化的程序行为未定义。
辅助变量模板
(C++17 起)
template< class T, class U >
inline constexpr bool is_same_v = is_same<T, U>::value;
继承自
std::integral_constant
成员常量
value[静态]: 若T与U是同一类型则为true,否则为false(公开静态成员常量)
成员函数
operator bool: 转换对象为bool,返回value(公开成员函数)operator(): (C++14), 返回value(公开成员函数)
成员类型
| 类型 | 定义 |
|---|---|
| value_type | bool |
| type | std::integral_constant<bool, value> |
可能的实现
template<class T, class U>
struct is_same : std::false_type {};
template<class T>
struct is_same<T, T> : std::true_type {};
示例
#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
}
输出:
true
false
-----
false
-----
true
false
true
-----
true
false
false
std::tie
API 地址: https://zh.cppreference.com/w/cpp/utility/tuple/tie .
在标头
<tuple>定义
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 对象。
可能的实现
template <typename... Args>
constexpr // C++14 起
std::tuple<Args&...> tie(Args&... args) noexcept {
return {args...};
}
注解
std::tie 可用于解包 std::pair ,因为 std::tuple 拥有从 pair 的转换赋值:
bool result;
std::tie(std::ignore, result) = set.insert(value);
示例
std::tie 能用于引入字典序比较到结构体,或解包 tuple :
#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";
}
输出:
Value was inserted successfully
std::ignore
API 地址: https://zh.cppreference.com/w/cpp/utility/tuple/ignore .
在标头
<tuple>定义
const /*unspecified*/ ignore;
(C++11 起)
(C++17 前)
inline constexpr /*unspecified*/ ignore;
(C++17 起)
任何值均可赋给而无效果的未指定类型的对象。目的是令 std::tie 在解包 std::tuple 时作为不使用的参数的占位符使用。
可能的实现
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 ,但只保存布尔值。
#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";
}
}
输出:
Value was inserted successfully
std::remove_reference
API 地址: https://zh.cppreference.com/w/cpp/types/remove_reference .
在标头
<type_traits>定义
template< class T >
struct remove_reference;
(C++11 起)
若类型 T 为引用类型,则提供成员 typedef type ,其为 T 所引用的类型。否则 type 为 T 。
添加 remove_reference 的特化的程序行为未定义。
成员类型
| 名称 | 定义 |
|---|---|
| type | T 所引用的类型,或若 T 不是引用则为 T |
辅助类型
template< class T >
using remove_reference_t = typename remove_reference<T>::type;
(C++14 起)
可能的实现
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;};
示例
#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>();
}
输出:
true
false
false
true
true
true
std::boolalpha, std::noboolalpha
API 地址: https://zh.cppreference.com/w/cpp/io/manip/boolalpha
在标头
<ios>定义
std::ios_base& boolalpha( std::ios_base& str );
(1)
std::ios_base& noboolalpha( std::ios_base& str );
(2)
启用流
str中的boolalpha标志,如同通过调用str.setf(std::ios_base::boolalpha)。禁用流
str中的boolalpha标志,如同通过调用str.unsetf(std::ios_base::boolalpha)。
std::boolalpha 是 I/O 操纵符,故可用如 out << std::boolalpha 的表达式对任何 std::basic_ostream 类型的 out ,或用如 in >> std::boolalpha 的表达式对任何 std::basic_istream 类型的 in 调用。
参数
str - 到 I/O 流的引用
返回值
str (到操纵后的流的引用)
示例
#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';
}
输出:
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>定义
template< class... Types >
std::tuple<VTypes...> make_tuple( Types&&... args );
(C++11 起)
(C++14 起为 constexpr)
创建 tuple 对象,从参数类型推导目标类型。
对于每个 Types... 中的 Ti , Vtypes... 中的对应类型 Vi 为 std::decay<Ti>::type ,除非应用 std::decay 对某些类型 X 导致 std::reference_wrapper<X> ,该情况下推导的类型为 X& 。
参数
args - 构造 tuple 所用的零或更多参数
返回值
含给定值的 std::tuple 对象,如同用 std::tuple<VTypes...>(std::forward<Types>(t)...). 创建
可能的实现
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)...);
}
示例
#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";
}
输出:
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>定义
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> |
示例
#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));
}
可能的输出:
3 12 16
std::accumulate
API 地址: https://zh.cppreference.com/w/cpp/algorithm/accumulate .
在标头
<numeric>定义
(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)中元素的和。
- 以初始值
init初始化(具有 T 类型的)累加器acc,然后按顺序对范围[first, last)的每个迭代器i通过acc = acc + *i(C++11 前)acc = std::move(acc) + *i(C++11 起) 进行累加。- 以初始值
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) 在 v 是 std::vector<double> 时会给出错误的结果。
可能的实现
版本一
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;
}
版本二
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;
}
示例
#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';
}
输出:
和: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>定义
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++ 中的实现。
版本一
// 经由标签派发的实现,移除 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());
}
版本二
// 经由 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;
}
}
示例
#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';
}
输出:
distance(first, last) = 3
distance(last, first) = -3
std::exception::what
API 地址: https://zh.cppreference.com/w/cpp/error/exception/what .
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>定义
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 版本
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 版本
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;
}
}
}
}
示例
#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';
}
输出:
4 1
std::next
API 地址: https://zh.cppreference.com/w/cpp/iterator/next .
在标头
<iterator>定义
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) 的要求,则复杂度为常数。
可能的实现
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()) 可以。
示例
#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';
}
输出:
3 4
loop = 6
std::multiplies
API 地址: https://zh.cppreference.com/w/cpp/utility/functional/multiplies .
在标头
<functional>定义
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()
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 的结果。
异常
可能抛出实现定义的异常。
可能的实现
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, |
(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, |
(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, |
(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
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
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
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。
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 中查找整数。
#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";
}
输出:
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
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) 成线性。
示例
#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";
}
输出:
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>定义
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。
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;
}
示例
#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';
}
输出:
原来的 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
结语
第二十九篇博文写完,开心!!!!
今天,也是充满希望的一天。