6.1 字符串

字符串的存储:

        1.字符串就是一组字符组成,用双引号括起来表示,用字符’\0‘作为结束符(ASCII码也是0)

                "hello world\0" 等价于 "hello world\0"

                "hello" " world"等价于"hello world"

                char e = '10'; 字符

                char e = 10; 是char类型,是以ASCII码作为值赋给变量

                char e = "10" 字符串 //并且无法保存,字符串不能如此定义

        2.C语言存储字符串的方法

                将字符串中每个字符的ASCII码按先后顺序存储在一段连续的内存中,每个字符占一个字节,最后用空字符,即ASCII码为0的字符结尾

 

字符串的表示

        C语言表示字符串的方式

                字符指针方式 字符指针不能修改任意字符,只能查看!!!! 不能pstr[2] = 'c';

                char *pstr = "hello";//pstr保存字符串的首地址!!!!!注意是首地址!!!不是hello字符串!!!!

                不能通过pstr修改指向的字符串,例如:pstr[1] = 'E'

                printf("%s\n",pstr); //打印字符串只需传递一个首地址

字符数组方式         字符数组可以任意修改任意字符!!!

        str[] = "abc";

        str[] = {'a','b','c','\0'};

                数组名即字符串首地址

                可以用字面值初始化,也可以用{}初始化

                        用{}初始化需要手动显示注明结束符,否则就是一个数组

        指针对应的字符串,其内存分配在常量区,不可更改

        但是数组内存放的字符串,是数组自己定义并分配的内存空间,放在栈区,栈区的内存值是可以修改的

//字符串演示
//切记:当调用一个函数时,如果给这个函数传递一个字符串,实际本质是将这个字符串的首地址
//传递给这个函数
#include <stdio.h>
int main(void) {
    printf("%s\n", "abcd\0"); //打印字符串占位符是:%s(s=string=字符串)
    printf("%s\n", "abcd");
    printf("%s\n", "1234\0abcd"); //1234
    printf("abcd""12345\n"); //printf("abcd12345\n");
    printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
    printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
    //字符指针变量和字符串的那点事儿
    char *pstr = "abc"; //pstr保存字符串abc的首地址,并且字符串abc所在的内存区域只能读不能修改
    printf("%s\n", pstr);//打印字符串只需传递一个首地址即可
    printf("%c %c %c\n", pstr[0], pstr[1], pstr[2]);
    printf("%d %d %d %d\n", *(pstr+0), *(pstr+1), *(pstr+2), *(pstr+3));
    //pstr[2] = 'C'; //不可以修改,直接崩溃
    //数组来表示字符串
    char str[] = {'x', 'y', 'z', '\0'};//此时str既是数组又是字符串
    printf("%s\n", str); //打印字符串
    printf("%c %c %c\n", str[0], str[1], str[2]);
    printf("%c %c %c\n", *(str+0), *(str+1), *(str + 2));
    str[2] = 'Z'; //可以修改
    printf("%s\n", str); //打印字符串
    char str1[] = "mnab";
    printf("%s\n", str1); //打印字符串
    *(str1 + 2) = 'A'; //可以修改
    printf("%s\n", str1); //打印字符串
    printf("%lu\n", sizeof(str1));
    return 0;
}

切记!!:当调用一个函数时,如果给这个函数传递一个字符串,实际本质是将这个字符串的首地址传递给这个函数

        printf("%s","abcd")

        char *pstr = "abcd";

        char parr[] = "abcd"

        printf("%s",pstr);prrintf("%s",parr);

        printf("%c %c %c %c",pstr[0],pstr[1],pstr[2],pstr[3]); //parr也可以

        printf("%d %d",*(pstr + 0),*(pstr+1)); //打印ASCII码值

字符串的输入

        scanf("%s",); //按照字符串形式将输入的字符串保存到str数组中,碰到空格就结束

        char* gets (char* s) ; /从标准输入读取一行字符串,读到换行符即返回,并将所读到的换行符置换为结尾空字符

字符串的输出

        printf("%s",...);

        int puts(const char *s);

                向标准输出写入一行字符串,并追加一个换行符

示例:

//字符串输入和输出的标准库函数:scanf/gets/printf/puts
#include <stdio.h>
int main(void) {
    char str[100] = {0}; //分配内存存储输入的字符串

    //从键盘上输入字符串保存到数组str中
    //scanf("%s", str);//按照字符串形式将输入的字符串保存到str数组中,碰到空格就结束
    gets(str);//获取字符串保存到str
    
    //打印字符串到显示器
    //printf("%s\n", str);
    puts(str);
    return 0;
}

