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;
}
相关推荐
鱼樱前端10 分钟前
重度Cursor用户 最强 Cursor Rules 和 Cursor 配置 mcp 以及最佳实践配置方式
前端
曼陀罗11 分钟前
Path<T> 、 keyof T 什么情况下用合适
前端
锈儿海老师17 分钟前
AST 工具大PK!Biome 的 GritQL 插件 vs. ast-grep,谁是你的菜?
前端·javascript·eslint
飞龙AI19 分钟前
鸿蒙Next实现瀑布流布局
前端
快起来别睡了20 分钟前
代理模式:送花风波
前端·javascript·架构
海底火旺22 分钟前
电影应用开发:从代码细节到用户体验优化
前端·css·html
圈圈编码29 分钟前
LeetCode Hot100刷题——合并两个有序链表
java·数据结构·算法·leetcode·链表
陈随易31 分钟前
Gitea v1.24.0发布,自建github神器
前端·后端·程序员
前端付豪34 分钟前
汇丰银行技术架构揭秘:全球交易稳定背后的“微服务+容灾+零信任安全体系”
前端·后端·架构
邹荣乐36 分钟前
uni-app开发微信小程序的报错[渲染层错误]排查及解决
前端·微信小程序·uni-app