C语言常用库函数实现

1.memcpy函数

memcpy 函数用于 把资源内存(src所指向的内存区域) 拷贝到目标内存(dest所指向的内存区域);拷贝多少个?有一个size变量控制拷贝的字节数;

函数原型:void *memcpy(void *dest, void *src, unsigned int count);

用法:可以拷贝任何类型的对象,因为函数的参数类型是void*(未定义类型指针),也就是说传进去的实参可以是int*,short*,char*等等,但是由于函数拷贝的过程是一个字节一个字节的拷贝的,所以实际操作的时候要把void*强制转化为char*,这样在指针加的时候才会保证每次加一个字节;

#include <stdio.h>
#include <iostream>
#include <assert.h>

using namespace std;

/********memcpy()函数原型为:void* memcpy(void* dest, void* src, size_t n); 返回指向dest的空类型指针*********/
//返回void* 类型的原因,是为了使用链式表达,即strlen((char*)(memcpy(dest,src,n)),这样可以直接计算dest的长度,是程序代码更简洁
/****注意void* 指针的使用,即该函数允许传入任何类型的指针数据****/
void* memcpy(void *dest, void *src, size_t n)
{
    assert((dest != NULL) && (src != NULL));
    char *dest_t = (char*)dest;                  //转换成字符型一个个复制拷贝,由于函数拷贝的过程是一个字节一个字节的拷贝的,
                                                 //所以实际操作的时候要把void*强制转化为char*,
    char *src_f = (char*)src;                    //这样在指针加的时候才会保证每次加一个字节
    while (n-- > 0)
    {
        *(dest_t++) = *(src_f++);
    }
    return dest;//void* 一定要返回一个值(指针),这个和void不太一样!函数返回指向dest的指针

}

int main()
{
    int a[5] = { 0, 1, 2 };
    int *b = new int[3];
    void *c = memcpy(b, a, 3 * sizeof(int));  //sizeof()可以用类型做参数,也可以传入实际的变量
    for (int i = 0; i < 3; i++)            //数组做参数时,不退化为指针,统计的是数组整体占据的内存
    {
        cout << b[i] << endl;
    }
    int *temp = (int*)c;
    temp++;
    cout << endl;
    cout << *temp << endl;
    return 0;
}

注1:与strcpy相比,memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。

    2:如果目标数组dest本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。

//memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;

  char a[100], b[50];

  memcpy(b, a,sizeof(b)); //注意如用sizeof(a),会造成b的内存地址溢出。

  strcpy就只能拷贝字符串了,它遇到'\0'就结束拷贝;例:

  char a[100], b[50];

      strcpy(a,b);

2.strcpy函数

#include <stdio.h>
#include <iostream>

using namespace std;

/********strcpy()函数原型为:char *strcpy(char* dest, const char *src); 返回指向dest的指针*********/
//返回char* 类型的原因,是为了使用链式表达,即strlen(strcpy(dest,src)),这样可以直接计算dest的长度,是程序代码更简洁

char* strcpy(char *dest, char *src)
{
    if(dest == NULL || src == NULL)
        return NULL;
    char *res = dest;//保存原始dst的首地址
    while(*src != '\0')
    {
        *dest = *src;
        dest++;
        src++;
    }
    *dest = '\0';
    return res;
}

int main()
{
    char *src = "hello world";
    char *dest = new char;
    //strcpy(dest,src);
    int len = strlen(strcpy(dest,src));
    cout << len << endl;
    cout << dest << endl;
    return 0;
}

 3.strcat函数

功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')。

说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。

#include <stdio.h>
#include <iostream>

using namespace std;

char* strcat(char *dest, char *src)
{
    if (dest == NULL)
        return NULL;
    if (src == NULL)
        return dest;
    char *head = dest;
    while (*dest != '\0')
        dest++;
    while (*src != '\0')
    {
        *dest = *src;
        dest++;
        src++;
    }
    *dest = '\0';
    return head;
}


int main()
{
    char dest[] = "nihao";
    char src[] = "zhouyang";
    char *res = strcat(dest, src);
    cout << dest << endl;
    system("pause");
    return 0;
}

4.strcmp函数

功能:比较两个字符串大小。

