C语言字符串拷贝

C语言里定义一个字符串可以使用指针也可以使用数组,如:
(1) char *s="hello"; //"hello"是字符串常量s是指向常量的指针,常量是不允许改变的,不能写成s[0]=X,但可以改变指针的值,使其指向不同的常量,如 s = "Xeron";
(2) char s[]="hello"; //指针常量,s本身的值不能修改,但可以修改其指向的内容,s[0]=X
两者的区别是
(1)定义的字符串在程序里不能被修改,因为它存放在代码段内
(2)定义的字符串可被修改,它存放在数据段或者栈内。

这两种定义字符串的方法在函数内部和外部稍有区别

*函数外部:
(1) char *s="hello"; /*定义了指针s(数据段)和常量字符串"hello"(数据段),s的值为字符串首地址*/
(2) char s[]="hello"; /*定义了字符数组s,数组内容为"hello"(代码段),注意这里s只是一个符号而不是变量实体*/

*函数内部:
如果在函数内部使用(1),(2)定义,则"hello"字符串本身存放在代码段,当函数被调用时,
(1) 仅把字符串"hello"的首地址地址赋给s
(2) 把字符串"hello"拷贝一份放到栈内,把拷贝串的首地址赋给s

所以(1)中s所指的内容不能改变,而(2)中s所指的串可修改,s指向的是"hello"串的拷贝,不会影响原串,每次调用函数的时候都拷贝一次

注:在函数内部使用(1)(2)是没有加static关键字修饰的,如果加了static关键字,那就跟在函数外部没什么区别了.
******************************
(1)稍加改变就能满足"hello"串可修改
char *s = (char []){"hello"}; //好像不可行
此时匿名"hello"串存放在数据段。
也可以给定义一个匿名数组赋给int型指针,如:
int *p=(int [10]){[0 ... 9]=0};

----------------------------------------------------------------------------------------

malloc()和free()的基本概念以及基本用法:

1、函数原型及说明:

void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一

个空指针(NULL)。

关于分配失败的原因,应该有多种,比如说空间不足就是一种。

void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,

让它重新得到自由。

2、函数的用法:

     其实这两个函数用起来倒不是很难,也就是malloc()之后觉得用够了就甩了它把它给free()了,举个简单例子:
程序代码:
        // Code...
        char *Ptr = NULL;
        Ptr = (char *)malloc(100 * sizeof(char));
        if (NULL == Ptr)
    {
        exit (1);
    }
        gets(Ptr);

        // code...
        free(Ptr);
        Ptr = NULL;
        // code.

代码如下:
        #include<stdio.h>
        void str_copy(char *from,char  *to);
        main()
        {    char *a="I am chinese!";
             char aa[20]="sssssssssssssssssss";  
             char * b;
             b=aa;
             str_copy(a,b);
             printf("字符串拷贝后:\n");
             printf("%s",aa);         //或者  printf("%s",b);        都成功!!
             printf("\n");
         }
        void str_copy(char *from,char *to)
        {
              while(*to++ = *from++);

            }
但是我改为一下代码,却出现了段错误:
        #include<stdio.h>
        void str_copy(char *from,char  *to);
        main()
        {    char *a="I am chinese!";   //对指针变量直接赋值是可以的。这时初始化指针时所创建的字符串常量被定义为只读。即*a内容不能变
             char *b="ssssssssssssssssssssss";  //对指针变量直接赋值是可以的。这时初始化指针时所创建的字符串常量被定义为只读。即*b内容不能变
             str_copy(a,b);
             printf("字符串拷贝后:\n");
             printf("%s",b);
             printf("\n");
         }
        void str_copy(char *from,char *to)
        {
              while(*to++ = *from++);

            }

  所谓段错误就是一般指指针未赋值,就是所谓的野指针,但是这种char *b="ssssssssssssssssssssss";字符串定义不是给b分配了指向数组的地址了吗?为什么会出现这种情况呢?

#include "stdafx.h"
char *strcpy_v1(char *dest , const char *src)
{
    //调试时,使用断言,入口检测
    assert( (dest!=NULL) && (src!=NULL) );
    
    //注意这里的内存指向参数dest所在的内存,不是栈内存,因而可以在函数中返回
    char *to = dest;
    
    //主要操作在while条件中完成
    while( (*dest++ = *src++)!='\0')       //判断是否赋值是'\0'
    {
        NULL;    
    }
    
    //返回拷贝字符串首地址,方便连缀,比如strlen(strcpy(dest,"hello"))
    return to;
}

/*
 * 说明:字符串拷贝版本2
 * 参数:dest目标地址,src源地址
 * 返回:返回拷贝好的地址;如果出错,无定义
 * 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。
 */
char *strcpy_v2(char *dest , const char *src)
{
    char *d = dest;
    char c;
    
    while((c=*src++) != '\0')
    {
        *(dest++)=c;
    }
    
    *dest='\0';
    
    return d;
}

/*
 * 说明:字符串拷贝版本2(你能找出错误的原因吗)
 * 参数:dest目标地址,src源地址
 * 返回:返回拷贝好的地址;如果出错,无定义
 * 异常:可能出现字符串溢出,及dest所占空间不如src所占空间大。
 */

原文地址:https://www.cnblogs.com/renyuan/p/2724389.html