9.9 Memory Operations
By definition, a string is terminated with a NUL byte, so strings may not contain any NULs. However, it is not uncommon for nonstring data to contain zeros. You cannot use the string fractions to process this kind of data because they would stop working when they reached the first NUL.
根据定义,字符串由一个NUL 宇节结尾,所以字符串内部不能包含任何NUL 字符。但是,非字符串数据内部包含零值的情况并不罕见。你无法使用字符串函数来处理这种类型的数据,因为当它们遇到第1 个NUL 字节时将停止工作。
There is a related set of functions whose operations are similar to some of the string functions, but these functions deal with arbitrary sequences of bytes. Here are their prototypes.
不过,我们可以使用另外一组相关的函数,它们的操作与字符串函数类似,但这些函数能够处理任意的字节序列。下面是它们的原型。
void *memcpy( void *dst, void const *src, size_t length );
void *memmove( void *dst, void const *src, size_t length );
void *memcmp( void const *a, void const *b, size_t length );
void *memchr( void const *a, int ch, size_t length );
void *memset( void *a, int ch, size_t length );
Each prototype includes an explicit argument to indicate how many bytes to process, but unlike the strn--- functions, their operations do not stop if they encounter a NUL byte.
每个原型都包含二个显式的参数说明需要处理的字节数。但和strn 带头的函数不同,它们在遇到NUL 字节时并不会停止操作。
memcpy copies length bytes, beginning at src, into the memory beginning at dst.You can copy any type of value in this manner, so long as the third argument specifies the length of the value in bytes. The result is undefined if src and dst overlap in any way.
memcpy 从src 的起始位置复制length 个字节到dst 的内存起始位置。你可以用这种方法复制任何类型的值,第3 个参数指定复制值的长度(以字节计)。如果src 和dst 以任何形式出现了重叠,它的结果是未定义的。
For example:
char temp[SIZE], values[SIZE];
...
memcpy( temp, values, SIZE );
copies the SIZE bytes from the array values into the array temp.
它从数组values 复制SIZE 个字节到数组temp 。
But what if both were arrays of integers? Then (he following statement would do the job:
但是,如果两个数组都是整型数组该怎么办呢?下面的语句可以完成这项任务:
memcpy( temp, values, sizeof( values ) );
No casts are needed on the first two arguments because the prototype calls for void pointers, and any type of pointer can be converted to a void *.
前两个参数并不需要使用强制类型转换,因为在函数的原型中,参数的类型是void*型指针,而任何类型的指针都可以转换为void*型指针.
If only part of the array is to be copied, the desired count may be given for the third argument. For data that is larger than one byte, be sure to multiply the count by the size of each datum, for example:
如果数组只有部分内容需要被复制,那么需要复制的数量必须在第3 个参数中指明。对于长度大于一个字节的数据,要确保把数量和数据类型的长度相乘,例如:
memcpy( saved_answers, answers,
count * sizeof( answers[ 0 ] ) );
You can also copy structures or arrays of structures with this technique.
你也可以使用这种技巧复制结构或结构数组。
memmove behaves exactly the same as memcpy except that its source and destination operands may overlap. Though it need not be implemented this way, the result of memmove is the same as the result obtained by copying the source operand to a temporary location that overlaps neither the source nor the destination, then copying from this temporary location to the destination operand. memmove usually cannot be implemented using the special byte‐string handling instructions provided on some machines, so it may be slower than memcpy. However, memmove should be used when there is a real possibility of overlapping arguments, as in the following example.
memmove 函数的行为和memcpy 差不多,只是它的源和目标操作数可以重叠。虽然它并不需要以下面这种方式实现,不过memmove 的结果和这种方法的结果相同:把源操作数复制到一个临时位置,这个临时位置不会与源或目标操作数重叠,然后再把它从这个临时位置复制到目标操作数。memmove 通常无法使用某些机器所提供的特殊的字节-字符串处理指令来实现,所以它可能比 memcpy 慢一些。但是,如果源和目标参数真的可能存在重叠,就应该使用memmove. 如下例所示:
/*
** Shift the values in the x array left one position
*/
memmove( x, x + 1, ( count – 1 ) * sizeof( x[ 0 ] ) );
memcmp compares the length bytes of memory beginning at a to the bytes beginning at b. The values are compared byte by byte as unsigned characters, and the function returns the same type of value as strcmp – a negative value if a is less than b,a positive value if a is greater than b, and zero if they are equal. Because the values are compared as sequences of unsigned bytes, memcmp may give unexpected results if it is used to compare nonbyte data such as integers or floats.
memcmp 对两段内存的内容进行比较,这两段内存分别起始于a 和b. 共比较length 个字节。这些值按照无符号字符逐字节进行比较,函数的返回类型和strcmp 函数一样一一负值表示a 小于b.正值表示a 大于b. 零表示a 等于b 。由于这些值是根据一串无符号字节进行比较的,所以如果memcmp函数用于比较不是单字节的数据如整数或浮点数时就可能给出不可预料的结果'。
memchr searches the length bytes beginning at a for the first occurrence of the character ch and returns a pointer to that location. If the character does not occur,NULL is returned.
memchr 从a 的起始位置开始查找字符ch 第1 次出现的位置,并返回一个指向该位置的指针,它共查找length 个字节。如果在这length 个字节中未找到该字符,函数就返回一个NULL 指针。
Finally, memset sets each of the length bytes beginning at a to the character value ch. For example,
最后,memset 函数把从a 开始的length 个字节都设置为字符值ch 。例如:
memset( buffer, 0, SIZE );
initializes the first SIZE bytes of the buffer to zero.
把buffer 的前SIZE 个字节都初始化为0 。