C语言面试题整理

strcpy

char *strcpy(char *strDest, const char *strSrc)
{
    assert((strDest != NULL) && (strSrc != NULL));
    char *address = strDest;
    while((*strDest++ = *strSrc++) != '\0')
        NULL;
    return address;
}
// strcpy 能把strSrc的内容复制到strDest,为什么还要char *类型的返回值?
// 为了实现链表表达式

二分查找法

int binary_search(int* arr, int key, int n)
{
    int left = 0;
    int right = n - 1;
    int mid;
    while(left <= right)
    {
        mid = (left + right)/2;
        if(arr[mid] > k)
            right = mid -1;
        else if(arr[mid] < k)
            left = mid + 1;
        else
            return mid;
    }
    return -1;
}

给出一个字节中被置1的位的个数

unsigned int TestAsOne0(char log)
{
    int i;
    unsigned int num = 0, val;
    for(i = 0; i < 8; i++){ // 一个字节八位
        val = log >> i;
        val &= 0x01;
        if(val)
            num++;
    }
    return num;
}

字符串转换成整数

int Invert(char *str)
{
    int num = 0;
    while(*str != '\0')
    {
        int digital = *str - 48;
        num = num * 10 + digital;
        str = str + 1;
    }
    return num;
}

整数转换成字符串

// 1
void intToString(int num, char* str) {
    sprintf(str, "%d", num);
}

// 2
void reverseString(char* str) {
    int len = 0;
    while (str[len] != '\0') {
        len++;
    }

    int i = 0;
    int j = len - 1;
    while (i < j) {
        char temp = str[i];
        str[i] = str[j];
        str[j] = temp;
        i++;
        j--;
    }
}

void intToString(int num, char* str) {
    int i = 0;
    int sign = 0;

    if (num < 0) {
        sign = 1;
        num = -num;
    }

    if (num == 0) {
        str[i++] = '0';
    }

    while (num > 0) {
        int digit = num % 10;
        str[i++] = digit + '0';
        num = num / 10;
    }

    if (sign) {
        str[i++] = '-';
    }

    str[i] = '\0';

    reverseString(str);
}

实现strcmp函数

int mystrcmp(const char* str1, const char* str2)
{
    assert((str1 != NULL) && (str2 != NULL));
    int ret = 0;
    // 只有在当前位置字符相等且 str2 还未到达字符串结尾时,循环才会继续执行。
    while(!(ret = *(unsigned char*)str1 - *(unsigned char*)str2) && *str2)
    {
        str1++;
        str2++;
    }
    
    if (ret > 0)
        ret = 1;
    else if (ret < 0)
        ret = -1;
    return ret;
}

在给定区域搜索给定的字符,并返回该字符所在位置的索引值

int search(char *cpSource, int n, char ch) // 起始地址-搜索长度-目标字符
{
    int i;
    for(i = 0; i < n && *(cpSource + i)!=ch; ++i);
    return i;
}

在一个字符串中找到最长的子字符串,该字符串是由同一字符组成的

int ChildString(char *p)
{
    char *q = p;
    int stringlen=0, i = 0, j = 1, len = 0, maxlen = 1;
    while(*q!='\0')
    {
        Stringlen++;
        q++;
    }
    while(i < Stringlen)
    {
        if(*(p + i) == *(p + j) && j < Stringlen)
        {
            len++;
            i++;
            j++;
        }else{
            if(len > maxlen)
            {
                maxlen = len + 1;
                len = 0;
            }else{
                len = 0;
            }
            i++;
            j++;
        }
    }
    return maxlen;
}

怎么判断链表中是否有环?

// 用两个指针来遍历这个单向链表,第一个指针p1,每次走一步;第二个指针p2,每次走两步;当p2指针追上p1的时候,就表明链表当中有环路了。
int testLinkRing(LinkNode* head)
{
    LinkNode* t1 = head, *t2 = head;
    while(t1 -> next && t2 -> next)
    {
        t1 = t1->next; // 走一步
        if(NULL == (t2 = t2->next->next)) // 走两步
            return 0;
        if(t1 == t2)
            return 1;
    }
    return 0;
}

冒泡:对浮点数组A进行降序排序

void Bubble(double arr[], int n)
{
    int exchange = 1; // 交换标志位
    for(int i = 0; i < n; i++) 
    {
        exchange = 0; 
        for(j = 0; j <= n - i - 1; j++)
            if(arr[j] < arr[j+1])
            {
                double temp = arr[j]
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                exchange = 1; 
            }
        if(!exchange) 
            return;
    }
}

双向链表删除一个节点P,在节点P后插入一个节点

// 删除操作




// 插入操作

反转链表

class Solution{
public:
    ListNode * reverse(ListNode* head)
	{
        ListNode* dummyHead = head;
    	ListNode* pre = head;
    	ListNode* cur = head->next;
        
	}
    
};

将二维数组行列元素互换,存到另一个数组中

#include <stdio.h>
int main(){
    int a[2][3] = {{1,2,3},{4,5,6}};
    int b[3][2],i,j;
    printf("array a:\n");
    for(i=0; i<=1; i++)
    {
        for(j = 0; j <= 2; j++)
        {
            printf("%5d",a[i][j]);
            b[j][i] = a[i][j];
        }
        printf("\n");
    }
    printf("array b:\n");
    for(i = 0; i <= 2; i++)
    {
        for(j = 0; j <= 1; j++)
            printf("%5d", b[i][j]);
        printf("\n");
    }
}

