当前位置:网站首页>C语言_字符串与指针的爱恨情仇

C语言_字符串与指针的爱恨情仇

2022-06-24 06:55:00 踏过山河,踏过海

引言_难点前的小基础

1.字符串常量

10是数值常量,“hello world"是字符串常量
①对于数值常量,编译器不会分配内存,所以也不能够取地址.
即:printf(”%d\n",&(10));是错误的
②对于字符串常量,编译器会分配内存
并且这块内存从程序执行之前创建,到程序结束之后销毁
字符串不可修改,编译器给字符串常量分配的是只读内存.
即printf(“%d\n”,&“abc”);是正确的

2.定义可修改的字符串

char s[]="hello world";//s可修改,因为是把字符串拷贝到自己空间就可读可写了
s[0]='H';

①编译器看到双引号括起来的字符串,那么就会为该字符串分配只读内存,并且字符串常量一直都会存在.
②将字符串常量从只读内存中拷贝到字符串数组中.
③s字符串数组是可读可写,"hello world"字符串常量只读

3.定义不可修改的字符串(不能修改值,只能修改指向)

char *s ="hello world";
printf("%s\n",s);

字符串常量只是代表一个地址.
从我们的角度来看,这个地方写的只是一个字符串.
从编译器的角度,这个地方只是放了一个字符串的地址.

结论1

c语言的字符串都认为是char* 类型的

补充:相同字符串,指向的是同一段内存

char *s1 = "abc";
char *s2 = "abc";

图解如下:

在这里插入图片描述

结论2

char*字符串只能通过修改指向的方式修改值

函数指针

char * my_bussinese(){
    
    char s[]="hello world";
    return s;
}
char * my_logic(){
    
    char * s ="hello world";
    return s;
}
void main(){
    
    char *s1=my_bussinese();
    char *s2=my_logic();
    printf("s1=%s\n",s1);  ====>输出 s1=烫烫烫烫
    printf("s2=%s\n",s2);  ====>输出 s2=hello world
}

s1错误输出的原因:内存释放后,无论里面存的值是否正确都必须停止使用

my_businese图解如下:

在这里插入图片描述

my_logic图解如下:
在这里插入图片描述

关于多级指针

一级指针存放的是变量的地址.
二级指针存放的是一级指针的地址.(实际上,在工作学习中,最多用到二级指针)
三级指针存放的是二级指针的地址.

eg:

int a=10;
int *p1=&a;
int* *p2=&p1;
int** *p3=&p2;

图解如下:

在这里插入图片描述

️修改一级指针的指向

方法一:直接修改地址

int a=10;
int b=20;
int *pa = &a;
pa = &b;//此时,*pa的值已经修改为20

方法二:二级指针间接修改

int a=10;
int b=20;
int *pa = &a;
int **ppa=&pa;
*ppa =&b;//此时,*pa的值已经修改为20
//============> *ppa是对ppa进行了一次解引,找出来ppa里面放的地址,就是pa的地址, 即*ppa相当于pa 

二级指针函数

void pointer_to_string(char **s){
    
    *s="hello world";//s是二级指针,*s解引了一次,表示拿到s里面存放的地址
    //**s表示解引了二次,找到p里面的地址(null的地址还为null)
}
void test02(){
    
    char *p=nullptr;
    pointer_to_string(&p);//一级指针的地址是二级指针,二级指针存放的是一级指针的地址
    printf("p=%s\n",p);
}
void main(){
    
    test02();
}

图解如下:

在这里插入图片描述

指针数组

void print_string(char **ns,int len){
    
    for(int i=0;i<len;i++){
    
        printf("%s\n",ns[i]);//操作数组用下标
    }
}
void test03(){
    
    char *names[]={
    "Trump","Obama","Smith"};
    print_string(names,3);
}
void main(){
    
    test03();
}

指针例题练习

void main(){
    
    char *p,*q;
    p=(char*)malloc (sizeof(char)*20);
    q=p;
    scanf("%s%s",p,q);//假设输入abc def
    printf("%s%s\n",p,q);//输出的是defdef
}
//在最开始的引言部分中,我们说同一个字符串常量,指针指向的同一块位置,
//这里,p和q都指向的是同一段空串空间,所以后输入的def将abc覆盖了.

🧭用指针实现字符串拷贝

void copy_string(char *dst,char *src){
    
    if(nullptr==dst){
    printf("dst指针为空.\n");return;}
    if(nullptr==src){
    printf("src指针为空.\n");return;}
    char *s =src;//新指针与src共同指向"hello world"
    while(*s != '\0'){
    
        *dst = *s;//因为数组指向的是数组元素的首地址,
        //解引一次后指向的是第一个元素,故只能一个元素一个元素的拷贝
        ++s;
        ++dst;
    }
    *dst = *s;//将s最后的字符\0拷贝到目标空间
}
void test(){
    
    char *src="hello world";//源字符串
    char dst[128]={
    0};//定义目标字符串
    copy_string(dst,src);//拷贝字符串
    printf("dst = %s \n",dst);//输出拷贝完成的字符串
}
void main(){
    
    test();
}
原网站

版权声明
本文为[踏过山河,踏过海]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_52668597/article/details/125419326