Linux的常用工具
1.vim编辑器 vi(是老版本) 但是我们一般都是用vim 两者的差别并不大
2.gcc工具链就是编译器
3.make和Makefile
4.gdb调试工具
5.Shell使用基础
注意一点我们平时用的Linux一般是指内核,而Linux发行版则是加了一些模块使其更具有针对性,常常运用于不同的方面,也就是它的侧重点不同。
vim有三种模式:命令行模式(控制光标的移动,字符 字 行的删除)
插入模式(输入文字)
底行模式(保存文件,推出,设置vi)
我们通过命令 vim /etc/vimrc 打开Red hat....
通过命令 vim /etc/vim/vimrc 打开Ubuntu
进入之后然后我们可以设置一些命令比如
set autoindent 自动缩进
set shiftwidth
这两个命令是设置tab键长度为4的
set tabstop
set number 行号
syntax on 设置关键字高亮
注意这些命令要输入在最后的endif下方
我们在命令行模式的时候有一些快捷键可以使用
G:跳到最后 gg:跳到第一行 x:删除字符 dd:剪切一行 D:剪切一行 3dd:剪切三行
yy:复制一行 3yy:复制三行 u:撤销
在切换到插入模式的时候,按A光标会后移一位 而按 I 就不会移动
在底行模式中
set nonu 取消行号 set nu 列出行号
%s/main/xxx/g 可以把全文中的main替换为xxx
gcc实际上过程分为四步(在编译的时候我们可以通过加-o 文件名 来改名字。比如gcc test.c -o test)
第一步是预处理
我们通过预处理来处理所有以#开头的代码(比如说头文件展开)
gcc-E test.c -o test.i
第二步是编译
我们通过编译首先是语法检查,然后是把C语言翻译成汇编语言。
gcc -S test.c -o test.s
第三步是汇编
我们通过汇编来把汇编语言编译成二进制文件
gcc -c test.s -o test.o
第四步是链接
我们通过链接把该文件所需要的库文件链接过来
gcc test.o -o test
Makefile(工程管理器)
make是一个命令 在当前目录找Makefile文件(一个文件夹只能有一个)
target(目标):dependency(依赖)
(Tab字符)command
注意一点这个comman前面一定不是空格,而是一个Tab字符。
gdb也就是一种调试工具
我们可以先创建一个test.c的文件,然后对它进行编译也就是 gcc test -o test -g 。这样我们就能得到一个命名为test的文件,
然后我们打出 gdb test 这个命令,然后就会进入gdb模式可以对这个文件进行操作。
在这个模式下我们也有一套指令可以使用,比如:
list(l)列出源码 l 5 就是以第五行为中间行列出十行源码
break(b)设置断点 b 5 就是在第五行设置断点(在第五行是不运行的)
run(r)运行
contine(c)继续运行
next(n)执行一句(不进入被调函数中)
step(s)向下执行一句(可进入被调函数中)
info 查看信息 info b 查看断点信息
delete 删除断点 (有的电脑需要在后面加b)(在后面加数字可以选择删除第几个断点)
print(p)显示变量值
quit(q)退出
return 返回 (剩下的函数执行完,再跳出)
shell(脚本的一种)是命令解析器,将用户输入指令转化为机器运行程序
我们在创建文件时可以这样,比如说 vim test.sh 。然后在写程序开头时注意一定要写绝对路径,比如
#!/bin/bash
在完成文件之后需要更改一下文件权限。
1.全局变量与局部变量的区别以及两者的优先级关系
区别:全局变量作用于整个源程序文件,而局部变量只是作用于某个具体的函数内。在c语言中,main函数的局部变量也仅能在main函数中使用,在其他函数中亦不可使用。
优先级关系:当在同一个源文件中时,若外部变量和局部变量同名,则在局部变量的作用范围内,外部变量被屏蔽,不起作用。
2.声明与定义的区别
定义的形象的理解就是一旦一个对象被分配到一个内存,那么这个名字就和这块内存匹配起来,永远只能定义一次;至于声明的理解需要分为两个层面:第一点,声明可以出现多次;第二点,别的地方不可再用它作为变量名或对象名。
3.关于逻辑运算符
则整个事件也就为假;同时只要A为 对于||而言,只要A||B中,A事件为真,则B事件就不需要再考虑,则整个事件也就为真;A事件为假,则整个事件也就为假。书中例子:if((++i>0)||(++j>0)),如果(++i)>0,如果为真则不再计算。
4.关于条件运算符
条件运算符的一般形式是:表达式1?表达式2:表达式3
其含义很简单,若表达式1为真,则以表达式2的值作为表达式的值,否则是表达式3的值作为返回值;其次要注意条件表达式的优先级虽然低于关系运算符和算术运算符,但是要高于赋值符。
5.关于(++i)和(i++)的区别
如果有表达式a=i++,则其等价于a=i; i=i+1;如果有表达式a=++i ,则其等价于 i=i+1;a=i;
6.c语言中{;}什么意思?
这相当于while(1);死循环。for语句的一般形式如下:for(表达式1;表达式2;表达式3)(需要执行的语句); 其执行过程是:表达式1首先执行且只执行一次;然后执行表达式2,通常都是一个用于判定条件的表达式,如果表达式2条件成立,就执行(需要执行的语句);然后再执行表达式3;再判断表达式2,再执行表达式3…..一直到表达式2不成立时,跳出循环往下执行。
7.关于常量以及const int *p以及 int * const p的区别
常量所在内存空间被加上了只读属性,因此其值不会变;对于const的处理:将除了const的语句外的类型修饰符去掉即可。 const int *p去掉int后就是const *p,因而p指向的空间的值不会变;然而,int * const p去掉int *之后就变得不一样了。 const p即p不可再变,p不可指向别的地址,但是p所指向的内容可变。
8.寄存器变量的使用
程序是保存在内存中的,因为cpu的速度远远快于内存和寄存器,而寄存器的速度又要远远快于内存(与两者的物理结构和造价体积大小有关),因此在操作过程中一般是cpu先从内存取出数据到寄存器中,运算完后再送回到内存中。在我们设置寄存器变量的过程中,考虑到寄存器的速度快,因此寄存器变量的优势在此。
但是寄存器变量不可设置太多,一方面因为寄存器可能被其他程序占用;另一方面寄存器变量必须是cpu能接收的类型。我们还要注意到寄存器变量是没有地址的,因而不可以使用区地址符。
9.typedef与#define的区别和联系
两者的联系typedef与#define两者都可以用来定义,两者的区别也很明显,对于typedef是为一个新的类型起新名字,但是对于#define只是简单的字符串替换。因而在涉及到有指针最好用typedef,当有表达式则必须加个括号才能成功定义。
10.关于运算符优先级的记忆方法
!>算术运算符>关系运算符>&&>||>赋值运算符