三、C语言初阶:字符串

3 字符串

3.1 字符串操作:遍历、赋值、修改

int main(){
    char s[] = "Hello World!";
    // 字符串遍历1
    char* q = s;
    while('\0' != *q){
        printf("%c",*q++);
    }
    printf("\n");
    // 字符串遍历2
    for(int i = 0;'\0' != s[i];i++){
        printf("%c",s[i]);
    }
    printf("\n");

    // 字符串赋值
    char* p;
    p = s; //字符串可以赋值给指针
    // s = p; //指针不允许赋值给字符串

    // 字符串修改
    p[1] = 'A';
    printf("%p\n%p\n",s,p);
    printf("%s\t%s\n",s,p);
    s[2] = 'L';
    printf("%p\n%p\n",s,p);
    printf("%s\t%s\n",s,p);
}
Hello World!
Hello World!
0x7ffc0789c4fb
0x7ffc0789c4fb
HAllo World!	HAllo World!
0x7ffc0789c4fb
0x7ffc0789c4fb
HALlo World!	HALlo World!

3.2 字符串与函数

  • 字符串传参
    字符串传参方式与数组传参方式一样,只不过很多时候不需要传递字符串的长度
    两种传参方式:char* str / char str[]
void print_str(char* str){
    printf("%s\n",str);
}
void print_str2(char str[]){
    printf("%s\n",str);
}
int main(){
    char str[] = "Hello World!";
    print_str(str);
    print_str2(str);
}
  • 字符串返回
    字符串返回只能使用指针char*
    str1和str2拼接
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* Strcat(char* s1,char* s2){
    char *s = malloc(strlen(s1)+strlen(s2)+1);
    int k = 0;
    for(int i = 0;s1[i] != '\0';i++){
        s[k++] = s1[i];
    }
    for(int i = 0;s2[i] != '\0';i++){
        s[k++] = s2[i];
    }
    return s;
}
int main(){
    char str1[] = "Hello";
    char str2[] = "World";
    char* s = Strcat(str1,str2);
    printf("%s\n",s);
}

字符拼接2

#include <stdio.h>
char* Strcat(char* s1,char* s2){
    char* res = s1;
    while('\0' != *s1){
        ++s1;
    }
    while('\0' != *s2){
        *s1++ = *s2++;
    }
    *s1 = '\0';
    return res;
}
int main(){
    char str1[11] = "Hello";
    char str2[] = "World";
    char* s = Strcat(str1,str2);
    printf("%s\n",s);  
}

3.3 字符串指针

数组可以用指针表示
字符数组可以直接初始化字符数组,并且可以赋值给指针。

#include <stdio.h>
int main(){
    char s[] = "Hello World";
    char* p = s;
    printf("%s\n",p);
}

字符串也可以直接赋值给指针,这种指针成为字符串指针

#include <stdio.h>
int main(){
    char* s = "Hello World";
    printf("%s\n",s);
}

3.4 字符串指针 vs 字符数组

1、sizeof与strlen()
2、字符是否可修改
3、地址是否可修改

  • 1、sizeof与strlen()
#include <stdio.h>
#include <string.h>
int main(){
    char* s = "Hello World";
    char s1[] = "Hello World";
    printf("%d\t%d\n",sizeof(s),strlen(s));
    printf("%d\t%d\n",sizeof(s1),strlen(s1));
}
8	11 sizeof(s)为指针s的长度,strlen(s)为字符串的长度
12	11 sizeof(s1)为字符串s1的长度(包含'\0'),strlen(s1)为字符串的长度
  • 2、字符是否可修改
    字符串指针的元素不可以修改
    字符数组的元素可以修改
    char* s = "Hello World";
    char s1[] = "Hello World";
    //*(s+2) = 'L'; //字符串指针不支持修改元素
    s1[2] = 'L'; //字符数组可以修改元素
    printf("%s\n%s\n",s,s1);
//等价
char s[] = "Hello World";
char s[]={'H','e','l','l','o',' ','W','o','r','l','d','\0'};
//等价
char* s = "Hello World";
const char t[]="Hello World"; //看作const型,所以无法修改元素
char* s = t;
  • 3、地址是否可修改
    字符串指针内容可以整体修改
    字符串数组内容无法整体修改
#include <stdio.h>
#include <string.h>
int main(){
    char* p = "Hello";
    char s[] = "Hello";
    p = "World"; //可以修改
    // s = "World"; //无法修改
    printf("%s\n%s\n",p,s);
}
  • 字符串指针和字符数组如何选择
    1、如果需要构造字符串使用数组;如果需要处理字符串使用指针(指向字符数组的指针)。
    2、字符串不需要修改,使用字符串字面量初始化字符串指针。
    3、字符串需要修,改使用字符串字面量初始化字符数组。

3.5 字符串const

  • const字符数组
  • 指向const字符是数组的字符串指针
#include <stdio.h>
#include <string.h>
int main(){
    const char s[] = "Hello World";
    //s[0] = 'h'; //不可修改
    //s[6] = 'w';
    char* p = s;
    printf("%s\n%s\n",s,p);
    *(p+6) = 'w'; //可修改
    *p = 'h';
    printf("%s\n%s\n",s,p); //s和p均被修改
}
Hello World
Hello World
hello world
hello world

结论:决定能否修改的是指针指向的值能否修改,const的限制只针对对应为const的变量。

3.6 字符串函数

  • 字符串比较 strcmp
int strcmp(const char* s1,const char* s2)

s1>s2,返回值>0;
s1<s2,返回值<0;
s1==s2,返回值为0.

  • 字符串拷贝 strcpy
char* strcpy(char* restrict dst,const char* restrict src);

返回值为dst

#include <stdio.h>
#include <string.h>

int main(){
    char dst[3] = "cd";
    const char* src = "ab";
    char* res  = strcpy(dst,src);
    printf("%s\t%s\n",dst,res);
    printf("%p\t%p\n",dst,res);
}
ab	ab
0x7ffd7f72fbbd	0x7ffd7f72fbbd
#include <stdio.h>
#include <string.h>

int main(){
    char dst[3] = "cd";
    const char* src = "ab";
    strcpy(dst,src);
    printf("%s\n",dst);
}  
ab
  • 字符串拼接 strcat
#include <stdio.h>
#include <string.h>

int main(){
    char* a = "hello";
    const char* b = "world";
    char res[11];
    strcat(strcat(res,a),b);
    printf("%s\n",res);
}

strcpy和strcat都会有安全问题:dst空间不足,出现越界。

  • 字符查找
#include <stdio.h>
#include <string.h>

int main(){
    const char* s1 = "abcdef";
    const char* s2 = "cd";
    char* c = strstr(s1,s2);
    printf("%s\n",c);
    printf("%p\t%p\n",c,s1+2);
}
cdef
0x40072a	0x40072a

返回地址为s2在s1中首次出现的地址

3.7 空字符串

#include <stdio.h>
#include <string.h>
int main(){
    char str[10] = "";
    char str2[] = "";
    printf("%d\t%d\n",strlen(str),strlen(str2));
    printf("%d\t%d\n",sizeof(str),sizeof(str2));
    // char* str3; //错误,使用未初始化的char*,若指针定义时候无法确定初始值,使用NULL初始化指针
    // printf("%s\n",str3);
}
0	0
10	1
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值