1. 程式人生 > >字符串與指針

字符串與指針

jpg 組元 賦值 字符數 src eight 下一個 lov 個數

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;
} 

字符串與指針