字符串与指针

1、字符串的表示形式

  在C程序中,可以用两种方法访问一个字符串:(1)用字符数组存放一个字符串,然后输出该字符串;(2)用字符指针指向一个字符串。

//定义一个字符数组,对它初始化,然后输出该字符串
#include<stdio.h>
int main(){
    char string[]="I love China!";
    printf("%s\n",string);
    return 0;
} 

和前面介绍的数组属性一样,string 是数组名,它代表字符数组的首元素的地址。string[4]代表数组中序号为4的元素(它的值是字母v),实际上string[4]就是善(string+4),string+4是一个地址,它指向字符“v”。

//可以不定义字符数组,而定义一个字符指针。用字符指针指向字符串中的字符。
#include<stdio.h>
int main(){
    char *string="I love China!";
    printf("%s\n",string);
    return 0;
}

在这里没有定义字符数组,在程序中定义了一个字符指针变量string,用字符串常量“I love China!"对它初始化。C语言对字符串常量是按字符数组处理string的,在内存中开辟了一个字符数组用来存故该字符串常量。对字符指针C变量string初始化,实际上是把字符串第1个元素的地址(即存放字符串的字符数组的首元素地址)赋string。有人误认为皮,string是一个字符串变量,以为在定义时把“I love China!"这几个字符赋给该字符串变量,这是不对的。定义string的部分:

char *string="I love China!"

等价于:

char *string;                                                                                                                                                                                                                                                string="I love China!";

可以看到string被定义为一个指针变量,指向字符型数据,请注意它只能指向一个字符变量或其他字符类型数据,不能同时指向多个字符数据,更不是把“I love China!"这些字符存放到string中(指针变量只能存放地址),也不是把字符串赋给* string。只是把“I love China!"的第1个字符的地址赋给指针变量string。

  输出时用printf("%s\n",string);,%s是输出字符串时所用的格式符,在输出项中给出字符指针变量名string,则系统先输出它所指向的一个字符数据,然后自动使string加1,使之指向下一个字符,然后再输出一个字符.....如此直到遇到字符串结束标志'\0'为止。注意,在内存中,字符串的最后被自动加了一个‘\0',因此在输出时能确定字符串的终止位置。说明:通过字符数组名或字符指针变量可以输出一个字符串。而对一个数值型数组,是不能企图用数组名输出它的全部元素的。

//将字符串a复制为字符串b
#include<stdio.h>
int main(){
    int i;
    char a[]="I am a boy!",b[20];
    for(i=0;*(a+i)!='\0';i++)
        *(b+i)=*(a+i);
    *(b+i)='\0';
    printf("string a is:%s\n",a);
    printf("string b is:");
    for(i=0;*(b+i)!='\0';i++)
        printf("%c",b[i]);
    printf("\n");
    return 0; 
}

运行结果:

程序中a和b都定义为字符数组,可以通过地址访问其数组元素。在for语句中,先检查a[i]是否为'\0'(今a[i]是以*(a+i)形式表示的)。如果不等于'\0’,表示字符串尚未处理完,就将a[i]的值赋给b[i],即复制一个字符。在for循环中将a串全部复制给了b串。最后还应将'\ 0复制过去,即:*(b+i)='\0'。

//也可以用指针变量,用它的值的来改变来指向字符串中不同的字符
#include<stdio.h>
int main(){
    char a[]="I am a boy!",b[20],*p1,*p2;
    int i;
    p1=a;
    p2=b;
    for(;*p1!='\0';p1++,p2++)
        *p2=*p1;
    *p2='\0';
    printf("string a is:%s\n",a);
    printf("string b is:");
    for(p2=b;*p2!='\0';p2++)
        printf("%c",*p2);
    printf("\n");
    return 0;
} 

p1、p2是指向字符型数据的指针变量。先使p1和p2的值分别为字符串a和b第1个字符的地址。* p1最初的值为‘I’,赋值语句“*p2=*p1的作用是将字符'I'(a串中第1个字符)赋给p2所指向的元素,即b[0]。然后p1和p2分别加1,指向其下面的一个元素,直到*pl的值为'\0'止。注意p1和p2的值是不断在改变的,程序必须保证p1和p2同步移动。

2、字符指针作函数参数

   将一个字符串从一个 函数传递到另一个 函数,可以用地址传递的办法,即用字符数组名作参数,也可以用指向字符的指针变量作参数。在被调用的函数中可以改变字符串的内容,在主调函数中可以得到改变了的字符串。
//用函数调用实现字符串的复制,用字符数组作参数 
#include<stdio.h>
void copy(char a[],char b[]){
    int i=0;
    while(a[i]!='\0'){
        b[i]=a[i];
        i++;
    }
    b[i]='\0';
}
int main(){
    char a[]="I am a teacher!";
    char b[]="You are a student!";
    printf("string a=%s\nstring b=%s",a,b);
    printf("\ncopy string a to b:\n");
    copy(a,b);
    printf("string a=%s\nstring b=%s",a,b);
    return 0;
}

运行结果:

注意:b数组最后3个元素仍保留原状。在输出b时由于按%s(字符串)输出,遇'\0'即告结束,因此第一个'\0'后的字符不输出。如果不采取%s格式输出而用%c逐个字符输出是可以输出后面这些字符的。在main函数中也可以用字符型指针变量作实参,先使指针变量a和b分别指向两个字符串。函数可改写如下:

#include<stdio.h>
void copy(char a[],char b[]){
    int i=0;
    while(a[i]!='\0'){
        b[i]=a[i];
        i++;
    }
    b[i]='\0';
}
int main(){
    char m[]="I am a teacher!";
    char n[]="You are a student!";
    char *a=m,*b=n;
    printf("string a=%s\nstring b=%s",a,b);
    printf("\ncopy string a to b:\n");
    copy(a,b);
    printf("string a=%s\nstring b=%s",a,b);
    return 0;
} 

以下程序是以形参用字符指针变量实现的:

#include<stdio.h>
void copy(char *a,char *b){
    for(;*a!='\0';a++,b++){
        *b=*a;
    }
    *b='\0';
}
int main(){
    char a[]="I am a teacher!";
    char b[]="You are a student!";
    printf("string a=%s\nstring b=%s",a,b);
    printf("\ncopy string a to b:\n");
    copy(a,b);
    printf("string a=%s\nstring b=%s",a,b);
    return 0;
} 

猜你喜欢

转载自www.cnblogs.com/geziyu/p/9689848.html