第四十二天学习记录:C语言进阶:笔试题整理Ⅲ

news/2025/2/16 6:05:22/

问:解释一下int(*a[20])(int)是什么?
ChatAI答:
int (*a[20])(int) 是一个数组,该数组中每个元素都是一个指向函数的指针,该函数具有一个int类型的参数,并返回一个int类型的值。

具体来说,a是一个数组,包含20个函数指针元素。每个函数指针指向的函数都具有一个int类型的参数,并返回一个int类型的值。可以使用下标访问数组中的任何函数指针元素,并将其赋值为指向满足该条件的函数的指针。

以下是一些使用该数组类型的示例:

#include <stdio.h>int add(int n) {return n + 1;
}int sub(int n) {return n - 1;
}int main() {int (*a[20])(int);a[0] = add;   // 将a[0]指向add函数a[1] = sub;   // 将a[1]指向sub函数int x = 10;x = a[0](x);  // 调用add函数,将a[0]作为函数指针传递x = a[1](x);  // 调用sub函数,将a[1]作为函数指针传递printf("%d\n", x);return 0;
}

在这个示例中,我们声明了一个包含20个函数指针元素的数组a,并将其第一个元素指向add函数,第二个元素指向sub函数。我们还定义了一个变量x并将其初始化为10。然后,我们通过调用a[0]a[1]中的函数指针来操作x的值,并在最后打印出x的值。

请注意,在声明函数指针时,需要使用一对括号将函数名括起来,这是因为()的优先级高于*,否则会被解释为函数原型。

单选题:
题目名称:
关于回调函数描述错误的是(D)
题目内容:
A、回调函数就是一个通过函数指针调用的函数。
B、回调函数一般通过函数指针实现。
C、回调函数一般不是函数的实现方调用,而是在特定的场景下,由另一方调用。
D、回调函数是调用函数指针指向函数的函数。
(回调函数是调用函数指针指向的那个函数,而不是指向函数的函数。)

求下列程序输出结果:

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>int main()
{int a[5] = { 5,4,3,2,1 };int* ptr = (int*)(&a+1);printf("%d,%d", *(a + 1), *(ptr - 1));return 0;//4,1
}

输出:4,1

求下列程序输出结果:

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>int main()
{int aa[2][5] = { 10,9,8,7,6,5,4,3,2,1 };int* ptr1 = (int*)(&aa + 1);int* ptr2 = (int*)(*(aa + 1));printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));return 0;//1,6
}

输出:1,6

题目名称:

字符串左旋
题目内容:
实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
第一种写法:暴力求解法

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>
#include <string.h>
#include <assert.h>//暴力求解法
void left_move(char arr[], int k)
{assert(arr != NULL);int i = 0;int len = strlen(arr);for (i = 0; i < k; i++){char tmp = *arr;int j = 0;for (j = 0; j <len-1 ; j++){*(arr + j) = *(arr + j + 1);}*(arr + len - 1) = tmp;}
}int main()
{char arr[] = "abcdef";left_move(arr, 2);printf("%s\n", arr);return 0;
}

在这里插入图片描述

第二种写法:三部翻转法

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>
#include <string.h>
#include <assert.h>//三部翻转法
void reverse(char* left, char* right)
{assert(left != NULL);assert(right != NULL);while (left<right){char tmp = *left;*left = *right;*right = tmp;left++;right--;}
}void left_move(char arr[], int k)
{assert(arr);int len = strlen(arr);assert(k <= len);reverse(arr,arr+k-1);//逆序左边reverse(arr+k,arr+len-1);//逆序右边reverse(arr,arr+len-1);//逆序整体
}int main()
{char arr[] = "abcdef";left_move(arr, 2);printf("%s\n", arr);return 0;
}

题目名称:

字符串旋转结果
题目内容:
写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1=AABCD和s2=BCDAA,返回1,给定s1=ABCD和s2=ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC

