C语言习题~day16

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

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

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

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

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

答案解析:

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

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

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

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

因此,选择C

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

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

cpp 复制代码
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;
	}
}

改进一:

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

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

cpp 复制代码
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)即可。这样只需要做数值交换即可,可以写一个函数帮我们完成局部逆序,代码如下:

cpp 复制代码
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

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

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

cpp 复制代码
/*
思路:
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.写一个函数,可以逆序一个字符串的内容。

cpp 复制代码
/*
思路:该题比较简单,请参考代码
*/
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;
}
相关推荐
元亓亓亓15 小时前
LeetCode热题100--79. 单词搜索
算法·leetcode·职场和发展
就叫飞六吧16 小时前
css+js 前端无限画布实现
前端·javascript·css
2501_9411481516 小时前
高并发搜索引擎Elasticsearch与Solr深度优化在互联网实践分享
java·开发语言·前端
IT 前端 张16 小时前
Uniapp全局显示 悬浮组件/无需单页面引入
前端·javascript·uni-app
hazy1k16 小时前
ESP32基础-Socket通信 (TCP/UDP)
c语言·单片机·嵌入式硬件·网络协议·tcp/ip·udp·esp32
allenjiao16 小时前
WebGPU vs WebGL:WebGPU什么时候能完全替代WebGL?Web 图形渲染的迭代与未来
前端·图形渲染·webgl·threejs·cesium·webgpu·babylonjs
dvvvvvw16 小时前
x的y次幂的递归函数.c
c语言
司铭鸿16 小时前
化学式解析的算法之美:从原子计数到栈的巧妙运用
linux·运维·服务器·算法·动态规划·代理模式·哈希算法
上车函予16 小时前
geojson-3d-renderer:从原理到实践,打造高性能3D地理可视化库
前端·vue.js·three.js
孟祥_成都16 小时前
别被营销号误导了!你以为真的 Bun 和 Deno 比 Node.js 快很多吗?
前端·node.js