zoukankan      html  css  js  c++  java
  • c/c++面试题(4)字符串翻转/打印任意进制格式/类型转换

    1.字符串的翻转,这里一般是字符数组.不包括字符串字面值.

       char* reversal_str(char* str,size_t size);

       翻转之后的字符串是原来的字符串的翻转.

     

    #include <stdio.h>
    #include <string.h>
    char* reversal(char* str,size_t len)
    {
        if(str != NULL)
        {
            char* start =  str;
            char* end   = str + len - 1;
            char ch;
            while(start < end) //注意这里的条件不能是start != end;因为大小如果是偶数的话,它们永远不会相等.
            {
                ch = *start;
                *start++ = *end;
                *end-- = ch;
            }
        }
        return str;
    }
    int main(void)
    {
        char str[] = "abcdefg";
        size_t len = strlen(str);
        reversal(str,len);
        printf("%s
    ",str);
        return 0;
    }

    这里有一定的局限性,因为这样只能是在原来的地址上进行字符串的翻转;如果是字符串字面值的情况,其就不能在原来的地址上

    进行翻转.下面给出一个更一般的实现,不过它的思想不是在原来的字符串的地址上进行修改,而是重新分配了一块内存来进行

    字符串的翻转;它的思想是得到一个原来的字符串的翻转之后的字符串,它返回的结果是一个新的地址.

    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    char* reversal_str(char* const dest,const char* src,size_t len)
    {
        assert(dest != NULL && src != NULL);
        char* start = dest;
        char*   end = dest + len - 1;
        char ch;
        strcpy(dest,src);//把它拷贝到dest内存中.
        while(start < end) //注意这里不能写成start != end;
        {
            ch = *start;      //交换首尾字符
            *start++ = *end;
            *end-- = ch;
        }
        return dest;
    }
    
    int main(void)
    {
        char *str1 = "abcdefg";
        char str2[] = "1234567";
        char str[100] = {};
        size_t len = strlen(str1);
        reversal_str(str,str1,len);
        printf("%s
    ",str);
        len = strlen(str2);
        reversal_str(str,str2,len);
        printf("%s
    ",str);
        return 0;
    }

    2.写一个函数,由用户输入一个十进制数和它想要打印这个数的进制数.函数的功能是把这个十进制

      数按照用户的要求打印出来,例如如果用户输入一个数100并且想要的进制是16进制则打印的结果是

      64;如果是100,进制要求是8,则结果是144

    算法分析:

    主要是先对进制求余数,然后是再除于这个base,直到num/base==0为止.

    然后再反向打印即可.

    #include <stdio.h>
    
    void shift_base(int num,size_t base)
    {
        int arr[32] = {},i = 0;
        do
        {
            arr[i++] = num % base;
        }while(num /= base);
        printf("它的%d进制的格式是:
    ",base);
        for(num = i - 1;num >= 0;num--)
            arr[num] < 10?printf("%d",arr[num]):
                printf("%c",arr[num]-10+'A');
        printf("
    ");
    }
    int main(void)
    {
        int num = 0;
        size_t base = 0;
        printf("请输入一个整数:");
        scanf("%d",&num);
        printf("你输入你要打印的进制数:");
        scanf("%d",&base);
        shift_base(num,base);
        return 0;
    }

    3.设计一个函数,求1! + 2! + 3! + 100!的阶乘之和!

      这个题有很多中解法,但是这里有一个巧用static的诀窍,我感觉很强大.

      在这里和大家分享下.

    #include <stdio.h>
    
    long factial(int n)
    {
        static long fac = 1;
        int i = 0;
        fac *= n;
        return fac;
    }
    long sum_fac(int n)
    {
        int i;
        static long sum = 0;
        for(i = 1;i <= n;i++)
        {
            sum += factial(i);
        }
        return sum;
    }
    int main(void)
    {
        int n;
        printf("请输入你要求的阶乘数:");
        scanf("%d",&n);
        printf("1!+2!+...%d! = %ld
    ",n,sum_fac(n));
        return 0;
    }

    4.类型转换问题?先看题

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int main(void)
    {
        float a = 1.0f;
        cout << (int)a << endl;
        cout << &a << endl;
        cout << (int&)a << endl;
        cout << boolalpha << ((int)a == (int&)a) << endl;
        float b = 0.0f;
        cout << (int)b << endl;
        cout << &b << endl;
        cout << (int&)b << endl;
        cout << boolalpha << ((int)b == (int&)b) << endl;
        return 0;
    }

    1)(int)a这里注意它和*(int*)&a是不同的,(int)a这里是相当于是取浮点数a的整数部分

       所以结果是1.

    2)&a打印的是a的地址.

    3)(int&)a这里要注意了,这里相当于是打印*(int*)&a;这里的结果肯定不是1了,因为这里

       相当于把地址&a里面的内容由浮点类型解释成一个整型输出了,因为float和整型的存

       储的方式不同,所以打印的结果不是1.

    4)根据上面的分析这里的打印结果是false;

    5)由于0.0比较特殊,所以后面的打印结果是0,b的地址,0和true.

    5.int和char以及char*之间的转换问题?

     下面程序的打印结果.

    #include <stdio.h>
    int main(void)
    {
        unsigned int a  = 0xFFFFFFF7;
        unsigned char i = (unsigned char)a; 
        char* b = (char*)&a; 
        printf("%08x,%08x
    ",i,*b);
        return 0;
    }

    分析:

    把一个unsigned int 赋值给unsigned char的时候高字节会被截断,只留下低8位.

    即f7,打印的时候又是以整型数打印的所以结果是000000f7;

    而char* b = (char*)&a;这里向当于让b指向了a的地址,但是a的内容并没有变化,

    最后打印的时候又是按整型打印的所以结果是fffffff7;

    6.用一个表达式,判断一个数X是否是2的N次方(2,4,8,16,...),不能使用循环语句.

      分析:2的n次方就说明这个数的二进制表示只有一个1,如果这个数减去1之后,

      则其前面的其他位的结果都是1.所以如果x&(x-1)的结果是0就表示它是2的N

    次方.所以可以写成下面的表达式 !(X&(X-1)) 如果返回1表示它是,否则不是.

    7.下面代码的结果

     

    int  fun(int x,int y)
    {
               return (x&y) + ((x^y)>>1)   
    }
    fun(144,296) = _____________?

    这里主要考察一种整型数据的用位于求表达式的问题.

    (x&y)相于表示的是x和y相同位的一半.(主要是有1的位)

    (x^y)表示的是(x和y)不同位的值,右移一位相当于除以2.(主要是一个是1一个是0的位)

    因为用二进制求数,其实我们关注的是位数是1的地方,其他是0的地方只是在填位.

      

  • 相关阅读:
    C#使用Oracle.ManagedDataAccess.dll
    C#调用webservice
    “认证发布”和“获取展示”,如何在 SharePoint 中正确使用 RSS Feed。
    不怕你配置不会,就怕你看的资料不对!MIM 与 SharePoint 同步完全配置指南。
    SharePoint Server 2013 安装篇
    打印机服务不能正常启动
    JAVA课程体系
    学习网
    Oracle Database 11g安装教程
    方法重载
  • 原文地址:https://www.cnblogs.com/yasanlun/p/3838111.html
Copyright © 2011-2022 走看看