2011-05-04 23 views
1

我写了一个小程序,它反转一个字符串,并将其打印到屏幕:这个程序是兼容的大和小endian系统?

void ReverseString(char *String) 
{ 
    char *Begin = String; 
    char *End = String + strlen(String) - 1; 
    char TempChar = '\0'; 

    while (Begin < End) 
    { 
     TempChar = *Begin; 
     *Begin = *End; 
     *End = TempChar; 
     Begin++; 
     End--; 
    } 
    printf("%s",String); 
} 

它完美地在开发的C++在Windows(小端)。 但我突然怀疑它的效率。如果你看这条线:

while (Begin < End) 

我比较开始和结束的地址。这是正确的方法吗? 此代码是否适用于像Mac OS X这样的大端操作系统? 或者我在想错误的方式?

我有上面提到的几个疑问。 任何人都可以请澄清?

+0

作为一个次要的挑剔,TempChar在循环之外是毫无意义的,也没有必要对它进行初始化。在循环内移动它,并使其为const:const TempChar = * Begin ;. – unwind 2011-05-04 07:10:56

+0

另一个小小的挑剔 - Mac OS X不是大端,它可以是大或小端,因为它运行在x86(小端),PowerPC(大端)和其他体系结构上。 – 2011-05-04 07:16:29

+1

如果您正在查找问题,则在传递位于数组开头的空字符串时,此代码具有未定义的行为 - 无法在“开始之前”指针指向一个空字符串。在实践中,它可以在平坦记忆模型的任何地方工作,也可能在大多数地方没有。 – 2011-05-04 08:31:05

回答

6

您的代码没有排序相关的问题。你比较两个指针的方式也没有问题。总之,你的代码很好。

+0

你能否详细解释一下为什么你认为它是正确的? – Vijay 2011-05-04 06:47:24

+3

@僵尸:你的代码中只有指针和字符(字节)。这些字节按照定义为endian-neutral。而你所做的所有指针都是读,分配,递增和递减,所有这些都是端到中立的操作。你解引用字节也是endian中立的。所以一切都很好。 – DarkDust 2011-05-04 07:06:33

1

只要你操纵整个type T对象(这就是你所做的type Tchar)你只是不能遇到字节顺序问题。

例如,如果您尝试在较大的类型中操作单独的字节(例如int),但您没有这样做,您可以运行它们。这就是为什么在你的代码期间不可能存在字节码问题。

3

Endianness定义为多字节基元类型中字节的显着性顺序。所以如果你的int是big-endian,这意味着在内存中的int的第一个字节(即具有最低地址的那个)包含int的最高有效位,依此类推到最后/最不重要。那是全部它的意思。当我们说一个系统是big-endian时,这通常意味着它的所有指针和算术类型都是big-endian,尽管这里有一些奇怪的特殊情况。 Endian-ness不会影响指针算术或比较,也不会影响字符串存储在内存中的顺序。

您的代码不使用任何多字节基元类型[*],所以endian-ness无关紧要。一般来说,如果您以某种方式访问​​此类对象的各个字节(例如,通过投射指向unsigned char*的指针,将内存写入文件或通过网络等),则字节序只会变得相关。

假设主叫做这样的事情:

int x = 0x00010203; // assuming sizeof(int) == 4 and CHAR_BIT == 8 
ReverseString((char *)&x); 

然后他们代码将尾数依赖。在一个big-endian系统中,他们会传递给你一个空字符串,因为第一个字节是0,所以你的代码将不会改变x。在一个小端系统,他们会通过你三字节的字符串,因为前三个字节是0x030x020x01,第四个字节为0,所以你的代码会改变x0x00030201

[*]以及,指针是多字节的,在OSX和几乎每个C实现上都是如此。但是你不检查他们的存储表示,你只是用它们作为值,所以没有机会根据字节顺序来区分行为。