方法一:穷举法

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>
#include <string.h>
#include <assert.h>//三部翻转法
void reverse(char* left, char* right)
{assert(left != NULL);assert(right != NULL);while (left<right){char tmp = *left;*left = *right;*right = tmp;left++;right--;}
}void left_move(char arr[], int k)
{assert(arr);int len = strlen(arr);assert(k <= len);reverse(arr, arr + k - 1);//逆序左边reverse(arr + k, arr + len - 1);//逆序右边reverse(arr, arr + len - 1);//逆序整体
}int is_left_move(char* s1, char* s2)
{int len = strlen(s1);int i = 0;for (i = 0; i < len; i++){left_move(s1, 1);int ret=strcmp(s1, s2);if (ret == 0){return 1;}}return 0;
}int main()
{char arr1[] = "abcdef";char arr2[] = "cdefab";int ret = is_left_move(arr1, arr2);if (ret == 1){printf("Yes\n");}else{printf("No\n");}return 0;
}

输出:Yes

方法二:

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>
#include <string.h>int is_left_move(char* str1, char* str2)
{int len1 = strlen(str1);int len2 = strlen(str2);if (len1 != len2){return 0;}//1.在str1字符串中追加一个str1字符串//strcat(str1,str1)//err不能自己给自己追加strncat(str1,str2,6);//2.判断str2指向的字符串是否是str1指向的字符串的子串char* ret=strstr(str1, str2);if (ret == NULL){return 0;}else{return 1;}
}int main()
{char arr1[30] = "abcdef";char arr2[] = "cdefab";int ret = is_left_move(arr1, arr2);if (ret == 1){printf("Yes\n");}else{printf("No\n");}return 0;
}

推荐:《程序员编程艺术》

题目名称:
杨氏矩阵
题目内容:
有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。
要求:时间复杂度小于0(N)。

问:时间复杂度如何理解?
ChatAI答:
时间复杂度通常用来表示一个算法的执行效率,是指通过分析算法的执行次数与输入规模之间的关系,来描述算法的时间性能。时间复杂度常见的表示方法有大O符号表示法。

大O符号表示法是一种常用的描述算法时间复杂度的方法,它描述的是算法复杂度的一个上界,可以用来衡量算法的时间性能。

具体来说,时间复杂度有三种情况,分别是最坏时间复杂度、最好时间复杂度和平均时间复杂度。最坏时间复杂度表示在最差情况下的执行次数,最好时间复杂度表示在最优情况下的执行次数,平均时间复杂度则是考虑所有输入情况下的执行次数的期望值。在实际应用中,我们常常关注最坏时间复杂度,因为它是通常情况下最能反映算法时间性能的指标。

时间复杂度可以表示为 T(n) = O(f(n)),其中 n 表示问题规模,f(n) 表示每次运行算法所需的基本操作数,O 表示“不超过”的关系。大O记号表示的是一个函数的渐进上界,即随着输入规模 n 的增大,函数 f(n) 的增长速度不超过某个常量乘以 g(n)。其中 g(n) 是已知的一个非负函数,常用的有 O(1)、O(log n)、O(n)、O(nlog n)、O(n²)、O(n³) 等复杂度级别,其中 O(1) 表示常数复杂度,O(n) 表示线性复杂度,O(n²) 表示平方复杂度,O(log n) 表示对数复杂度,O(nlog n) 表示几乎线性的复杂度。

#define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>int FindNum(int arr[3][3], int k, int *px, int *py)
{int x = 0;int y = *py - 1;while (x<=*px-1&&y>=0){if (arr[x][y] > k){y--;}else if (arr[x][y] < k){x++;}else{*px = x;*py = y;return 1;}}//找不到return 0;
}int main()
{int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };int k = 7;int x = 3;int y = 3;int ret = FindNum(arr, k, &x, &y);if (ret == 1){printf("找到了\n");printf("下标是:%d %d\n", x, y);}else{printf("找不到\n");}return 0;
}

在这里插入图片描述
问:C语言函数能返回一个数组吗?

ChatAI答:
在 C 语言中,函数不能直接返回一个数组,但可以通过以下几种方式来返回数组:

  1. 返回指针

函数可以返回一个指向数组首元素的指针。这种方式效率高,也比较常用。需要注意的是函数返回的指针变量不能指向一个局部数组或变量,因为函数调用结束后,局部数组或变量的内存会被释放,指向它们的指针变量也就失效了。下面是一个返回动态分配数组的例子:

int* allocate_array(int n) {int* array = malloc(n * sizeof(int));/* 为数组赋初值 */for (int i = 0; i < n; i++) {array[i] = i + 1;}return array;
}
  1. 传入参数

