比特C语言小练

文章详细介绍了C语言中指针的声明与使用,包括const修饰符对指针和指针解引用的影响。同时,讨论了数组的调整,如将奇数放在偶数前面的算法,以及多种递归实现的数学运算,如阶乘、字符串逆序、斐波那契数等。此外,还涉及到了VS调试快捷键的使用和基本的字符串函数模拟实现。
摘要由CSDN通过智能技术生成

语言中哪一种形式声明了一个指向char类型变量的指针p,p的值不可修改,但p指向的变量值可修改?(C)

A. const char *p

B. char const *p

C. char*const p

D. const char *const p

答案解析:

A:错误,const修饰*p,表示p指向的内容不能修改

B:错误,同上

C:正确,const修饰p本身,表示p的指向不能修改,p指向的空间中内容可以修改

D:错误,第一个const表示p指向的内容不能修改,第二个const表示p不能指向其他变量

以下关于指针的说法,正确的是( C)

A. int *const p与int const *p等价

B. const int *p与int *const p等价

C. const int *p与int const *p等价

D. int *p[10]与int (*p)[10]等价

答案解析:

A:错误,int* const p中,const修饰指针变量p本身,表示p的指向不能改变,

int const *p中,const修饰p指针解引用之后的结果,表示p指向的内容不能改变

因此,不等价

B:错误,同上

C:正确,const都修饰p指针解引用之后的结果,表示p指向的内容不能改变

D:错误,int *p[10]定义了一个指针数组,数组中10个元素,每个元素都是int*类型的指针

int (*p)[10]定义了一个数组指针,该指针只能指向存储10个整形元素的数组

关于VS调试快捷键说法错误的是:(A

A. F5-是开始执行,不调试

B. F10-是逐过程调试,遇到函数不进入函数

C. F11-是逐语句调试,可以观察调试的每个细节

D. F9是设置断点和取消断点

答案解析:

A:错误,F5是开始调试,在遇到短点的位置可以停下来,Ctrl+F5是开始执行,不调试

B:正确,F10遇到函数时不会进入到函数体中,F11会

C:F11遇到函数时,会进入函数中

D:F9会在光标所在行下短点,如果有短点会取消短点

调整奇数偶数顺序

调整数组使奇数全部都位于偶数前面。

输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分

/*思路:
1. 给定两个下标left和right,left放在数组的起始位置,right放在数组中最后一个元素的位置
2. 循环进行一下操作
 a. 如果left和right表示的区间[left, right]有效,进行b,否则结束循环
 b. left从前往后找,找到一个偶数后停止
 c. right从后往前找,找到一个奇数后停止
 d. 如果left和right都找到了对应的数据,则交换,继续a,*/
void swap_arr(int arr[], int sz)
{
    int left = 0;
    int right = sz-1;
    int tmp = 0;
    while(left<right)
    {
     // 从前往后,找到一个偶数,找到后停止
        while((left<right)&&(arr[left]%2==1))
        {
            left++;
        }
        // 从后往前找,找一个奇数,找到后停止
        while((left<right)&& (arr[right]%2==0))
        {
            right--;
        }
     // 如果偶数和奇数都找到,交换这两个数据的位置
     // 然后继续找,直到两个指针相遇
        if(left<right)
        {
            tmp = arr[left];
            arr[left] = arr[right];
            arr[right] = tmp;
        }
    }
}

求阶乘

递归和非递归分别实现求n的阶乘(不考虑溢出的问题)

/*
Fac(N) = 1*2*3*……*N
递归方式实现:
        1    N <= 1
Fac(N)
        Fac(N-1)*N    N >= 2
*/
long long Fac(int N)
{
    if(N <= 1)
        return 1;
    
    return Fac(N-1)*N;
}
/*
循环方式:从1乘到N即可
*/
long long Fac(int N)
{
    long long ret = 1;
    for(int i = 2; i <= N; ++i)
    {
        ret *= i;
    }
    return ret;
}

strlen的模拟(递归实现)

递归和非递归分别实现strlen

/*循环实现:
1. 给一个计数,用来统计有效字符的个数
2. 遍历字符串,只要没有遇到\0, 遇到一个字符给计数加1,直到遇到\0*/
 int my_strlen(char* str)
 {
     int count = 0;
     while('\0' != *str)
     {
         count++;
         str++;
     }
     return count;
 }

/*递归实现:
                0  *str == '\0' 
my_strlen(str)
                my_strlen(p+1) + 1  子问题划分*/
int my_strlen(char *str)
{
    if('\0' == *str)
        return 0;
    else
        return 1+my_strlen(1+str);
}

字符串逆序(递归实现)

编写一个函数 reverse_string(char * string)(递归实现)

实现:将参数字符串中的字符反向排列,不是逆序打印。

要求:不能使用C函数库中的字符串操作函数。

/*思路:
逆置字符串,循环的方式实现非常简单
  1. 给两个指针,left放在字符串左侧,right放在最后一个有效字符位置
  2. 交换两个指针位置上的字符
  3. left指针往后走,right指针往前走,只要两个指针没有相遇,继续2,两个指针相遇后,逆置结束*/
void reverse_string(char* arr)
{
    char *left = arr;
    char *right = arr+strlen(arr)-1;
    while(left<right)
    {
        char tmp = *left;
        *left = *right;
        *right = tmp;

        left++;
        right--;
    }
}


/*递归方式:
对于字符串“abcdefg”,递归实现的大概原理:
  1. 交换a和g,
  2. 以递归的方式逆置源字符串的剩余部分,剩余部分可以看成一个有效的字符串,再以类似的方式逆置*/
void reverse_string(char* arr)
{
    int len = strlen(arr);
    char tmp = *arr;
    *arr = *(arr+len-1);
 
    *(arr+len-1) = '\0';
    if(strlen(arr+1)>=2)
        reverse_string(arr+1);
 
    *(arr+len-1) = tmp;
}

计算一个数的每位之和(递归实现)

写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和

/*
思路:
            n    n < 10
DigiSum(n) = 
           DibiSum(n/10)+n%10   // 前n-1位之和+第N位
*/

int DigitSum(int n)//1729
{
    if(n>9)
        return DigitSum(n/10)+n%10;
    else
        return n;
}

递归实现n的k次方

编写一个函数实现n的k次方,使用递归实现。

/*思路:
          1      K==0
Pow(n,K) = 
          Pow(n, K-1)*n
          */
int Pow(int n, int k)
{
    if(k==0)
        return 1;
    else if(k>=1)
    {
        return n*Pow(n, k-1);
    }
}

计算斐波那契数

递归和非递归分别实现求第n个斐波那契数

/*
思路:
一个问题直接求解时不好求解,如果可以将其划分成其子问题,并且子问题和原问题有相同的解法时,就可以使用递归的方式解决
递归的两个条件:
 1. 将问题划分成其子问题,要求:子问题要与原问题具有相同的解法
 2. 递归的出口


     1                       N < 3
Fac(N)
     Fac(N-1) + Fac(N-2)     N >= 3
*/
long long Fac(int N)
{
 if(N < 3)
     return 1;
 
 return Fac(N-1) + Fac(N-2);
}

strlen实现

模拟实现库函数strlen

size_t my_strlen (const char * str)
{
        const char *eos = str;
        while( *eos++ ) ;
        return( eos - str - 1 );
}

strcpy实现

模拟实现库函数strcpy

char * my_strcpy(char * dst, const char * src)
{
        char * cp = dst;
        while( *cp++ = *src++ );
        return( dst );
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值