输入一行字符,统计其中有多少个单词

#include <stdio.h>
int main(){
    char string[81];
    int i, num=0, word = 0;
    char c;
    gets(string);
    for(i = 0;  (c = string[i])!='\0'; i++)
    {
        if(c == ' ')//判断当前字符是否为空格
            word = 0;
        else if(word == 0)
        {
            word = 1;
            num++;
        }
    }
    printf("There are %d words in the line\n", num);
}

写一个内存拷贝函数,不用任何库函数

void* memcpy(void* pvTo, const void* pvFrom, size_t size)
{
    assert((pvTo != NULL)&&(pvFrom != NULL));
    byte* pbTo = pvTo;
    byte* pbFrom = pbFrom;
    while(size-- > 0){
        *pbTo++ = *pbFrom++;
    }
    return pvTo;
}

有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?

#include "stdio.h"
#include "conio.h"

int main(){
    int i, j, k;
    printf("\n");
    for(i = 1; i < 5; i++)
        for(j = 1; j < 5; j++)
            for(k = 1; k < 5; k++)
            {
                if(i!k && i!= j && j!=k)
                    printf("%d,%d,%d\n",i,j,k);
            }
    getch();
    return 0;
}

取一个整数a从右端开始的4~7位

int main(){
    unsigned int a = 0x12345678;
    unsigned int b = (a >> 4) & 0xf;
    printf("%x\n", b);
    retrun 0;
}

求一个字符串的长度

#include <stdio.h>

int strlen(char* s) {
    int len = 0;
    while (*s) {
        len++;
        s++;
    }
    return len;
}

int main() {
    char str[100];
    printf("请输入一个字符串:");
    scanf("%s", str);
    int len = strlen(str);
    printf("该字符串的长度为:%d\n", len);
    return 0;
}
    

电话加密:数据是四位的整数,每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换。

void main(){
    int a;
    int i;
    int aa[4];
    int t;
    scanf("%d", &a);
    aa[0] = a%10;
    aa[1] = a%100/10;
    aa[2] = a%1000/100;
    aa[3] = a /1000;
    for(i = 0; i <= 3; i++)
    {
        aa[i] += 5;
        aa[i]% = 10;
    }
    for(i = 0; i < 2; i++)
    {
        t = aa[i];
        aa[i] = aa[3 - i];
        aa[3 - i] = t;
    }
    
    for(i = 3; i >= 0; i--)
        printf("%d", aa[i]);
    getch();
}

计算字符串中子串出现的次数

void main(){
    char str1[20], str2[20], *p1, *p2;
    int sum = 0;
    printf("please input two strings\n");
    scanf("%s%s",str1,str2);
    p1 = str1; 
    p2 = str2;
    while(*p1!='\0')
    {
        if(*p1 == *p2)
        {
            while(*p1 == * p2 && *p2 != '\0')
            {
                p1++;
                p2++;
            }
        }
        else
            p1++;
        if(*p2 == '\0')
            sum++;
        p2 = str2;
    }
    printf("%d",sum);
    getch();
}

求N的阶乘末尾0的个数:刚开始写的是求二进制数末尾的0,比较简单,后来发现是说让求十进制末尾0的个数

// 要求 N 的阶乘末尾 0 的个数,可以思考以下两个方面:
// 阶乘中 0 的个数取决于因子 2 和因子 5 的个数。由于 10 = 2 × 5,所以 10 的阶乘末尾有一个 0。
// 在 N 的阶乘中,因子 2 的个数远多于因子 5 的个数。因此,我们只需要计算阶乘中因子 5 的个数即可。
int countTrailingZeros(int num){
    int count = 0;
    // 阶乘末尾的 0 的个数取决于因子 5 的个数。每隔 5 个数就会出现一个因子 5,每隔 25 个数又会多出一个因子 5,每隔 125 个数又会多出一个因子 5,以此类推。因此,我们需要将这些因子 5 的个数累加起来才能得到最终的结果。
    // 例如,数字 25 本身贡献了两个因子 5(因为它可以分解为 5 × 5),而数字 125 贡献了三个因子 5(因为它可以分解为 5 × 5 × 5)。
    for(int i = 5; num / i >=1; i*=5){
        count += num / i;
    }
    return count;
}

十进制数转换成任意N进制

#include <stdio.h>

void decimalToN(int decimal, int base) {
    if (decimal == 0) {
        printf("Converted number: 0\n");
        return;
    }

    char converted[32];
    int index = 0;

    while (decimal > 0) {
        int remainder = decimal % base;

        if (remainder < 10) {
            converted[index] = remainder + '0';
        } else {
            converted[index] = remainder - 10 + 'A';
        }

        decimal = decimal / base;
        index++;
    }

    printf("Converted number: ");
    for (int i = index - 1; i >= 0; i--) {
        printf("%c", converted[i]);
    }
    printf("\n");
}

int main() {
    int decimal = 123;
    int base = 2;

    decimalToN(decimal, base);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值