C语言关于字符串和字符数组的转化问题

C语言关于字符串和字符数组的转化问题

小菜鸡CS本科生一枚,第一次写博客,如果有什么写的不对或者不好的欢迎大家批评指正,
写这篇博客的原因是我今天遇到的一道题,题目很简单,leetcode中等难度,可是这道题却困扰了我整整一天,连上课都没好好听讲,无论如何也想不出个所以然。之所以我被困扰了这么久,就是因为字符数组转化字符串的小细节。下面我们进入正题:

要把字符串转化为字符数组是很简单的,有手就行,在这里就不讨论也不解释了,代码如下:

int main()
{
    char *str1="numstr";
    char num1[strlen(str1)];
    int i;
    for(i=0;i<strlen(str1);i++)//strlen是求字符串长度的函数,需要string.h头文件
    {                          //它返回的是字符串除0之前的字符数目
        num1[i]=str1[i];
        printf("%c",num1[i]);
    }
    return 0;
}

本文的关键在于如何把字符数组转化为字符字符串,其实也很简单,我们只需要设置一个字符指针,然后给它分配内存就可以了。代码如下:

char *str(char numstr[],int numstrSize)//这里传入一个字符数组,numstrSize是其长度
{
    char *s=malloc((numstrSize+1)*sizeof(char));//定义一个字符指针并给它分配numstrSize+1个内存单元,
    int i;
    for(i=0;i<numstrSize;i++)
    {
        s[i]=numstr[i];
    }
    s[numstrSize]=0;
    return s;//返回一个字符串
}

为什么要分配numstrSize+1个呢,这是因为,字符串是以‘/0’结尾的,0不计入字符串长度,只计入字符数组长度。

那么有萌新会问,可不可以定义一个字符指针,让它直接指向字符数组的首地址呢,这当然是不行的,由于数组名代表数组的首地址,所以如果我们定义一个字符指针直接指向字符数组的话,它其实指向的是字符数组第一个字符的地址,所以这是不行的。

如果我们定义一个字符指针,不分配地址,然后将字符数组中的字符存进去呢,这就更扯淡了,不分配内存的话,它指向哪里呢?所以我也想过让它指向另一个和我们需求一样长度的字符串,然后修改字符串里面的字符,让字符串里面的字符被修改为字符数组里的字符,这样可不可以呢?就像这样:

int main()
{
    char numstr[6]={76,77,78,79,80,81};
    char *st="hello!";
    int i;
    for(i=0;i<6;i++)
    {
        st[i]=numstr[i];
    }
    printf("%s\n",st);
    return 0;
}

答案是不可以。这是为什么呢?因为字符串被保存在只读的常量存储区中,所以不能对字符串直接进行修改。我也正是因为忽略了这一点,所以才迟迟没有弄清楚其中的玄机,而且之前用的很熟的堆内存分配函数也没被我想起来,这就直接导致了我整整一天都被搞得一头雾水,那种很迷糊的感觉,萌新们应该深有体会吧。

最后给大家隆重介绍一下堆内存分配函数

堆内存分配函数的用法:
用法:指针名=(数据类型*)malloc(要申请内存空间的数量*要申请内存空间的字节长度)。如果不声明要申请内存空间数目的话,则默认只申请一个内存空间。

malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* 类型。void* 表示未确定类型的指针。malloc()函数其实就在内存中找一片指定大小的空间,然后将这个空间的首地址范围给一个指针变量,这里的指针变量可以是一个单独的指针,也可以是一个数组的首地址,这要看malloc()函数中参数size的具体内容。

头文件:#include 有些编译器需要#include ,在TC2.0中可以使用alloc.h头文件。
类似函数:calloc函数、realloc函数、free函数。

总结:我只说最重要的两点,1是堆内存分配函数,2是字符串不能直接被修改,注意这里的直接,我觉得我这个直接还是用的很妙的,好啦,我的经历就分享到这里吧,第一次写博客,这好吗,这很好。

你可能感兴趣的:(c语言,字符串)