2020
1. 请试着解释其输出。
int main(int argc , char *argv[])
{
unsigned char a = 255;
char ch = 128;
a -= ch;
printf("a = %d ch = %d\n", a, ch);
}
char最大值=127
给char类型赋值128 会溢出变成-128
运行表达式时依旧会带入赋给的值进行运算。
a=127 ch=-128
2. 下面代码的运行输出结果是什么,并说说你的理解。
int main(int argc, char *argv[])
{
char *str = "Xi You Linux Group 20";
printf("%d\n", printf(str));
return 0;
}
同 22-1
Xi You Linux Group 2021
3. 这段代码的输出结果是什么?为什么会出现这样的结果?
int i = 2;
void func()
{
if (i != 0)
{
static int m = 0;
int n = 0;
n++;
m++;
printf("m = %d, n = %d\n", m, n);
i--;
func();
}
else
{
return;
}
}
int main(int argc, char *argv[])
{
func();
return 0;
}
m = 2, n = 1
static 静态变量
循环俩次
m++ = 1 ;n++ = 1
n释放,m存储在静态区 n=0,m=1
m++ = 2 ;n++ = 0
4. 下面程序会出现什么结果?为什么会出现这样的结果?
int main(int argc, char *argv[])
{
char ch = 'A';
int i = 65;
unsigned int f = 33554433;
*(int *)&f >>= 24;
*(int *)&f = *(int *)&f + '?';
printf("ch = %c i = %c f = %c\n", ch, i, *(int *)&f);
return 0;
}
ch = A i = A f = A
位运算后得f=2 ?的ASCII码为63
A的ASCLL码为65
5. 下面代码的运行输出结果是什么,并说说你的理解。
int main(int argc, char *argv[])
{
int a[2][2];
printf("&a = %p\t&a[0] = %p\t&a[0][0] = %p\n", &a, &a[0], &a[0][0]);
printf("&a+1 = %p\t&a[0]+1 = %p\t&a[0][0]+1= %p\n", &a + 1, &a[0] + 1, &a[0][0] + 1);
return 0;
}
&a = 0x7fffffffdcd0 &a[0] = 0x7fffffffdcd0 &a[0][0] = 0x7fffffffdcd0
&a+1 = 0x7fffffffdce0 &a[0]+1 = 0x7fffffffdcd8 &a[0][0]+1= 0x7fffffffdcd4
&a——数组地址用首元素地址表示
&a[0] ——数组第一行地址用首元素地址表示
&a[0][0]——数组首元素地址
&a+1——加整个数组地址长度
a[0]+1——加一行数组地址长度
a[0][0]+1——加一个元素的地址长度
6. 下列程序的功能是什么?有什么问题,你能找出问题并解决它吗?
int* get_array()
{
int array[1121];
for (int i = 0; i < sizeof(array) / sizeof(int); i++)
{
array[i] = i;
}
return array;
}
int main(int argc, char *argv[])
{
int *p = get_array();
return 0;
}
功能:给数组array[1121]赋值下标
问题 :for循环结束后array[1121]释放内存, 所以返回地址然而找不到对应的变量
修改:
int array[1121];———> static int array[1121];
7. 下面代码的运行输出结果是什么,并说说你的理解。
int main(int argc, char *argv[]) {
char str[] = "XiyouLinuxGroup";
char *p = str;
char x[] = "XiyouLinuxGroup\t\106F\bamily";
printf("%zu %zu %zu %zu\n", sizeof(str), sizeof(p), sizeof(x), strlen(x));
return 0;
}
16 8 25 24
同22-2
8. 如下程序,根据打印结果,你有什么思考?
int add(int *x, int y)
{
return *x = (*x ^ y) + ((*x & y) << 1);
}
int a;
int main(int argc, char *argv[])
{
int b = 2020;
if (add(&b, 1) || add(&a, 1))
{
printf("XiyouLinuxGroup%d\n", b);
printf("Waiting for y%du!\n", a);
}
if (add(&b, 1) && a++)
{
printf("XiyouLinuxGroup%d\n", b);
printf("Waiting for y%du!\n", a);
}
return 0;
}
位运算 同22-5
XiyouLinuxGroup2021
Waiting for y0u!
9. 在下段程序中,我们可以通过第一步打印出a
的地址,假如在你的机器上面打印结果是0x7ffd737c6db4
;我们在第二步用scanf
函数将这个地址值输入变量c
中;第三步,随机输入一个数字,请问最终输出了什么结果,你知道其中的原理吗?
void func()
{
int a = 2020;
unsigned long c;
printf("%p\n", &a);
printf("我们想要修改的地址:");
scanf("%lx", &c);
printf("请随便输入一个数字:");
scanf("%d", (int *)c);
printf("a = %d\n", a);
}
a=输入的数字
%lx,表示long类型指针,用16进制输出
func()
打印a的地址–>
将地址的16进制值赋值给无符号长整形c–>
将c进行强制类型转换变成指针并输入随机数–>
变量a的地址就变成了c–>
a=输入的数字
10. 请问一个C语言程序从源代码到可执行文件中间会进行哪些过程,你能简单描述一下每个环节都做了什么事情吗?
11. 请解释一下这行代码做了什么?
puts((char *)(int const[]){
0X6F796958, 0X6E694C75, 0X72477875,
0X3270756F, 0X313230, 0X00000A});
XiyouLinuxGroup2021
同22-12
12. 请随机输入一串字符串,你能解释一下输出结果吗?
int main(int argc, char *argv[])
{
char str[1121];
int key;
char t;
fgets(str, 1121, stdin);
for (int i = 0; i < strlen(str) - 1; i++)
{
key = i;
for (int j = i + 1; j < strlen(str); j++)
{
if (str[key] > str[j])
{
key = j;
}
}
t = str[key];
str[key] = str[i];
str[i] = t;
}
puts(str);
return 0;
}
adahjqoiocnqcjkqpock
aacccdhijjkknooopqqq
fgets()
char *fgets(char *s, int size, FILE *stream);
它的功能是从 stream 流中读取 size 个字符存储到字符指针变量 s 所指向的内存空间。它的返回值是一个指针,指向字符串中第一个字符的地址。
fgets实现对字符串的读取
for循环实现的是对字符的排序
puts打印字符串
13. 用循环和递归求Fibonacci
数列,你觉得这两种方式那种更好?说说你的看法。如果让你求Fibonacci
数列的第100项,你觉得还可以用常规的方法求解吗?请试着求出前100项的值(tip大数运算)。
递归 方便快捷,but数字大时运行速度太慢,此时循环更为快捷
//递归
#include <stdio.h>
int Fibonacci(int n)
{
if (n <= 2)
return 1;
else
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
int main()
{
int n;
scanf("%d", &n);
int x=Fibonacci(n);
printf("%d", x);
return 0;
}
//循环
#include <stdio.h>
long long int a = 1, b = 1;
long long int c = 0;
int n, i;
int main()
{
scanf("%d", &n);
for (i = 3; i <= n; i++)
{
c = a + b;
a = b;
b = c;
}
printf("%lld", c);
return 0;
}
14. Linux 实操题
请通过命令创建一个目录,在该目录中创建几个后缀为
.Linux
的文件,然后通过命令查询这几个文件的基本属性信息(如文件大小,文件创建时间等),之后使用命令查看该目录下文件名含有“.Linux
”的文件的数量(不包括子目录下的文件),把得到的数字写入到一个文件中,最后删除此目录。
mkdir abc
touch abc/ABC.Liunx
stat ABC.Linux
cd:abc
rm -rh abc
2021
1. 大小和长度竟然不是一个意思
sizeof()
和strlen()
有什么异同之处?他们对于不同参数的结果有什么不同?请试举例子说明。
int main(void)
{
char s[] = "I love Linux\0\0\0";
int a = sizeof(s);
int b = strlen(s);
printf("%d %d\n", a, b);
}
16 12
同22-2
2. 箱子的大小和装入物品的顺序有关
test1
和test2
都含有:1个short
、1个int
、1个double
,那么sizeof(t1)
和sizeof(t2)
是否相等呢?这是为什么呢?
struct test1
{
int a;
short b;
double c;
};
struct test2
{
short b;
int a;
double c;
};
int main(void)
{
struct test1 t1;
struct test2 t2;
printf("sizeof (t1) : %d\n", sizeof(t1));
printf("sizeof (t2) : %d\n", sizeof(t2));
}
sizeof (t1) : 16
sizeof (t2) : 16
同22-4
3. 哦,又是函数
想必在高数老师的教导下大家十分熟悉函数这个概念。那么你了解计算机程序设计中的函数吗?请编写一个
func
函数,用来输出二维数组arr
中每个元素的
void func(int (&arr)[10][13])
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 13; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main(void)
{
int arr[10][13];
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 13; j++)
{
arr[i][j] = rand();
}
}
func(arr);
}
1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421 1025202362 1350490027 783368690
1102520059 2044897763 1967513926 1365180540 1540383426 304089172 1303455736 35005211 521595368 294702567 1726956429 336465782 861021530
278722862 233665123 2145174067 468703135 1101513929 1801979802 1315634022 635723058 1369133069 1125898167 1059961393 2089018456 628175011
1656478042 1131176229 1653377373 859484421 1914544919 608413784 756898537 1734575198 1973594324 149798315 2038664370 1129566413 184803526
412776091 1424268980 1911759956 749241873 137806862 42999170 982906996 135497281 511702305 2084420925 1937477084 1827336327 572660336
1159126505 805750846 1632621729 1100661313 1433925857 1141616124 84353895 939819582 2001100545 1998898814 1548233367 610515434 1585990364
1374344043 760313750 1477171087 356426808 945117276 1889947178 1780695788 709393584 491705403 1918502651 752392754 1474612399 2053999932
1264095060 1411549676 1843993368 943947739 1984210012 855636226 1749698586 1469348094 1956297539 1036140795 463480570 2040651434 1975960378
317097467 1892066601 1376710097 927612902 1330573317 603570492 1687926652 660260756 959997301 485560280 402724286 593209441 1194953865
894429689 364228444 1947346619 221558440 270744729 1063958031 1633108117 2114738097 2007905771 1469834481 822890675 1610120709 791698927
4.就不能换个变量名吗?
- 请结合下面的程序,简要谈谈
传值
和传址
的区别。- 简要谈谈你对C语言中变量的生命周期的认识。
int ver = 123;
void func1(int ver)
{
ver++;
printf("ver = %d\n", ver);//1026
}
void func2(int *pr)
{
*pr = 1234;
printf("*pr = %d\n", *pr);//1234
*pr = 5678;
printf("ver = %d\n", ver);//123
}
int main()
{
int a = 0;
int ver = 1025;
for (a = 3; a < 4; a++)
{
static int a = 5;
printf("a = %d\n", a);//5
a = ver;
func1(ver);
int ver = 7;
printf("ver = %d\n", ver);//7
func2(&ver);
}
printf("a = %d\tver = %d\n", a, ver);//4 1025
}
a = 5
ver = 1026
ver = 7
*pr = 1234
ver = 123
a = 4 ver = 1025
5. 套娃真好玩!
请说明下面的程序是如何完成求和的?
unsigned sum(unsigned n)
{
return n ? sum(n - 1) + n : 0;
}
int main(void)
{
printf("%u\n", sum(100));
}
5050
递归思想
6. 算不对的算术
void fanc(void)
{
short a = -2;
unsigned int b = 1;
b += a;
int c = -1;
unsigned short d = c * 256;
c <<= 4;
int e = 2;
e = ~e | 6;
d = (d & 0xff) + 0x2022;
printf("a=0x%hx\tb=0x%x\td=0x%hx\te=0x%x\n", a, b, d, e);
printf("c=Ox%hhx\t\n", (signed char)c);
}
a=0xfffe b=0xffffffff d=0x2022 e=0xffffffff
c=Oxf0
%x代表以16进制的 输出32位
%hx 代表以16进制的 输出16位
%hhx 代表以16进制的 输出8位
7. 指针和数组的恩怨情仇
int main(void)
{
int a[3][3] = {
{
1, 2, 3}, {
4, 5, 6}, {
7, 8, 9}};
int(*b)[3] = a;
++b;
b[1][1] = 10;
int *ptr = (int *)(&a + 1);
printf("%d %d %d \n", a[2][1], **(a + 1), *(ptr - 1));
}
10 4 9
#include<stdio.h>
int main()
{
int a[3][3] = {
{
1,2,3},{
4,5,6},{
7,8,9} };
int(*b)[3] = a;//指向数组的指针
++b;//此时b[0]=a[1],b[1]=a[2];
b[1][1] = 10;//所以a[2][1]=10
int* ptr = (int*)(&a + 1);//&a指向a数组开头,+1后指向下一个数组, 所以*(ptr - 1)=a[2][2]
printf("%d %d %d\n", a[2][1], **(a + 1), *(ptr - 1));//**(a+1)=a[1][1]
return 0;//结果为10 4 9
}
8. 移形换位之术
下面有
a
、b
、c
三个变量和4个相似的函数。
- 你能说出使用这三个变量的值或地址作为参数分别调用这5个函数,在语法上是否正确吗?
- 请找出下面的代码中的错误。
const int
和int const
是否有区别?如果有区别,请谈谈他们的区别。const int *
和int const *
是否有区别?如果有区别,请谈谈他们的区别。
int a = 1;
int const b = 2;
const int c = 3;
void funco(int n)
{
n += 1;
n = a;
}
void func1(int *n)
{
*n += 1;
n = &a;
}
void func2(const int *n)//错 *修饰int n,n的值不能改变
{
*n += 1;//n的值无法改变
n = &a;
}
void func3(int *const n)//错 const修饰int*n,n的地址不能改变
{
*n += 1;
n = &a;//无法完成赋值
}
void func4(const int *const n)//错 n的值,n的地址不能被改变
{
*n += 1;//n的值不能改变
n = &a;//无法完成赋值
}
const int 和int const都是指该int类型变量不能被修改,没有区别const int和int const也没有区别,都是指指针指向的值不能被改变
9. 听说翻转字母大小写不影响英文的阅读?
请编写
convert
函数用来将作为参数的字符串中的大写字母转换为小写字母,将小写字母转换为大写字母。返回转换完成得到的新字符串。
int main(void)
{
char *str =(char*)"XiyouLinux Group 2022";
char *temp = convert(str);
puts(temp);
}
char* convert(const char* str)
{
int i;
char* tmp = (char*)malloc(sizeof(char) * strlen(str));
tmp[21] = '\0';
strcat(tmp, str);
for (i = 0; i < 21; i++) {
if (tmp[i] >= 96 && tmp[i] <= 122) {
tmp[i] -= 32;
}
else if (tmp[i] >= 65 && tmp[i] <= 90) {
tmp[i] += 32;
}
}
free(tmp);
return tmp;
}
10. 交换礼物的方式
- 请判断下面的三种
Swap
的正误,分别分析他们的优缺点。- 你知道这里的
do {...} while(0)
的作用吗?- 你还有其他的方式实现
Swap
功能吗?
#define Swap1(a, b, t) \
do \
{
\
t = a; \
a = b; \
b = t; \
} while (0)//对
#define Swap2(a, b) \
do \
{
\
\ int t = a; \
a = b; \
b = t; \
} while (0)//对
void Swap3(int a, int b)
{
int t = a;
a = b;
b = t;
}//错 没有main()
do{
……
}while(0)配合宏定义使用
void swap(int* p1,int* p2)
{
int temp=*p1;
*p1=*p2;
*p2=temp;
}
11. 据说有个东西叫参数
你知道
argc
和argv
的含义吗?请解释下面的程序。你能在不使用argc
的前提下,完成对argv
的遍历吗?
int main(int argc, char *argv[])
{
printf("argc = %d\n", argc);
for (int i = 0; i < argc; i++)
printf("%s\n", argv[i]);
}
同22-11
#include <stdio.h>
int main(int argc, char* argv[])
{
int i = 0;
printf("argc = %d\n", argc);
while (argv[i] != NULL)
printf("%s\n", argv[i++]);
return 0;
}
argc = 1
/home/zhj/桌面/solution of something/test
12. 人去楼空
这段代码有是否存在错误?谈一谈静态变量与其他变量的异同。
int *func1(void)
{
static int n = 0;
n = 1;
return &n;
}
int *func2(void)
{
int *p = (int *)malloc(sizeof(int));
*p = 3;
return p;
}
int *func3(void)
{
int n = 4;
return &n;
}
int main(void)
{
*func1() = 4;
*func2() = 5;
*func3() = 6;
}
func 3错 n在func 1中被static修饰,在*func 3中不能对其进行重新定义
13. 奇怪的输出
int main(void)
{
int data[] = {
0x636c6557, 0x20656d6f, 0x78206f74,
0x756f7969, 0x6e694c20, 0x67207875,
0x70756f72, 0x32303220, 0x00000a31};
puts((const char *)data);
}
Welcome to xiyou Linux group 2021
同22-12
14. 请谈谈对从「C语言文件到可执行文件」的过程的理解
同20-10
15. (选做) 堆和栈
你了解程序中的栈和堆吗?它们在使用上有什么区别呢?请简要说明。
16. (选做) 多文件
一个程序在不使用任何头文件的情况下,如何使用另一个文件中的函数。
17. (选做) GNU/Linux
与文件
- 你知道如何在
GNU/Linux
下如何使用命令行创建文件与文
件夹吗?- 你知道
GNU/Linux
下的命令ls 的每一列的含义吗?- 你知道
GNU/Linux
下文件的访问时间、修改时间、创建时间如何查看吗?并简单说说他们的区别。
2022
0. 我的计算器坏了?!
2^10=1024
对应于十进制的4位,那么2^10000
对应于十进制的多少位呢?
ans:2^10000 / 10^k <1;求k
1. printf还能这么玩?
尝试着解释程序的输出。
int main(void) {
if ((3 + 2 < 2) > (3 + 2 > 2))
printf("Welcome to Xiyou Linux Group\n");
else
printf("%d\n", printf("Xiyou Linux Group - 2%d", printf("")));
}
printf() 的嵌套使用,从左向右执行,从右向左打印
printf()的返回值是打印的字节数
2. 你好你好你好呀!
- 程序的输出有点奇怪,请尝试解释一下程序的输出吧。
- 请谈谈对
sizeof()
及strlen()
的理解吧。
int main(void)
{
char p0[] = "Hello,Linux";
char *p1 = "Hello,Linux";
char p2[12] = "Hello,Linux";
printf("p0==p1: %d, strcmp(p0,p2): %d\n", p0 == p1, strcmp(p0, p2));
printf("sizeof(p0): %zu, sizeof(p1): %zu, sizeof(*p2): %zu \n",
sizeof(p0), sizeof(p1), sizeof(*p2));
printf("strlen(p0): %zu, strlen(p1): %zu\n", strlen(p0), strlen(p1));
}
p0==p1: 0, strcmp(p0,p2): 0
sizeof(p0): 12, sizeof(p1): 8, sizeof(*p2): 1
strlen(p0): 11, strlen(p1): 11
p0字符串,p1常量指针,p2字符串
p0!=p1 返回 0 p0==p2 strcmp 返回 0
p0 12字节 p1常量指针 占字节数8(_64) or 4(_32) *p2指p2首元素H 即占1字节
p0 长度11字节 p1所指代内容占11字节
sizeof() 操作符 计算所占内存的实际大小 记得加\0 size_t类型
strlen() <string.h> 计算数据的字节多少 不加\0 strlen返回的类型,size_t 无符号长整型
strcmp <string.h> 返回值如下
从左到右依次比较 ASCLL码比较 遇到\0或不同字符停止
返回值>0 前大于后
返回值<0 前小于后
返回值=0 相同
3. 换个变量名不行吗?
请结合本题,分别谈谈你对C语言中「全局变量」和「局部变量」的「生命周期」理解。
int a = 3;
void test()
{
int a = 1;
a += 1;
{
int a = a + 1;
printf("a3 = %d\n", a);
}
printf("a2 = %d\n", a);
}
int main(void)
{
test();
printf("a1= %d\n", a);
}
a1 = 随机值
a2 = 2
a1 = 2
全局变量:
生命周期:程序运行期间一直存在,从程序开始到程序结束;不受函数内部运算的影响;
局部变量:
生命周期:随着函数的结束,即被销毁;
4. 内存对不齐
union
与struct
各有什么特点呢,你了解他们的内存分配模式吗。
typedef union
{
long l;
int i[5];
char c;
} UNION;
typedef struct
{
int like;
UNION coin;
double collect;
} STRUCT;
int main(void)
{
printf("sizeof (UNION) = %zu \n", sizeof(UNION));
printf("sizeof (STRUCT) = %zu \n", sizeof(STRUCT));
}
sizeof (UNION) = 24
sizeof (STRUCT) = 40
union:使不同类型变量共同占用同一段内存
struct:把不同类型的数据组合成一个整体–自定义数据类型
1.struct和union都是由多个不同的数据类型成员组成, 但在任何同一时刻, union中只存放了一个被选中的成员, 而struct的所有成员都存在。在struct中,各成员都占有自己的内存空间,它们是同时存在的。一个struct变量的总长度等于所有成员长度之和。在Union中,所有成员不能同时占用它的内存空间,它们不能同时存在。Union变量的长度等于最长的成员的长度。
2. 对于union的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于struct的不同成员赋值是互不影响的。
5. Bitwise
- 请使用纸笔推导出程序的输出结果。
- 请谈谈你对位运算的理解。
int main(void)
{
unsigned char a = 4 | 7;
a <<= 3;
unsigned char b = 5 & 7;
b >>= 3;
unsigned char c = 6 ^ 7;
c = ~c;
unsigned short d = (a ^ c) << 3;
signed char e = -63;
e <<= 2;
printf("a: %d, b: %d, c: %d, d: %d \n", a, b, c, (char)d);
printf("e: %#x \n", e);
}
a: 56, b: 0, c: 254, d: 48
e: 0x4
符号 名称 描述
& 按位与 两个数相应位都为1,则该位的结果为1,否则为0
| 按位或 两个数相应位有一个为1,则该位的结果为1,否则为0
^ 按位异或 两个数相应位不同时,则该位的结果为1,否则为0
~ 按位取反 对数的每一个位取反,即1变0,0变1
<< 左移运算 将数的每个位向左移,高位丢弃,低位补0
->> 右移运算 将数的每个位向右移,高位补0,低位丢弃(无-)
强制类型转换注意高字节转低字节量时的数据丢失 取后八位
6. 英译汉
请说说下面数据类型的含义,谈谈
const
的作用。
char *const p
。char const *p
。const char *p
。
const 定义常量,则常量的值不能被改变
1)char *const p const修饰的是p,所以p是不能改变的,p所指向的内容是可以改变的
2)char const *p 3)const char *p ||| 2 3都是修饰char *p的所以p可以改变,p所指向的内容是不能改变的
7. 汉译英
请用变量
p
给出下面的定义:
- 含有10个指向
int
的指针的数组。- 指向含有10个
int
数组的指针。- 含有3个「指向函数的指针」的数组,被指向的函数有1个
int
参数并返回int
。
int *p[10]
int (*p)[10]
int (*p[3])(int)
8. 混乱中建立秩序
你对排序算法了解多少呢?
请谈谈你所了解的排序算法的思想、稳定性、时间复杂度、空间复杂度。
提示:动动你的小手敲出来更好哦~
时间复杂度:时间复杂度是一个函数(数学里面带有未知数的表达式),而不是去计算算法跑了多少秒,时间与机器有关,没办法计算具体时间,因此算的是基本操作的执行次数,是大概的。使用大O的渐进表示法。
空间复杂度:空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度,也就是额外占取的空间的大小。
稳定性:排序稳定性指的是对于相同数值,在排序前后是否会发生变化
大家会说冒泡排序是稳定的,若条件改成">=或<="会导致算法不稳定。
//冒泡
#include <stdio.h>
int main()
{
int a[10], i, j, t;
for (i = 0; i < 10; i++)
scanf("%d", &a[i]);
for (i = 0; i < 10; i++)
{
for (j = 0; j < 10 - i - 1; j++)
{
if (a[j] > a[j + 1])
{
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
}
for (i = 0; i < 10; i++)
printf("%d ", a[i]);
printf("\n");
for (i = 9; i >= 0; i--)
printf("%d ", a[i]);
return 0;
}
//快排
#include <stdio.h>
void fx(int arr[], int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d", arr[i]);
}
printf("\n");
}//输出函数;
int gx(int arr[], int low, int high)//获取基准值并实现粗排序;
{
int temp = arr[low];//取最左值作为基准值作为临时保存;
while (low < high)
{
//high指针从后向前遍历 , 元素比基准元素大则指针向前移动 则比基准元素小则和基准元素交换;
while (low < high && arr[high] >= temp)
high--;
if (low < high)
arr[low] = arr[high]; //赋值给第一个元素,因为第一个元素作为基准元素已经临时保存了;
//low指针从前向后遍历 , 元素比基准元素小则指针向后移动 否则比基准元素大则和基准元素交换;
while (low < high && arr[low] <= temp)
low++;
if (low < high)
arr[high] = arr[low];//复制给high指针所指得位置,因为在11行已经赋值给arr[low]了 ;
}
arr[low] = temp;
return low;
}
void hx(int arr[], int low, int high)
{
if (low < high)
{
int base = gx(arr,low,high);//获取基准值
hx(arr,low, base-1);//对左子序列进行快排;
hx(arr,base+1, high);//对右子序列进行快排;
}
}//实现精准排序;
int main()
{
int arr[] = {
0, 1, 3, 5, 6, 9, 8, 7, 4, 2 };
int sz = sizeof(arr) / sizeof(arr[0]);
printf("原序列为:\n");
fx(arr, sz);
hx(arr, 0, sz - 1);
printf("经排序后的序列为:\n");
fx(arr, sz);
return 0;
}//没什么用的主函数;
9. 手脑并用
请实现ConvertAndMerge函数:
拼接输入的两个字符串,并翻转拼接后得到的新字符串中所有字母的大小写。提示:你需要为新字符串分配空间。
char* convertAndMerge(/*补全签名*/);
int main(void) {
char words[2][20] = {
"Welcome to Xiyou ", "Linux Group 2022"};
printf("%s\n", words[0]);
printf("%s\n", words[1]);
char *str = convertAndMerge(words);
printf("str = %s\n", str);
free(str);
}
#include <stdio.h>
#include <string.h>
#include <corecrt_malloc.h>
char* convertAndMerge(char words1[],char words2[])
{
char* str = (char*)malloc(40 * sizeof(char));
sprintf(str,"%s%s", words1, words2);
for (int i = 0; i < 40; i++)
{
if (*(str + i) > 96)
*(str + i) -= 32;
if (*(str + i) > 64 && *(str + i) < 91)
*(str + i) += 32;
}
return str;
}
int main(void) {
char words[2][20] = {
"Welcome to Xiyou ", "Linux Group 2022" };
printf("%s\n", words[0]);
printf("%s\n", words[1]);
char* str = convertAndMerge(words[0],words[1]);
printf("str = %s\n", str);
free(str);
}
10. 给你我的指针,访问我的心声
程序的输出有点奇怪,请尝试解释一下程序的输出吧。
int main(int argc, char **argv) {
int arr[5][5];
int a = 0;
for (int i = 0; i < 5; i++) {
int *temp = *(arr + i);
for (; temp < arr[5]; temp++) *temp = a++;
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
printf("%d\t", arr[i][j]);
}
printf("\n");
}
}
0 1 2 3 4
25 26 27 28 29
45 46 47 48 49
60 61 62 63 64
70 71 72 73 74
int* temp= *(arr+i); 表示从每一行的第一个位置开始放置数字
arr[5] 实际上指的是arr[5][0];其实不在定义的数组范围内,所以当执行完外层循环i=0时,数组的内容是:
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24//赋值25次
外层循环执行i=1时,是从第二行的第一个数字开始赋值//赋值20次
0 1 2 3 4(第一行)得以保留
当i=2,i=3,i=4时同上述操作
11. 奇怪的参数
你了解argc和argv吗?
直接运行程序argc的值为什么是1?
程序会出现死循环吗?
#include <stdio.h>
int main(int argc, char **argv)
{
printf("argc = %d\n", argc);
while (1)
{
argc++;
if (argc < 0)
{
printf("%s\n", (char *)argv[0]);
break;
}
}
}
argc = 1
C:\源\cs\x64\Debug\cs.exe
char argc 记录了用户在运行程序的命令行中输入的参数的个数
char **argv 是指命令行的字符串指针,可以写成char *argv[ ] 即是保存命令行的字符串指针的数组
argc=1 是因为在没有参数传入的情况下,保存程序名称
不会,int最大值是2^31-1,第一位是符号位,用0表示正数,超出最大值就会产生进位将符号位变为1,变成负数,发生溢出。
12. 奇怪的字符
程序的输出有点奇怪,请尝试解释一下程序的输出吧。
int main(int argc, char **argv)
{
int data1[2][3] = {
{
0x636c6557, 0x20656d6f, 0x58206f74},
// u o y i n i L \0
{
0x756f7969, 0x6e694c20, 0x00000000}};
int data2[] = {
0x47207875, 0x70756f72, 0x32303220, 0x00000a32};
char *a = (char *)data1;
char *b = (char *)data2;
char buf[1024];
strcpy(buf, a);
strcat(buf, b);
printf("%s \n", buf);
}
Welcome to Xiyou Linux Group 2022
0X 之后的是16进制数,而机器是从每一个的0X八位数从右往左,每俩个数字为一个单元进行读取,读取后转成10进制数与ascii码对应,进行输出,例如,57对应10进制数为87,所对应的ascii码为W,strcat将俩个数组进行拼接,之后的数字与上述操作相同,所以最后整体输出“Welcone to Xiyou Linux Group 2022”;( 大端序and小端序
strcpy()
strcpy(s1,s2);
拷贝s2到s1;
strcat()
strcat(s1,s2);
连接s2到s1;
13. 小试宏刀
- 请谈谈你对
#define
的理解。- 请尝试着解释程序的输出。
#include <stdio.h>
#define SWAP(a, b, t) t = a; a = b; b = t
#define SQUARE(a) a *a
#define SWAPWHEN(a, b, t, cond) if (cond) SWAP(a, b, t)
int main() {
int tmp;
int x = 1;
int y = 2;
int z = 3;
int w = 3;
SWAP(x, y, tmp);
printf("x = %d, y = %d, tmp = %d\n", x, y, tmp);
if (x > y) SWAP(x, y, tmp);
printf("x = %d, y = %d, tmp = %d\n", x, y, tmp);
SWAPWHEN(x, y, tmp, SQUARE(1 + 2 + z++ + ++w) == 100);
printf("x = %d, y = %d,tmp=%d\n", x, y, tmp);
printf("z = %d, w = %d ,tmp = %d\n", z, w, tmp);
}
x = 2, y = 1, tmp = 1
x = 1, y = 2, tmp = 2
x = 2, y = 2,tmp=2
z = 5, w = 5 ,tmp = 2
define 文本替换
前两行不解释
执行SWAPWHEN(x, y, tmp, SQUARE(1 + 2 + z++ + ++w) == 100);时
SQUARE(1 + 2 + z++ + ++w) 执行俩次 z=5 w=5
if 只决定tmp=x 之后的东西都执行
14. GNU/Linux命令 (选做)
你知道以下命令的含义和用法吗:
注:
嘿!你或许对Linux命令不是很熟悉,甚至你没听说过Linux。
但别担心,这是选做题,不会对你的面试产生很大的影响!
了解Linux是加分项,但不了解也不扣分哦!
ls
rm
whoami
请问你还了解哪些GNU/Linux的命令呢。
ls命令是指打开指定的文件及其文件夹清单
rm命令是强大的删除命令,它可以永久性地删除文件系统中指定的文件或目录
whoami命令的作用是显示当前有效用户的用户名