字符串和字符串函数

C语言中的字符串一般就是字符数组(char array terminated with a null character '\0')。而数组和指针又可以操作字符串,同时C标准库(stdio.h和string.h等)提供了很多常用的字符串操作函数。
因此,有必要记录这些重要的函数,以及字符串的函数和指针操作。

字符串的定义方式

最常用的方式为使用字符串常量,使用char类型数组,或使用char指针。

字符串常量

如"I am a symbolic string"等,字符串常量存储在内存中的静态存储区中,意味着一旦在函数中使用字符串常量,字符串常量仅会存储一次,其生命周期在整个程序的运行期,无论函数调用多少次。
整个字符串短语充当指向存储字符串的位置的指针。 此操作类似于充当指向数组位置的指针的数组的名称。如下程序示例。

#include<stdio.h>
int main(void)
{
    printf("%s, %p, %c\n", "We", "are", *"space farers");

    return 0;
}

输出结果为:
We, 0x104fbafa1, s。可以看出,%s输出整个字符串,%p输出字符串常量的地址,*操作取字符串首地址的值,即为s。

字符串数组的初始化

const char m1[40] = "Limit yourself to one line's worth."; const表示不允许通过m1的操作改变字符串产量。
const char m2[6] = "hello"; 和 const char m2[6] = {'h', 'e', 'l', 'l', 'o', '\0'}的标准数组初始化相同。值得注意的是,若以第二种方式声明字符串数组,必须显式使用'\0‘作为最后一个字符,否则该数组仅仅为字符数组,而不是字符串。
省略数组方括号中的字符长度,编译器将自动决定所需大小。

字符串的数组表示和指针表示的区别

示例:

// addresses.c -- addresses of strings
#define MSG "I'm special."

#include<stdio.h>
int main(void)
{
    char ar[] = MSG;
    const char *pt = MSG;
    printf("address of \"I'm special\": %p \n", "I'm special");
    printf("              address ar: %p\n", ar);
    printf("              address pt: %p\n", pt);
    printf("          address of MSG: %p\n", MSG);
    printf("address of \"I'm special\": %p \n", "I'm special");

    return 0;
}

输出:
address of "I'm special": 0x10de0ef4c
address ar: 0x7ffee1df1adb
address pt: 0x10de0ef20
address of MSG: 0x10de0ef20
address of "I'm special": 0x10de0ef4c

解读:pt和MSG的地址相同,ar的地址不同。MSG存储在静态存储区,pt指向静态存储区中该字符串的首地址,所以MSG和pt的值相同。而ar是在程序运行时才分配内存的,此时静态存储区中的字符串会复制一份到字符串数组中,但数组的首地址和静态存储区中的地址不为同一个地址。也就是说,此时会有MSG的两份字符串,一份为静态存储区中的, 另一份为存储在ar中。
"I'm special."打印了两次,但编译器选择使用同一个存储位置,却和MSG的地址不同。编译器可以自由的选择"I'm special"存储在一个位置还是不同位置(对于程序中多次出现该字符串常量来说)。

猜你喜欢

转载自www.cnblogs.com/jeffrey-yang/p/10223128.html