您的位置:首页 > 其它

C和指针--第九章_问题

2015-01-11 19:15 134 查看
9.1、C语言缺少显式的字符串数据类型,这是一个优点还是一个缺点?
这个问题存在争议(虽然我作出了一个结论)。目前这种方法的优点是操纵字符数组的效率和访问的灵活性。它的缺点是有可能引起错误:溢出数组,使用的下标超出了字符串的边界,无法改变任何用于保存字符串的数组的长度等。
我的结论是从现代的面向对象的技术引出的。字符串类毫无例外地包括了完整的错误检查、用于字符串的动态内存分配和其他一些防护措施。这些措施都会造成效率上的损失。但是,如果程序无法运行,效率再高也没有什么意义。而且,较之设计C语言的时代,现代软件项目的规模要大得多。
因此,在数年前,缺少显式的字符串类型还能被看成是一个优点。但是,由于这个方法内在的危险性,所以使用现代的高级的、完整的字符串类还是物有所值的。如果C程序员愿意循规蹈矩地使用字符串,也可以获得这些优点。
9.2、strlen函数返回一个无符号量(size_t),为什么这里无符号值比有符号值更合适?但无符号值其实也有缺点,为什么?
It is more appropriate because the length of a string simply cannot be negative. Also, using an unsigned value allows longer string lengths
(which would be negative in a signed quantity) to be represented. It is less appropriate because arithmetic involving unsigned expressions can yield unexpected
results. The “advantage” of being able to report the length of longer strings is only rarely of value: On machines with 16 bit integers, it is needed only for strings exceeding 32,767 characters
in length. On machines with 32 bit integers, it is needed only for strings exceeding 2,147,483,647 bytes in length (which is rare indeed).
无符号值更合适,是因为一个字符串的长度不可能为负值。而且,使用无符号值可以表示更长的字符串长度(若用有符号数将可能是负值)。(无符号值)也有不合适的时候,是因为包含无符号表达式的算术运算将产生无法预期的结果。表示的字符串长度可以更长--这一“优势”价值并不大:在16位整型的机器上,只有当字符串的长度超过32,767时才被需要;而在32位整型的机器上,也仅仅是在字符串长度超过2,147,483,647个字节时才被需要(这很少见)。
9.3、如果strcat和strcpy函数返回一个指向目标字符串末尾的指针,和事实上返回一个指向目标字符串起始位置的指针相比,有没有什么优点?
Yes, then subsequent concatenations could be done more efficiently because the work of finding the end of the string would not need to
be repeated.
有。(这样会使得)后面的(字符串)衔接更有效率,因为定位字符串尾这一工作将不会被重复做。
9.4、如果从数组x复制50个字节到数组y,最简单的方法是什么?
使用其中一个操纵内存的库函数:
memcpy( y, x, 50);
重要的是不要使用任何str--函数,因为它们将在遇见第一个NUL字节时停止。如果你想自己编写循环,那要复杂得多,而且在效率上也不太可能压倒这个方案。
9.5、假定你有一个名叫buffer的数组,它的长度为BSIZE个字节,你用下面这条语句吧一个字符串复制到这个数组:
strncpy( buffer, some_other_string, BSIZE - 1);
它能不能保证buffer中的内容是一个有效的字符串?
Only if the last character in the array is already NUL. A string must be terminated with a NUL byte, and strncpy does not guarantee that
this will occur. However, the statement does not let strncpy change the last position in the array, so if that contains a NUL byte (either through an assignment
or by the default initialization of static variables), then the result will be a string.
只要数组的最后一个字符已经是NUL就行。一个字符串必须以一个NUL字节结尾,strncpy函数并不保证它的存在。然而,此声明并没有让strncpy函数改变数组的最后一个位置,所以该位置包含一个NUL字节(通过赋值或者静态变量的默认初始化),所以结果还是一个(有效的)字符串。
9.6、用下面这种方法
if( isalpha( ch ) ){
取代下面这种显式的测试有什么优点?
if( ch >= 'A' && ch <= 'Z' ||
ch >= 'a' && ch <= 'z' ){
First, the former will work regardless of the character set in use. The latter will work with the ASCII
character set but will fail with the EBCDIC character set. Second, the former will work properly whether or not the locale has been changed; the latter may not.
首先,前者在不考虑使用的字符集的前提下就能工作。后者可以在(支持)ASCII字符集(的机器)上运行,但是在EBCDIC字符集(的机器)上无法运行。其次,不管场所是否改变,前者都能正确运行,而后者可能不会。
9.7、下面的代码怎样进行简化?
for ( p-str = message; *p_str != '\0'; p_str++){
if( islower( *p_str) )
*p_str = toupper( *p_str );
}
The main thing is to eliminate the test for islower: this is unnecessary because toupper
includes such a test already. After that, the loop can be made more efficient (but not simpler!)
by saving a copy of the character being processed, like this:
关键是消除islower这个检验:这个是不必要的,因为toupper已经包含了相同的检验。另外,通过保留正被处理字符的一份拷贝,可以使循环更有效率(但不会更简洁!),如下:
register int ch;
...
for( pstring = message; ( ch = *pstring ) != ’\0’; ){
*pstring++ = toupper( ch );
}
9.8、下面的表达式有何不同?
memchr( buffer, 0, SIZE ) - buffer
strlen( buffer )
如果缓冲区包含了一个字符串,memchar将在内存中buffer的起始位置开始查找第1个包含0的字节并返回一个指向该字节的指针。将这个指针减去buffer获得存储在这个缓冲区的字符串的长度。strlen函数完成相同的任务,不过strlen的返回值是个无符号(size_t)类型的值,而指针减法的值应该是个有符号类型(ptrdiff_t)。
但是,如果缓冲区内的数据并不是以NULL字节结尾,memchar函数将返回一个NULL指针。将这个值减去buffer将产生一个无意义的结果。另一方面,strlen函数在数组的后面继续查找,直到最终发现一个NUL字节。
尽管使用strlen函数可以获得相同的结果,但一般而言使用字符串函数不可能查找到NUL字节,因为这个值用于终止字符串。如果它是你需要查找的字节,你应该使用内存操纵函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: