在第一个示例中,您声明了一个指向变量的指针:
// A variable pointer to a variable string (i.e. an array of 6 bytes).
char *pName = "David";
此时可以修改'D', 'a', 'v', 'i', 'd', '\0'占用的6个字节:
pName[0] = 'c';
*pName = 'c';
*(pName+0) = 'c';
strcpy(pName, "Eric"); // Works well
但只有那 6 个字节:
// BUG: Will overwrite 2 random bytes located after \0 in RAM.
strcpy(pName, "Fredrik");
可以在运行时更改指针以指向另一个变量字符串,例如
pName = "Charlie Chaplin";
然后可以修改
pName[0] = 'c';
*pName = 'c';
*(pName+0) = 'c';
// OK now, since pName now points to the CC array
// which is 16 bytes located somewhere else:
strcpy(pName, "Fredrik");
正如其他人所说,您通常会在指针情况下使用const char *,这也是使用字符串的首选方式。原因是编译器会帮助您解决最常见(也很难找到)的内存垃圾错误:
// A variable pointer to a constant string (i.e. an array of 6 constant bytes).
const char *pName = "David";
// Pointer can be altered runtime to point to another string e.g.
pName = "Charlie";
// But, the compiler will warn you if you try to change the string
// using any of the normal ways:
pName[0] = 'c'; // BUG
*pName = 'c'; // BUG
*(pName+0) = 'c'; // BUG
strcpy(pName, "Eric");// BUG
其他方式,使用数组,灵活性较低:
char aName[] = "David"; // aName is now an array in RAM.
// You can still modify the array using the normal ways:
aName[0] = 'd';
*aName = 'd';
*(aName+0) = 'd';
strcpy(aName, "Eric"); // OK
// But not change to a larger, or a different buffer
aName = "Charlie"; // BUG: This is not possible.
同样,常量数组对您的帮助更大:
const char aName[] = "David"; // aName is now a constant array.
// The compiler will prevent modification of it:
aName[0] = 'd'; // BUG
*aName = 'd'; // BUG
*(aName+0) = 'd'; // BUG
strcpy(aName, "Eric");// BUG
// And you cannot of course change it this way either:
aName = "Charlie"; // BUG: This is not possible.
使用指针与数组声明的主要区别在于sizeof()的返回值:sizeof(pName)是指针的大小,通常为4。sizeof(aName)返回数组的大小,即长度字符串+1。
如果在函数内部声明变量,则最重要的是,尤其是当字符串很长时:它占用了更多宝贵的堆栈。因此,通常避免数组声明。
将变量传递给使用sizeof() 的宏时也很重要。此类宏必须提供预期的类型。
如果你想这样做也很重要。交换字符串。声明为指针的字符串是直截了当的,需要 CPU 访问更少的字节,只需移动指针的 4 个字节:
const char *pCharlie = "Charlie";
const char *pDavid = "David";
const char *pTmp;
pTmp = pCharlie;
pCharlie = pDavid;
pDavid = pTmp;
pCharlie 现在是“David”,pDavid 现在是“Charlie”。
使用数组,你必须为最大的字符串提供足够大的临时存储空间,并使用 strcpy(),它会占用更多 CPU,在字符串中逐字节复制。
最后一种方法很少使用,因为编译器会自动计算出 David 需要 6 个字节。不需要告诉它什么是显而易见的。
char aName[6] = "David";
但是,它有时用于数组必须是固定长度的情况,与它的内容无关,例如在二进制协议或文件中。在这种情况下,如果将来有人不小心从字符串中添加或删除字符,手动添加限制可能会有所帮助,以便从编译器获得帮助。