
Linux是一种开源的Unix-like操作系统内核,它是基于POSIX和Unix的多用户、多任务、支持多线程和多CPU的操作系统。Linux内核最初是由芬兰程序员Linus Torvalds在1991年创建的,之后成为自由软件和开源社区的一个主要项目。 以下是Linux操作系统的一些主要特点和组成部分:
总体而言,Linux操作系统是一个强大、灵活且可定制的操作系统,广泛应用于服务器、嵌入式系统、超级计算机等各种领域。
1.编译器gcc的使用
(1)编辑一个C语言程序文件 hello.c ,代码如下:
#include <stdio.h>
main()
{
char name[20];
printf(“Please input your name :”);
scanf(“% s”, name);
printf(“Welcome % s !\n”, name);
return 0;
}(2)编译文件: gcc -o hello hello.c。
(3)若有错误,修改hello.c的内容,然后再次编译,直至没有错误为止。
解:
(1)编辑一个C语言程序文件 hello.c ,代码如下:
#include <stdio.h>
main()
{
char name[20];
printf(“Please input your name :”);
scanf(“% s”, name);
printf(“Welcome % s !\n”, name);
return 0;
}在终端输入vim hello.c,将示例代码输入到hello.c结果显示如下:

退出保存,文件夹多了hello.c文件夹

(2)编译文件: gcc -o hello hello.c。
(3)若有错误,修改hello.c的内容,然后再次编译,直至没有错误为止。
在终端输入gcc -o hello hello.c结果显示报错如下所示:

回到源码hello.c,我们根据报错信息分段分析。
第一段:
hello.c:2:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
2 | main()
| ^~~~
hello.c: In function ‘main’:
hello.c:5:10: error: stray ‘\342’ in program
5 | printf(���Please input your name:”);
| ^
hello.c:5:11: error: stray ‘\200’ in program
5 | printf(���Please input your name:”);
| ^
hello.c:5:12: error: stray ‘\234’ in program
5 | printf(��Please input your name:”);
| ^
hello.c:5:13: error: ‘Please’ undeclared (first use in this function)
5 | printf(“Please input your name:”);
| ^~~~~~
hello.c:5:13: note: each undeclared identifier is reported only once for each function it appears in
hello.c:5:19: error: expected ‘)’ before ‘input’
5 | printf(“Please input your name:”);
| ^~~~~~
| )
hello.c:5:36: error: stray ‘\342’ in program
5 | printf(“Please input your name:���);
| ^
hello.c:5:37: error: stray ‘\200’ in program
5 | printf(“Please input your name:���);
| ^
hello.c:5:38: error: stray ‘\235’ in program
5 | printf(“Please input your name:��);这一段显示源码的错误提示是因为代码中使用了不可见的特殊字符,导致编译器无法识别。可以很容易发现源码中的printf(“Please input your name:”);的双引号使用的是中文模式输入,故将其改成printf("Please input your name:");
第二段:
hello.c:6:9: error: stray ‘\342’ in program
6 | scanf(���%s”,name);
| ^
hello.c:6:10: error: stray ‘\200’ in program
6 | scanf(���%s”,name);
| ^
hello.c:6:11: error: stray ‘\234’ in program
6 | scanf(��%s”,name);
| ^
hello.c:6:12: error: expected expression before ‘%’ token
6 | scanf(“%s”,name);
| ^
hello.c:6:14: error: stray ‘\342’ in program
6 | scanf(“%s���,name);
| ^
hello.c:6:15: error: stray ‘\200’ in program
6 | scanf(“%s���,name);
| ^
hello.c:6:16: error: stray ‘\235’ in program
6 | scanf(“%s��,name);
| ^这一段显示源码的错误提示仍然是因为代码中使用了不可见的特殊字符,导致编译器无法识别。可以很容易发现源码中的scanf(“%s”,name);的双引号使用的是中文模式输入,故将其改成scanf("%s",name);
第三段:
hello.c:7:10: error: stray ‘\342’ in program
7 | printf(���Welcome %s!\n”,name);
| ^
hello.c:7:11: error: stray ‘\200’ in program
7 | printf(���Welcome %s!\n”,name);
| ^
hello.c:7:12: error: stray ‘\234’ in program
7 | printf(��Welcome %s!\n”,name);
| ^
hello.c:7:13: error: ‘Welcome’ undeclared (first use in this function)
7 | printf(“Welcome %s!\n”,name);
| ^~~~~~~
hello.c:7:22: error: ‘s’ undeclared (first use in this function)
7 | printf(“Welcome %s!\n”,name);
| ^
hello.c:7:23: error: expected ‘)’ before ‘!’ token
7 | printf(“Welcome %s!\n”,name);
| ^
| )
hello.c:7:24: error: stray ‘\’ in program
7 | printf(“Welcome %s!\n”,name);
| ^
hello.c:7:26: error: stray ‘\342’ in program
7 | printf(“Welcome %s!\n���,name);
| ^
hello.c:7:27: error: stray ‘\200’ in program
7 | printf(“Welcome %s!\n���,name);
| ^
hello.c:7:28: error: stray ‘\235’ in program
7 | printf(“Welcome %s!\n��,name);这一段显示源码的错误提示仍然是因为代码中使用了不可见的特殊字符,导致编译器无法识别。可以很容易发现源码中的printf(“Welcome %s!\n”,name);的双引号使用的是中文模式输入,故将其改成printf("Welcome %s!\n",name);
此时改后的代码为:

