前言
介绍一些 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 error
occurs, 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 string
containingthe 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 file
forinput operations
. The file must exist."w"
->write
:Create an empty file
for output operations. If a file withthe same name already exists
, its contents arediscarded
and 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 file
and open it for update (both for input and output
). If a file with the same name already existsits contents are discarded
and the file is treated as a new empty file."a+"
->append/update
: Open a file for update (both for input and output
) 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
Pointer
to aFILE
object 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
Pointer
toa FILE object
that 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 willread
andignore
any whitespace characters
encountered beforethe next non-whitespace character
(whitespace characters
includespaces
,newline
andtab characters
).A single whitespace in the format string validates any quantity of whitespace characters extracted from the stream (including none).
Non-whitespace character, except format specifier (%)
:Any character
that is not 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 isdiscarded
and the function continues with the next character of format.If the character does not match, the function fails, returning and leaving subsequent characters of the stream unread.
Format specifiers
: A sequence formed byan initial percentage sign (%) indicates a format specifier
, which is used to specifythe type
andformat
of the data to be retrieved from the stream andstored
into the locations pointed by the additional arguments.
A format specifier for fscanf
follows this prototype
:
%[*][width][length]specifier
Where the specifier character
at the end is the most significant component
, since it defines which characters are extracted, their interpretation
and the type of its corresponding argument
:
specifier | Description | Characters extracted |
---|---|---|
i , u |
Integer |
Any number of digits , optionally preceded by a sign (+ or - ). Decimal digits assumed by default (0-9), but a 0 prefix introduces octal digits (0-7), and 0x hexadecimal digits (0-f). |
d |
Decimal integer |
Any number of decimal digits (0-9), optionally preceded by a sign (+ or -). |
o |
Octal integer |
Any number of octal digits (0-7), optionally preceded by a sign (+ or -). |
x |
Hexadecimal integer |
Any number of hexadecimal digits (0-9, a-f, A-F), optionally preceded by 0x or 0X, and all optionally preceded by a sign (+ or -). |
f , e , g , a |
Floating point number |
A series of decimal digits , optionally containing a decimal point , optionally preceeded by a sign (+ or - ) and optionally followed by the e or E character and a decimal integer . Implementations complying with C99 also support hexadecimal floating-point format when preceded by 0x or 0X . |
c |
Character |
The next character . If a width other than 1 is specified, the function reads exactly width characters and stores them in the successive locations of the array passed as argument. No null character is appended at the end. |
s |
String of characters |
Any number of non-whitespace characters , stopping at the first whitespace character found. A terminating null character is automatically added at the end of the stored sequence . |
p |
Pointer address |
A sequence of characters representing a pointer . |
[characters] |
Scanset | Any number of the characters specified between the brackets . |
[^characters] |
Negated scanset |
Any number of characters none of them specified as characters between the brackets. |
n |
Count | No input is consumed . The number of characters read so far from stream is stored in the pointed location. |
% |
% |
A % followed by another % matches a single % . |
Except for n
, at least one character
shall be consumed
by any specifier. Otherwise the match fails, and the scan ends there.
The format specifier can also contain sub-specifiers: asterisk (*)
, width
and length
(in that order), which are optional and follow these specifications:
sub-specifier | description |
---|---|
* |
An optional starting asterisk indicates that the data is to be read from the stream but ignored (i.e. it is not stored in the location pointed by an argument). |
width |
Specifiesthe maximum number of characters to be read in the current reading operation (optional ). |
length |
One of hh , h , l , ll , j , z , t , L (optional). This alters the expected type of the storage pointed by the corresponding argument. |
length\ specifiers |
d i | u o x | f e g a | c s [] [^] | p | n |
---|---|---|---|---|---|---|
(none) |
int* |
unsigned int* |
float* |
char* |
void** |
int* |
hh |
signed char* |
unsigned char* |
signed char* |
|||
h |
short int* |
unsigned short int* |
short int* |
|||
l |
long int* |
unsigned long int* |
double* |
wchar_t* |
long int* |
|
ll |
long long int* |
unsigned long long int* |
long long int* |
|||
j |
intmax_t* |
uintmax_t* |
intmax_t* |
|||
z |
size_t* |
size_t* |
size_t* |
|||
t |
ptrdiff_t* |
ptrdiff_t* |
ptrdiff_t* |
|||
L |
long double* |
… (additional arguments)
Depending on the format string, the function may expect a sequence of additional arguments, each containing a pointer to allocated storage
where the interpretation of the extracted characters is stored with the appropriate type
.
There should be at least as many of these arguments as
the number of values stored by the format specifiers. Additional arguments are ignored by the function.
These arguments are expected to be pointers
: to store the result of a fscanf operation on a regular variable
, its name should be preceded by the reference operator (&)
.
Return Value
On success
, the function returns the number of items of the argument list
successfully filled. This count can match the expected number of items or be less (even zero) due to a matching failure, a reading error, or the reach of the end-of-file.
If a reading error happens or the end-of-file is reached while reading, the proper indicator is set (feof
or ferror
). And, if either happens before any data could be successfully read, EOF is returned
.
Example
/* 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
FILE
object 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 returnsEOF
andsets 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 character
to be written.The value is internally converted to
an unsigned char
when written.
stream
- Pointer to a
FILE
object 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 string
with the content to be written tostream
.
stream
Pointer to a FILE object
that identifies an output stream.
Return Value
On success
, a non-negative
value is returned.
On error
, the function returns EOF
and sets the error indicator (ferror
).
Example
/* 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 string
to be printed.
Return Value
On success
, a non-negative value
is returned.
On error
, the function returns EOF
and sets the error indicator (ferror)
.
Example
/* 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 memory
with a size of at least (size*count
) bytes, converted to avoid*
.
size
Size
,in bytes
, of each element to be read.size_t
is an unsigned integral type.
count
Number of elements
, each one witha size of size bytes
.size_t
is an unsigned integral type.
stream
Pointer
to aFILE object
that specifies an input stream.
Return Value
The total number of elements
successfully read is returned.
If this number differs
from the count
parameter, either a reading error
occurred or the end-of-file
was reached while reading. In both cases, the proper indicator is set, which can be checked with ferror
and feof
, respectively.
If either size
or count
is zero, the function returns zero
and both the stream state and the content pointed by ptr
remain unchanged
.
size_t
is an unsigned integral type.
Example
/* 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 element
to be written.size_t
is an unsigned integral type.
count
Number of elements
, each one with asize
of size bytes.size_t
is an unsigned integral type.
stream
Pointer
toa FILE object
that specifies an output stream.
Return Value
The total number of elements
successfully written is returned.
If this number
differs from the count
parameter, a writing error prevented the function from completing
. In this case, the error indicator (ferror)
will be set for the stream.
If either size
or count
is zero
, the function returns zero
and the error indicator remains unchanged.
size_t
is an unsigned integral type.
Example
/* 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
Pointer
to aFILE
object that identifies the stream.
offset
Binary files
: Number of bytes to offset fromorigin
.Text files
: Eitherzero
, or avalue
returned 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-zero
value.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
Pointer
toa FILE object
that 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
Pointer
to aFILE
object that identifies the stream.
Return Value
A non-zero value
is returned in the case that the end-of-file
indicator associated with the stream is set.
Otherwise, zero is returned
.
Example
/* 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-string
beginning 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-string
beginning with the representation of an integral number.
Return Value
On success
, the function returns the converted integral number as an int
value.
If the converted value would be out of the range of representable values by an int
, it causes undefined behavior
.
See strtol
for a more robust cross-platform alternative
when this is a possibility.
Example
/* 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
Pointer
to a memory block previously allocated withmalloc
,calloc
orrealloc
.
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 array
where the content is to be copied, type-casted to a pointer of typevoid*
.
source
Pointer to the source of data
to be copied, type-casted to a pointer of type constvoid*
.
num
Number
of bytes to copy.size_t
is 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
Pointer
to block of memory.
ptr2
Pointer
to block of memory.
num
Number of bytes
to compare.
Return Value
Returns an integral value
indicating the relationship between the content of the memory blocks
:
return value | indicates |
---|---|
<0 |
the first byte that does not match in both memory blocks has a lower value in ptr1 than in ptr2 (if evaluated as unsigned char values) |
0 |
the contents of both memory blocks are equal |
>0 |
the first byte that does not match in both memory blocks has a greater value in ptr1 than in ptr2 (if evaluated as unsigned char values) |
Example
/* 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 string
to be compared.
str2
C string
to be compared.
Return Value
Returns an integral value
indicating the relationship
between the strings:
return value | indicates |
---|---|
<0 |
the first character that does not match has a lower value in ptr1 than in ptr2 |
0 |
the contents of both strings are equal |
>0 |
the first character that does not match has a greater value in ptr1 than in ptr2 |
Example
#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 string
to truncate.Notice that this string is modified by being broken into smaller strings (tokens).
Alternativelly,
a null pointer
may be specified, in which case the function continues scanning where a previous successful call to the function ended.
delimiters
C string
containingthe delimiter characters
.These can be different from one call to another.
Return Value
If
a token
is found,a pointer to the beginning of the token.
Otherwise,
a null pointer
.A null pointer
is always returned when the end of the string (i.e.,a null character
) is reached in the string being scanned.
Example
/* 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
Pointer
to the block of memory to fill.
value
Value to be set
. The value is passed as anint
, but the functionfills
the block of memory using theunsigned char
conversion of thisvalue
.
num
Number of bytes
to be set to thevalue
.size_t
is 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 element
whose mapped value is accessed.Member type
key_type
is the type of the keys for the elements stored in the container, defined in map as an alias of its first template parameter (Key
).If an
rvalue (second version)
, the key ismoved instead of copied
when a new element is inserted.
Return Value
A reference
to the mapped value of the element with a key
value equivalent to k
.
Member type mapped_type
is the type of the mapped values in the container, defined in map
as an alias of its second template parameter
(T
).
Example
// 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::construct
cannot construct an element withk
and a default-constructedmapped_type
(or ifmapped_type
is 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
Key
to search for.Member type
key_type
is the type of the element keys in the container, defined inmap
as 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
vector
object of the same type (i.e., with the same template parameters,T
andAlloc
).
il
An
initializer_list
object. The compiler will automatically construct such objects frominitializer list
declarators.Member type
value_type
is the type of the elements in the container, defined invector
as 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 elements
are 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::construct
is not supported with the appropriate arguments for the element constructions, or ifvalue_type
isnot copy assignable
(ormove assignable
for (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 elements
in the container.Member type
size_type
isan 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 element
s, 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_type
is an unsigned integral type.
val
Object
whose content is copied to the added elements in case thatn
is greater thanthe current container size
.If
not specified
,the default constructor
is used instead.Member type
value_type
is the type of the elements in the container, defined invector
as an alias of the first template parameter (T
).
Return Value
none
If a reallocation
happens, the storage is allocated using the container’s allocator
, which may throw exceptions on failure (for the default allocator
, bad_alloc
is thrown if the allocation request does not succeed).
Example
// 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
Linear
on the number of elements inserted/erased (constructions/destructions
).If a
reallocation
happens, the reallocation is itself up to linear inthe entire vector size
.
Iterator validity
In case the container
shrinks
,all iterators
,pointers
andreferences
to elements that have not been removed remain valid after the resize andrefer to the same elements
they were referring to before the call.If the container
expands
,the end iterator
isinvalidated
and, if it has toreallocate storage
, alliterators
,pointers
andreferences
related 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
n
is accessed, and concurrently accessing or modifying them issafe
.
Exception safety
If
n
is less than or equal to the size of the container, the functionnever
throws exceptions (no-throw guarantee
).If
n
is greater and a reallocation happens, there areno changes
in 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 element
in the container.Notice that
the first element
has a position of0
(not1
).Member type
size_type
is anunsigned integral type
.
Return Value
The element at the specified position
in thevector
.If the
vector
object isconst-qualified
, the function returns aconst_reference
. Otherwise, it returns areference
.Member types
reference
andconst_reference
are 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
container
isaccessed
(neither theconst
nor thenon-const
versions modify the container).The reference returned can be used to
access
ormodify 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
Value
to becopied
(ormoved
) to the new element.Member type
value_type
is 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
reallocation
happens, all iterators, pointers and references related to the container areinvalidated
.Otherwise
, onlythe end iterator
isinvalidated
, 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
reallocation
happens, all contained elements are modified.Otherwise, no existing element is accessed, and concurrently accessing or modifying them is safe.
Exception safety
If
no reallocations
happen, there areno changes
in the container in case of exception (strong guarantee).If a
reallocation
happens, the strong guarantee is also given if the type of the elements is eithercopyable
orno-throw moveable
.Otherwise, the
container
is guaranteed toend in a valid state
(basic guarantee).If
allocator_traits::construct
is not supported withval
as 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
Linear
in 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 iterators
to the initial and final positions of the sequence to be sorted. The range used is[first,last)
, which contains all the elements betweenfirst
andlast
, including the element pointed byfirst
but not the element pointed bylast
.RandomAccessIterator
shall point to a type for whichswap
is properly defined and which is bothmove-constructible
andmove-assignable
.
comp
Binary function that accepts
two elements
in 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
Values
to compare.
comp
Binary function
that acceptstwo values
of typeT
as arguments, and returnsa value convertible to bool
. The value returnedindicates
whether the element passed asfirst argument
is consideredless than
the second.The function
shall not modify
any of its arguments.This can either be
a function pointer
ora function object
.
il
An
initializer_list
object.These objects are automatically constructed from
initializer list
declarators.
T
shall support being compared with operator<
.
Return Value
The lesser
of the values passed as arguments.
Example
// 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
begin
is 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
结语
第二十九篇博文写完,开心!!!!
今天,也是充满希望的一天。