• 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所占空间大。
     */

  • 相关阅读:
    学习学习
    论文
    GitHub地址
    数据库测试用例生成系统设计与实现
    PICT的安装及使用
    Junit安装及使用
    使用source monitor检查代码复杂度
    FindBugs安装及使用
    PMD安装及使用
    Checkstyle安装及使用
  • 原文地址:https://www.cnblogs.com/renyuan/p/2724389.html
Copyright © 2020-2023  润新知