C语言习题~day16

简介: C语言习题

1.关于函数调用说法不正确的是:( )

A.函数可以传值调用,传值调用的时候形参是实参的一份临时拷贝

B.函数可以传址调用,传址调用的时候,可以通过形参操作实参

C.函数可以嵌套定义,但是不能嵌套调用

D.函数可以嵌套调用,但是不能嵌套定义

答案解析:


A:正确,形参按照值的方式传递,将来形参就是实参的一份临时拷贝,修改形参不会影响外部的实参


B:正确,形参按照指针方式传递,将来形参就是实参地址的一份拷贝,形参指向的是实参,修改形参指针指向的内容,  就是在操作实参


C:错误,C语言中,函数不能嵌套定义


D:正确,函数可以嵌套调用,即:A()中调用B(),B()中调用A(),但是要控制好,否则就成为无限递归


因此,选择C

2.字符串左旋  实现一个函数,可以左旋字符串中的k个字符。例如:ABCD左旋一个字符得到BCDA ,ABCD左旋两个字符得到CDAB

设计循环使其可以旋1次,然后让他执行n次是一个最简单的思路:

void leftRound(char * src, int time)
{
  int i, j, tmp;
  int len = strlen(src);
  time %= len; //长度为5的情况下,旋转6、11、16...次相当于1次,7、12、17...次相当于2次,以此类推。
  for (i = 0; i < time; i++) //执行k次的单次平移
  {
    tmp = src[0];
    for(j = 0; j < len - 1; j++) //单次平移
    {
      src[j] = src[j + 1];
    }
    src[j] = tmp;
  }
}

改进一:

这个思路当然可以,但是一次一次转毕竟太麻烦,就不能一次到位么?

当然可以,我们可以选择拼接法,一次到位:

void leftRound(char * src, int time)
{
  int len = strlen(src);
  int pos = time % len; //断开位置的下标
  char tmp[256] = { 0 }; //更准确的话可以选择malloc len + 1个字节的空间来做这个tmp
  
  strcpy(tmp, src + pos); //先将后面的全部拷过来
  strncat(tmp, src, pos); //然后将前面几个接上
  strcpy(

改进二:


这个方法要用到一个数组形成的辅助空间,让人觉得有点不爽,还可以有更好的选择,例如ABCDEFG,左旋3次后变成DEFGABC,有一个特殊的操作方式:


先将要左旋的前三个家伙逆序(CBADEFG),然后将后半段也逆序(CBAGFED),最后整体逆序(DEFGABC)即可。这样只需要做数值交换即可,可以写一个函数帮我们完成局部逆序,代码如下:

void reverse_part(char *str, int start, int end) //将字符串从start到end这一段逆序
{
  int i, j;
  char tmp;
 
  for (i = start, j = end; i < j; i++, j--)
  {
    tmp = str[i];
    str[i] = str[j];
    str[j] = tmp;
  }
}
 
void leftRound(char * src, int time)
{
  int len = strlen(src);
  int pos = time % len;
  reverse_part(src, 0, pos - 1); //逆序前段
  reverse_part(src, pos, len - 1); //逆序后段
  reverse_part(src, 0, len - 1); //整体逆序
}

3.模拟实现库函数strlen

/*
思路:该题比较简单,参考代码
*/
size_t my_strlen (const char * str)
{
        const char *eos = str;
        while( *eos++ ) ;
        return( eos - str - 1 );
}

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

/*
思路:
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;
    }
  }
}

5.写一个函数,可以逆序一个字符串的内容。

/*
思路:该题比较简单,请参考代码
*/
void Reverse(char* str)
{
    char* left = str;
    char* right = str + strlen(str)-1;
    while(left < right)
    {
        char temp = *left;
        *left = *right;
        *right = temp;
        ++left;
        --right;
    }
}
 
 
int main()
{
    char str[] = "hello bit";
    //在这里完成下面函数,参数自己设计,要求:使用指针
    Reverse(str);
    return 0;
}
 
 
// 注意:如果是在线OJ时,必须要考虑循环输入,因为每个算法可能有多组测试用例进行验证,参考以下main函数写法,
int main()
{
    char str[101] = {0};
    while(gets(str))
    {
        Reverse(str);
        printf("%s\n", str);
        memset(str, 0, sizeof(str)/sizeof(str[0]));
    }
    return 0;
}


目录
相关文章
TU^
|
1天前
|
C语言
C语言习题~day39
C语言习题~day39
TU^
4 0
C语言习题~day39
TU^
|
1天前
|
存储 C语言
C语言习题~day38
C语言习题~day38
TU^
2 0
TU^
|
1天前
|
C语言
C语言习题~day37
C语言习题~day37
TU^
3 0
TU^
|
1天前
|
算法 程序员 C语言
C语言习题~day36
C语言习题~day36
TU^
7 1
TU^
|
1天前
|
存储 C语言
C语言习题~day35
C语言习题~day35
TU^
7 1
TU^
|
1天前
|
存储 C语言
C语言习题~day34
C语言习题~day34
TU^
6 1
TU^
|
1天前
|
算法 C语言
C语言习题~day33
C语言习题~day33
TU^
7 1
TU^
|
1天前
|
C语言
C语言习题~day32
C语言习题~day32
TU^
7 1
TU^
|
1天前
|
编译器 C语言
C语言习题~day31
C语言习题~day31
TU^
6 2
TU^
|
1天前
|
C语言
C语言习题~day30
C语言习题~day30
TU^
5 1