[笔试面试题] 7-自定义函数篇

自定义函数篇


1 不使用C/C++字符串库函数,如何自行编写strcpy()函数?

char * strcpy(char *strDest, const char *strSrc)
{
    assert((strDest!=NULL) && (strSrc!=NULL));
    char *address = strDest;
    while( (*strDest++ = *strSrc++) != '\0');
    
    return address ;
}

返回类型为char *主要是为了实现链式表达式。例如:

int length=strlen(strcpy(strDest, "hello world")); 
strcpy(strDest, strcpy(strDest1, strSrc));

可以将strSrc复制到strDest1与strDest中,也就是说,可以将函数的返回值做为另一个函数的参数。


2 如何把数字转换成字符串?

C语言中常用到字符串与数字之间的相互转换,常见的此类库函数有atof (字符串转换成浮点数)、atoi (字符串转换成整型数)、atol (字符串转换成长整型数)、itoa (整型数转换成字符串)、ltoa (长整型数转换为字符串)等。

以自定义Myatoi()与Myitoa()函数为例,分别实现自定义字符串转换为整型数函数与自定义整型数转换为字符串函数。以下为自定义Myatoi()函数的实现以及测试代码:

#include<stdio.h> 

int Myatoi(char *str)
{
    if(str = NULL)
    {
        printf("Invalid Input");        
        return -1;
    }   
    
    while(*str = '') //跳过开头的空格字符
    {
        str++;
    }
    
    //'0xA1'是不打印字符,一般是占两个字节的汉字
    while((*str==(char)0xA1) && (*(str+1)==(char)0xAA))
    {
        str += 2;
    }  
    
    int nSign = (*str = '-')?-1:1;//确定符号位 
    if(*str='+' || *str='-')
    {
        *str++;
    }
    
    int nResult = 0;
    while(*str>='0' && *str<='9')
    {
        nResult = nResult*10 + (*str-0); 
        *str++;
    }
    
    return nResult * nSign;
}