字符串函数

                标准库提供一套专门针对字符串的函数

        字符串头文件:

                #include

        字符串长度

                unsigned int strlen(const char *s)

        字符串拷贝

                char* strcpy(char *dest, const char *src)

                char* strncpy(char* dest, const char *src, unsigned int n)

                字符串拷贝会覆盖数组中的原有字符串,且拷贝不可拷贝到字符指针上

                字符串的拷贝如 char a[100] = "123456"

                strcpy(a,"abcd");

         此时打印的结果是abcd,5被abcd的结束符覆盖,但是内存中还保留6

        字符串拼接

                char *strcat(char *dest, const char *src)

                char *strncat(char *dest, const char* src,unsigned int n)

        字符串比较

                int strcmp(const char *s1, const char* s2)

                int strncmp(const char *s1,const char *s2, size_t n)

                        字符串相等时 回0;

                        前边大于后边时回正数

                        后边大于前边时回负数

                        字符串比较的是ASCII码值,从左往右第一个不同结果时ASCII码的比较

使用字符串函数时需要注意

        1.所有字符串都必须以空字符结尾

        2.字符串长度以char为单位且不包含结尾空字符

        3.拷贝和连接的目标缓冲区必须可写且足够大

        4.不能使用关系运算符比较字符串

示例:

//字符串处理标准C库函数
//你们内心一定要有个鉴定的信念:这些函数我也能自己编写!
#include <stdio.h>
#include <string.h>
int main(void) {
    //1.strlen:获取字符串中有效字符的个数,不包含'\0'
    char *p1 = "abcdefg";
    printf("%lu, %lu\n", strlen(p1), strlen("abc"));
    //2.strcat:将一个字符串拼接到另一个字符串的后面
    char str[20] = "abc";//一次性分配20字节内存
    strcat(str, "xyz");//将字符串xyz拼接到abc的后面
    printf("%s\n", str);
    char *p2 = "mn";
    strcat(str, p2);//将p2指向的字符串mn拼接到abcxyz后面
    printf("%s\n", str);
    strncat(str, "1234", 2);//将字符串1234的前2个字符拼接到str对应的字符串后面
    printf("%s\n", str);
    //3.strcpy:字符串拷贝,将指定的字符串拷贝到指定的内存中
    char str2[20] = "abcd";
    strcpy(str2, "123456");//将字符串拷贝到str2数中
    printf("%s\n", str2);
    char *p3 = "abcd";
    strcpy(str2, p3);//将p3指向的字符串abcd拷贝到str2数组中
    printf("%s\n", str2);
    for(int i = 0; i < sizeof(str2)/sizeof(str2[2]); i++) //调试打印
        printf("%hhd ", str2[i]);
    printf("\n");
    strncpy(str2, "123456789", 7);//将字符串123456789前7个字符拷贝到str2数中
    printf("%s\n", str2);
    //4.strcmp:字符串比较,从左边到右边一个字符一个字符的比较,只要不相等或者字符串结束
    //比较就立刻结束
    int ret = 0;
    ret = strcmp("abc", "abc");
    printf("abc和abc比较的结果是:%d\n", ret);
    ret = strcmp("abd", "abc");
    printf("abd和abc比较的结果是:%d\n", ret);
    ret = strcmp("abc", "abd");
    printf("abc和abd比较的结果是:%d\n", ret);
    ret = strncmp("abc", "abd", 2);
    printf("abc和abd前2个字符比较的结果是:%d\n", ret);
    return 0;
}

提问

编写resverse函数实现字符串的反转:“12345678” - -> "87654321"

//字符串反转
#include <stdio.h>
#include <string.h>
//pstr="a   b   c   d   e   f   g   h" //字符
//      0   1   2   3   4   5   6   7  //下标
//      i                           len-1-i
//          i                   len-1-i
//              i           len-1-i
//                  i   len-1-i

void reverse(char *pstr/*char pstr[]*/) { //pstr保存数组的首地址:char *pstr = str;
    int len = strlen(pstr); //len=8, len/2=4
    for(int i = 0; i < len / 2; i++) {
        char c = pstr[i];
        pstr[i] = pstr[len-1-i];
        pstr[len-1-i] = c;
    }
}
int main(void) {
    char str[1024] = {0};
    for(;;) {
        gets(str); //从键盘上获取字符串保存到数组str
        reverse(str); //进行反转
        puts(str); //打印字符串
    }
    return 0;
}

提问:自己编写一个字符串比较函数

//自己编写一个字符串比较函数
#include <stdio.h>
//str1==str2,返回0
//str1>str2,返回>0
//str1<str2,返回<0
//str1 = "abc"
int my_strcmp(const char *str1, const char *str2) {
    while(*str1) {
        if(*str1 != *str2)
            return *str1 - *str2;
        str1++;
        str2++;
    }
    return *str1 - *str2;
}
int main(void) {
    int ret = 0;
    ret = my_strcmp("abc", "abc");
    printf("abc和abc比较的结果是:%d\n", ret);
    ret = my_strcmp("abd", "abc");
    printf("abd和abc比较的结果是:%d\n", ret);
    ret = my_strcmp("abc", "abd");
    printf("abc和abd比较的结果是:%d\n", ret);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值