实际上是对字符的ASCII码进行比较,实现原理如下:首先比较两个串的第一个字符,若不相等,则停止比较并得出两个ASCII码大小比较的结果;如果相等就接着比较第二个字符然后第三个字符等等。无论两个字符串是什么样,strcmp函数最多比较到其中一个字符串遇到结束符'/0'为止,就能得出结果。

返回结果:①str1小于str2,返回负值或者-1(VC返回-1);②str1等于str2,返回0;③str1大于str2,返回正值或者1(VC返回1);

#include <stdio.h>
#include <iostream>
#include <assert.h>

using namespace std;

/****strcmp原型: int strcmp(const char *str1, const char *str2)*****/
int strcmp(const char *str1, const char *str2)
{
    assert((str1 != NULL) && (str2 != NULL));
    while ((*str1 != '\0') && (*str2 != '\0'))
    {
        if (*str1 == *str2)
        {
            str1++;
            str2++;
        }
        else
        {
            if (*str1 > *str2)
                return 1;
            else
                return -1;
        }
    }
    if (*str1 == '\0' && *str2 == '\0')
        return 0;
    else if (*str1 == '\0' && *str2 != '\0')
        return -1;
    else if (*str1 != '\0' && *str2 == '\0')
        return 1;
}

int main()
{
    char *str1 = "78";
    char *str2 = "789";
    int res = strcmp(str1, str2);
    cout << res << endl;
    system("pause");
    return 0;
}

5.strlen函数

功能:返回字符串的长度。

#include <stdio.h>
#include <iostream>
#include <assert.h>


using namespace std;

/********strlen()函数原型为:int strlen(const char *src); 返回字符串的长度*********/
size_t strlen(const char *str)
{
    assert(str != NULL);
    int num = 0;
    while(*str != '\0')
    {
        str++;
        num++;
    }
    return num;
}

int main()
{
    char *str = "123456";
    int temp = strlen(str);
    cout << temp << endl;
    return 0;
}

6.strncpy

功能:将字符串src中最多n个字符复制到字符数组dest中(它并不像strcpy一样遇到NULL才停止复制,而是等凑够n个字符才开始复制),返回指向dest的指针。

要求:如果n > dest串长度,dest栈空间溢出产生崩溃异常。该函数注意的地方和strcpy类似,但是n值需特别注意。

#include <iostream>
#include <stdio.h>

using namespace std;

/***string.h,char *strncpy(char *dest, const char *src, size_t n),
把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回dest。**/
char* mystrncpy(char *dest, const char *src, size_t n)
{
    if (dest == NULL || src == NULL || n < 0)
        return NULL;
    char *res = dest;
    while (n--)
    {
        *dest = *src;
        dest++;
        src++;
    }
    *dest = '\0';
    return res;
}

int main()
{
    char *src = "hello world";
    char c[10];
    char *res = mystrncpy(c, src, 7);
    cout << res << endl;
    system("pause");
    return 0;

}

 7.strstr函数

功能:给出字符串str1, str2,判断str2是否为str1的子字符串,如果是,返回str2在str1中对应的起始地址。

#include <stdio.h>
#include <iostream>
#include <assert.h>

using namespace std;

/****
函数原型:
extern char *strstr(const char *str1, const char *str2);

str1: 被查找目标 string expression to search.
str2: 要查找对象 The string expression to find.
返回值:若str2是str1的子串,则返回str2在str1的首次出现的地址;如果str2不是str1的子串,则返回NULL。
****/

const char* strstr(const char *str1, const char *str2)
{
    if (str1== NULL || str2 == NULL)
        return NULL;
    const char *temp = str1;
    const char *res = str2;while (*str1 != '\0')
    {
        temp = str1;
        res = str2;
        while (*temp== *res){
            temp++;
            res++;
        }
        if (*res == '\0')return str1;
        str1++;

    }
    return NULL;

}
int main()
{
    char *src = "1234567";
    char *dest = "345";
    const char *res = strstr(src, dest);
    cout << res<< endl;//cout<<重载了,会直接输出字符串内容而不是地址
    system("pause");
    return 0;
}

 

posted @ 2018-08-20 23:55  追逐更好的自己  阅读(5013)  评论(0编辑  收藏  举报