int main()
{
    printf(""%d\n",Myatoi("12345")); 
    return 0;
}

程序输出结果:

12345

以下为自定义Myitoa函数的实现以及测试代码:

#include <stdio.h> 

char *Myitoa(int num)
{
    char str[1024];
    int sign = num,i = 0,j = 0;
    char temp[11];
    //如果为负数,则转换为其绝对值
    if(sign<0)
    {
        num = -num;
    };
    
    //数字转换为倒序的字符数组
    do
    {
        temp[i] = num%10 + '0'; 
        num/=10;
        i++;
    }while(num>0);
    
    //字符数组加上“符号”
    if(sign<0)
    {
        temp[i++] = '-';
    }
    
    //转换为字符串
    temp[i] = '\0';
    
    //将字符串反转
    i—-;
    while(i>=0)
    {
        str[j] = temp[i];
        j++;
        i--;
    }
    str[j] ='\0'; 
    
    return str;
}

int main()
{
    printf("%s\n",Myitoa(-12345)); 
    
    return 0;
}

程序输出结果:

12345


3 将字符串翻转?

#include "stdafx.h"
#include<iostream>

using namespace std;

#define swap(a,b) a=a^b,b=a^b,a=a^b

//将一个字符串翻转  在不使用额外数据结构和储存空间的情况下
//注 只能翻转字符数组,翻转字符指针会导致程序崩溃
char* strRev(char *str)
{
    int len = strlen(str);
    for (int i = 0, j = len - 1; i<j; i++, j--)    //不能是i<=j
        swap(str[i], str[j]);

    return str;
}

int main(void)
{
    char str[6] = "abcde";
    strRev(str);
    cout << str << endl;    //dcba
}

/*
输出结果:

edcba
*/


4 确定字符互斥的两种方法?

#include "stdafx.h"
#include <iostream>
#include <string>
#include <string.h>

using namespace std;

//确定字符互异方法1-通过string实现 (本质都是通过"遍历"实现)
//确定字符互异:确定一个字符串的所有字符是否全都不同。
//True代表所有字符全都不同,False代表存在相同的字符。
class Different {
public:
    bool checkDifferent(string iniString) {
        string str = iniString;
        char c;
        for (unsigned int i = 0; i<str.length(); i++)
        {
            c = str.at(i);
            for (unsigned int j = i + 1; j<str.length(); j++)
            {
                if (c == str.at(j))
                    return false;
            }
        }

        return true;
    }
};

//确定字符互异方法2-通过char*实现 (本质都是通过"遍历"实现)
//确定字符互异:确定一个字符串的所有字符是否全都不同。
//返回1代表所有字符全都不同,返回0代表存在相同的字符。
int check(char *str)
{
    char *t_str = str;

    int len = strlen(str);

    char c;
    int i, j;
    for (i = 0; i<len; i++)
    {
        c = t_str[i];
        for (j = i + 1; j<len; j++)
        {
            if (c == t_str[j])
                return  0;
        }
    }

    return 1;
}


int main(void)
{
    Different temp;
    temp.checkDifferent("abcd") ? cout << "true" << endl : cout << "false" << endl;

    check("abacd") ? cout << "true" << endl : cout << "false" << endl;
}

/*
输出结果:

true
false
*/


5 如何自定义内存复制函数memcpy()?

memcpy是C语言中的内存复制函数,它的函数原型为void *memcpy(void *dest, const void*src, size_t n)。它的目的是将src指向地址为起始地址的连续n个字节的数据复制到以dest指向地址为起始地址的空间内,函数返回指向dest的指针。需要注意的是,src和dest所指内存区域不能重叠,同时,与strcpy相比,memcpy遇到’\0’不结束,而是一定会复制完n个字节。

自定义内存复制函数示例如下:

#include <stdio.h> 
void *MyMemCpy(void *dest, const void *src, size_t count)
{
    char *pdest = static_cast<char*>(dest); 
    const char *psrc = static_cast<const char*>(src); 
    if((pdest>psrc) && (pdest<(psrc+count))) //这种情况:MyMemCpy(str+1, str+0, 9); 
    {
        for(size_t i=count-l; i!=-l; —-i) 
            pdest[i] = psrc[i];
    }
    else
    {
        for(size_t i=0; i<count; ++i) //这种情况:MyMemCpy(str, str+5, 5); 
            pdest[i] = psrc[i];
    }
    
    return dest;
}

int main()
{
    char str[] = "0123456789";
    MyMemCpy(str+1, str+0, 9); 
    printf("%s\n",str);
    MyMemCpy(str, str+5, 5); 
    printf("%s\n",str); 
    
    return 0;
}


6 将整型数倒序?

//将一个整型数字倒序 例12->21 100->1
int fun(int num)
{
    int s = 0;
    while(num)
    {
        s = s*10 +num%10;
        num/=10;
    }

    return s;
}


7 字符串循环右移的2种方法?

#include <iostream>
#include <string.h>

using namespace std;

//循环右移,库函数实现   例如step=2, abcd -> cdab
void loopRightStr(char *str, int step)
{
    char tmp[100];

    int len = strlen(str);
    strcpy(tmp, str + step);   //先复制"abcd"的cd
    strcpy(tmp + step, str);   //再复制"abcd"的ab cd
    *(tmp + len) = '\0';  //使用'\0'来截断,去掉后面的cd\0
    strcpy(str, tmp);   //再将tmp拷贝给str
}

//循环右移,不用库函数实现  例如step=2, abcd -> cdab
void loopRightStr2(char *str, int step)
{
    char tmp[100];

    int len = strlen(str);

    for (int i = 0; i<step; i++)
    {
        tmp[i] = *(str + 2 + i);
    }

    for (int i = step; i<len; i++)
    {
        tmp[i] = *(str - step + i);
    }

    tmp[len] = '\0';

    for (int i = 0; i<len; i++)
        str[i] = tmp[i];    //再将tmp拷贝给str
}

int main(void)
{
    char str[5] = "abcd";
    loopRightStr2(str, 2);
    cout << str << endl;    //cdab
}

/*
输出结果:

cdab
*/


8 判断是否为回文字符串,是回文字符串,返回1,不是返回0?

#include "stdafx.h"
#include <iostream>
#include <string.h>

using namespace std;

int fun(char *str)
{
    int len = strlen(str);

    for (int i = 0, j = len - 1; i<j; i++, j--)
    {
        if (str[i] != str[j])
            return 0;
    }

    return 1;
}

int main(void)
{
    char str[7] = "abcba";  //回文:从左读和从右读都是一样的

    cout << fun(str) << endl;    //cdab
}

/*
输出结果:

1
*/

转载于:https://www.cnblogs.com/linuxAndMcu/p/10143819.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值