此时进行编译报错如下:

提示错误是由于没有定义main()的类型,故将main函数前加上int,最终修改版代码如下:

再次进行编译结果显示通过如下:

输入./hello运行结果如下:

2.使用GDB 调试程序BUG(教材12.7节)
(1)使用文本编辑器输入以下代码greet.c。程序试图倒序输出main 函数中定义的字符串,但结果没有显示。
#include <stdio.h>
int display1(char *string);
int display2(char *string);
main()
{
char string[] = “Welcome to Linux !”;
display1(string);
display2(string);
}
int display1(char *string)
{
printf(“The original string is % s \n”, string);
}
int display2(char *string1)
{
char *string2;
int size, i;
size = strlen(string1);
string2 = (char *)malloc(size + 1);
for (i = 0; i < size; i++)
{
string2[size - i] = string1[i];
}
string2[size + 1] =’’;
printf(“The string afterward is % s\n”, string2);
}(2)使用gcc –g 的选项编译这段代码,运行生成的可执行文件,观察运行结果。
(3)使用gdb 调试程序,通过设置断点、单步跟踪,一步步找出错误所在。(调试过程需截图)
(4)纠正错误,更改源程序并得到正确的结果。
解:
在终端输入vim greet.c,输入以上示例为:

输入gcc -o greet greet.c进行编译结果如下:

回到源码greet.c,我们根据报错信息分段分析。
第一段:
greet.c:4:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
4 | main()
| ^~~~这里错误提示为main()函数无类型,故在main()前加上int。
第二段:
greet.c: In function ‘main’:
greet.c:6:17: error: stray ‘\342’ in program
6 | char string[] = ���Welcome to Linux!”;
| ^
greet.c:6:18: error: stray ‘\200’ in program
6 | char string[] = ���Welcome to Linux!”;
| ^
greet.c:6:19: error: stray ‘\234’ in program
6 | char string[] = ��Welcome to Linux!”;
| ^
greet.c:6:20: error: ‘Welcome’ undeclared (first use in this function)
6 | char string[] = “Welcome to Linux!”;
| ^~~~~~~
greet.c:6:20: note: each undeclared identifier is reported only once for each function it appears in
greet.c:6:28: error: expected ‘,’ or ‘;’ before ‘to’
6 | char string[] = “Welcome to Linux!”;
| ^~
greet.c:6:37: error: stray ‘\342’ in program
6 | char string[] = “Welcome to Linux!���;
| ^
greet.c:6:38: error: stray ‘\200’ in program
6 | char string[] = “Welcome to Linux!���;
| ^
greet.c:6:39: error: stray ‘\235’ in program
6 | char string[] = “Welcome to Linux!��;
| 这里错误提示为main()函数内的引号输入为中文模式下输入,需更改为英文状态。根据源码可以很容易发现其他的引号也均需要修改。
第三段:
greet.c: In function ‘display2’:
greet.c:20:8: warning: implicit declaration of function ‘strlen’ [-Wimplicit-function-declaration]
20 | size = strlen(string1);
| ^~~~~~
greet.c:20:8: warning: incompatible implicit declaration of built-in function ‘strlen’
greet.c:2:1: note: include ‘<string.h>’ or provide a declaration of ‘strlen’
1 | #include <stdio.h>
+++ |+#include <string.h>
2 | int display1(char *string);
greet.c:21:19: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
21 | string2 = (char *)malloc(size + 1);
| ^~~~~~
greet.c:21:19: warning: incompatible implicit declaration of built-in function ‘malloc’
greet.c:2:1: note: include ‘<stdlib.h>’ or provide a declaration of ‘malloc’
1 | #include <stdio.h>
+++ |+#include <stdlib.h>
2 | int display1(char *string);
greet.c:26:17: error: empty character constant
26 | string2[size+1]='';这个错误提示包含了三个问题:
修改源码如下:

输入gcc -g test.c -o test进行编译结果如下:

输入./ greet


在23行(for循环处)设置断点:b 24;在29行(printf函数处)设置断点:b 29。此时输入info b查看断点设置情况。

输入r运行代码,也可输入n单步运行代码,继续单步运行代码数次,并使用命令查看,发现string2[size-1]的值正确。

继续程序的运行:c
在程序中,第24行代码为:string2[size-i] = string1[i];,这个语句是将字符串string1中的每个字符倒序复制到另一个字符串string2中。但是,在循环中,i的取值范围是从0到size-1,因此在第一次循环中,string2[size-i]实际上是string2[size-0],即string2的最后一个字符,而不是第一个字符。这会导致第一个字符无法被正确赋值。 为了解决这个问题,可以将循环的范围修改为从0到size。这样,在第一次循环中,string2[size-i]就会被正确地赋值为string1中的第一个字符,而不是最后一个字符。修改后的代码如下所示

重新进行编译,结果显示通过。

Linux操作系统的领域就像一片未被勘探的信息大海,引领你勇敢踏入开源系统的神秘领域。这是一场独特的学习冒险,从基本概念到系统架构,逐步揭示更深层次的操作系统原理、命令行工具和高级系统管理的奥秘。