函数通过传入数组的方式,将结果保存在数组中。这种方式可以兼容局部数组和动态分配的数组。下面是一个接收参数并修改数组的例子:

void modify_array(int* array, int n) {/* 修改数组的元素 */for (int i = 0; i < n; i++) {array[i] += 1;}
}int main() {int a[5] = {1, 2, 3, 4, 5};modify_array(a, 5);/* 输出修改后的数组 */for (int i = 0; i < 5; i++) {printf("%d ", a[i]);}return 0;
}
  1. 结构体返回

函数可以返回一个包含数组的结构体,但这种方式适用于较小的数组,否则会导致栈溢出的风险。下面是一个结构体返回数组的例子:

struct Array {int data[5];
};struct Array get_array() {struct Array arr = {.data = {1, 2, 3, 4, 5}};return arr;
}int main() {struct Array arr = get_array();/* 输出获取的数组 */for (int i = 0; i < 5; i++) {printf("%d ", arr.data[i]);} return 0;
}

http://www.ppmy.cn/news/83732.html

相关文章

你不知道的useEffect

相信大家在写react时&#xff0c;在项目中使用了大量的useEffect&#xff0c;以至于让我们的代码变得混乱和难以维护。 难道说useEffect这个hook不好吗&#xff1f;并不是这样的&#xff0c;只是我们一直在滥用而已 在这篇文章中&#xff0c;我将展示怎样使用其他方法来代替us…

2222. 迷宫

Powered by:NEFU AB-IN Link 文章目录 2222. 迷宫题意思路代码 2222. 迷宫 题意 摘要&#xff1a;终点为n,n&#xff0c;存在传送门&#xff0c;代价与走动代价相同&#xff0c;均为1&#xff0c;起点不定&#xff0c;求从初始格子走到终点的最短 步数的期望值是多少 思路 两种…

设计模式实战 - 工厂模式实现总览页面工作进展指标查询

设计模式实战 - 工厂模式实现总览页面工作进展指标查询 1. 请求入口 ProgressController PostMapping("/progress/indicators") ApiOperation(value "总览工作进展") PreAuthorize("hasAnyAuthority(superAdmin,overViewQuery,incidentQuery,alert…

ChatGPT提示工程课程,吴恩达OpenAI

Principle 1: Write clear and specific instructions 使用明确的分隔符&#xff0c;是LLM知道这个某个单独的字段。 前提设置&#xff1a; import openai import osfrom dotenv import load_dotenv, find_dotenv _ load_dotenv(find_dotenv()) # read local .env fileopena…

网络是信息传输网络3

网络是信息传输、接收、共享的虚拟平台&#xff0c;通过它把各个点、面、体的信息联系到一起&#xff0c;从而实现这些资源的共享。网络是人类发展史来最重要的发明&#xff0c;提高了科技和人类社会的发展。 网络会借助文字阅读、图片查看、影音播放、下载传输、游戏、聊天等…

5G信道建模研究进展与展望

5G信道建模研究进展与展望 一、信道建模定义二、5G信道建模研究进展1. 5G信道建模的理论框架1.1 大尺度衰落特性1.2 小尺度衰落特性1.3 信道新特性 2. 5G信道测量平台和应用场景2.1 5G信道测量平台2.2 5G信道的应用场景 3. 5G信道特性提取与建模 三、未来6G信道建模的研究方向1…

V-Ray渲染教程:又快又好的V-Ray渲染参数!

Chaos V-Ray 是适用于大部分主流3D设计软件和CAD程序的3D渲染插件&#xff0c;它可以与 3ds Max、Cinema 4D、Houdini、Maya、Nuke、Revit、Rhino、SketchUp、Unreal 无缝协作。借助 V-Ray渲染器强大的功能&#xff0c;艺术家和设计师可以产生出非常逼真的渲染效果。 那么&…

数据分析师职业规划——数据分析师这个岗位,可能近几年会消亡

近期成为月入两万的数据分析师的广告遍地都是&#xff0c;可能会对一些未入行的同学造成错觉。我个人感觉数据分析师这个岗位&#xff0c;可能近几年会消亡。 这不意味着这份工作本身不重要&#xff0c;而是说这份工作本身可能会转化为产品运营的一些必备技能&#xff0c;而不…