您的位置:首页 > 编程语言 > C语言/C++

C语言中的字符串与指针

2009-09-21 10:47 246 查看
C语言中的字符串实际上就是char类型的一维数组。按照约定,C的字符串是以字符串结束标志/ 0 (或null)结尾的。null字符就是所有位均为 0 的字符。因此,它的十进制值是 0 。由于字符串的处理具有它自己的方式,因此我们把它当作一个独立的主题。把字符串看成是长度可变,由/ 0 定界、但最大长度不超过字符串本身长度的这种观点是非常有用的。字符串的长度必须包含存储结尾的/ 0 字符所需要的存储空间。和所有数组一样,程序员应该确保字符串的边界未超出。

字符串常量由一对双引号所包围。例如,"abc"是一个长度为4的字符数组,其中最后一个元素是结尾字符/ 0 。注意,字符串常量和字符常量是不同的概念。例如,'a' 和 "a" 并不相同。后者拥有两个元素,一个是'a' ,另一个是'/ 0 '。

字符串常量和数组名一样,也是被编译器当成指针来对待的。它的值就是字符串的基地址。考虑下面的代码:

char *p="abc";

printf("%s %s/n",p,p+1);

变量p被赋值为字符数组"abc"的基地址。当一个char类型的指针按照字符串格式打印时,被指向的字符以及每个后续字符都被打印出来,而指向字 符串"abc"中字母b的表达式p+1将导致bc被打印出来。由于象"abc"这样的字符串常量是被当作指针看待的,因此下面的两个表达式都是可行的:

"abc"[1] 和 *("abc"+2)

如果输出的话结果应该是bc 和c。下面我们通过一个具体例子来说明。

int main(void)
{
printf("%c%c%c%c!/n",
"ghi"[1],*("def"+1),
*"abc"+11,"klm"[1],*"ghi"+8);
getch();
}

以上程序编译运行后可以看到运行结果为:hello!

但是,虽然数组和指针具有相似的用法,它们也是存在区别的。考虑下面两个声明:

char*p="abcde"; 和 char s[]="abcde";

在第一个声明中,编译器在内存中为p分配空间,把字符串常量“abcde”放在内存中的其他位置,并把p的值初始化为这个字符串的基地址。我们现在可以把p看成是指向这个字符串,第二个声明相当于:

char s[]={'a','b','c','d','e','/ 0 '};

由于方括号是空的,编译器为数组s分配6个字符的内存。第一个字节被初始化为'a',第二个字节被初始化为'b',接下来依次类推。我们可以把这些对象看成是象下面这样存储在内存中的:



char总是按照1个字节存储的,在绝大多数机器上指针是按照1个机器字存储的。因此,这里p是按4个字节存储的,而s是按6个字节存储的。请看以下代码:

void f(int a[]);
int main(void)
{
char s[]="deep in the heart of texas";
char *p="deep in the heart of texas";
int a[3];
double d[5];
printf(%s%d/n%s%d/n%s%d/n%s%d/n","sizeof(s)=",sizeof(s),
"sizeof(p)=",sizeof(p),
"sizeof(a)=",sizeof(a),
"sizeof(d)=",sizeof(d));
f(a);
getch();
return 0 ;
}
void f(int a[])
{
printf("In f() :sizeof(a)=%d/n",sizeof(a));
}

运行结果为:



最后,我们来看一个用一句话实现字符串拷贝的例子:

while(*s1++=*s2++);

实现字符串s2到字符串s1的拷贝。只要表达式*s1++=*s2++的结果为true,while循环就会被执行。假定*s1指向一个字符串中的 一个字符,并且s2指向另一个不同字符串中的一个字符。s2所指向的值被赋值给s1所指向的值,并且把它作为整个表达式的值。然后s1和s2都进行增值, 使它们指向各自字符串中的下一个字符。

s1所指向的字符被赋值为s2所指向的字符值。然后两者都进行增值,使它们各自指向下一个字符。这个过程持续进行,直到s2指向null字符/ 0 (其值为 0 )。当 0 这个值被赋给s1所指向的字符时,相当于设置了字符串的结束标志,并且整个表达式的值为 0 ,使控制流推出while循环。这样,就把字符串s2复制给字符串s1。

还要注意的一点是:对于*s1++ ,由于单目操作符++处于后缀位置,它的优先级高于*操作符,因此*s1++ 相当于*(s1++) ,这意味着s1本身被增值。反之,(*s1)++ 则是对s1所指向的对象进行增值,而s1本身的值保持不变。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: