慕课网>Linux C语言编程基本原理与实践
笔记:
cd
cd ~ 回到根目录
pwd 查看当前所在位置
ls list
ls -l 详细信息 long
ls -a 显示所有(包括隐藏) all
mkdir make directory
touch 创建文件
rm remove
cd 目录名/
clear 清空面板
vim 命令模式,编辑模式,最后行模式
ESC 与 i (insert) 进行切换命令模式和编辑模式
: 进入最后行模式 输入命令,一般用来执行查找特定的字符串、保存及退出等任务
命令模式下:
i 当前光标前编辑(默认)
shift+i 行首插入(大写的i)
a 当前光标后编辑
shift+a 行尾插入
o 下一行
shift+o 上一行
x 删除
dd 整行删除
:w 保存 write写入
:q 退出vim编辑器
mv 对文件或文件夹进行重命名和移动
缩进:4个空格=1个tab
执行:./文件 .表示当前路径,此句表示打开当前路径下的文件
多个源文件分而治之
:sp 文件名
ctrl + w + ↓
数字+dd
数字(表示几行)+yy 复制几行
p 粘贴
:wqa 所有文件都进行保存后退出 all->write->quit
-o 文件名 执行后输出的文件名(如文件编译后的文件名)
:set nu 打开显示行号
#include " " 相对路径下的引入
gcc命令:
gcc -c max.c -o max.o
cp 拷贝
cp a.c b.c 将a.c文件拷贝给b.c
cat a.c 查看a.c文件
头文件与函数定义分离:自己编写头文件
max.h 文件内容为: int max(int a,int b);
rm *.o 删除所有.o结尾的文件
makeFile的编写
Makefile 约定文件之间的依赖
#this is make file --注释
main.out:max.o min.o main.c
gcc max.o min.o main.c -o main.out -- 这一行一定要用 Tab 键
max.o:max.c
gcc -c max.c -- -c选项:编译或汇编源文件,但是不作连接.编译器输出对应于源文件的目标文件
min.o:min.c
gcc -c min.c
指令1 && 指令2 连接两条指令,指令1必须执行成功时(返回0)才执行指令2
echo $? 检查错误和异常
int main(int argv,char* argc[])
argv %d 操作系统传递参数的个数
argc[] %s 操作系统传递进来的参数
Linux的标准输入流, 输出流, 错误流
stdin stdout stderr
资源句柄
fprintf printf相当于是对fprintf的封装
fscanf scanf相对于是对fscanf的封装
Linux通道
输出流重定向
> 覆盖
>> 追加
输入流重定向
< 依次输入
./a.out 1>t.txt 2>f.txt
系统默认的0是标准输入流,1就是标准输出,2就是标准错误流
管道原理及应用
ls /etc/ | grep ab
输出流 管道 输入流
grep 文件搜索
grep a,b 搜索包含ab的文件
ps -e 查看所有进程
ps -e | grep ssh 搜索所有进程中包含ssh服务的进程
管道( | ) 将两个独立功能的程序结合到一起
./input.out | ./avg.out
慕课网>Linux C语言指针与内存
gdb 打断点,单点调试
gcc -g main.c -o main.out 方可支持调试(此时源代码不能删除)
cp 文件1 文件2 将文件1复制为文件2
gdb ./main.out 调试main.c经过编译后的可执行文件main.out
(gdb) 调试状态,后面输入调试命令
l (list) 列出当前源代码(默认显示10行)
回车(Enter) 继续执行之前的命令(比如上一个命令是l:按回车可显示未显示完的内容)
start 开始调试
p 变量 print 打印显示变量的值
n 向下执行(一行一行的执行,包括函数一行,不进入函数)
s 进入函数里面
bt 查看函数堆栈
f + 数字 切换相应数字对应的函数栈
q 退出调试(quit)
x/数字+格式 地址 例如 x/3d 0x7fffffffb3e0
x/3d 0x7fffffffb8ec 从地址0x7fffffffb8ec连续打印按10进制数值输出的3个数
人与计算机进行交互
二进制:高电位,低电位
内存 1字节(Byte)=8个二进制 位
计算机:二进制
显示:十进制
编程:十六进制(0x)
内存管理
1字节=8位
32位操作系统:最大使用4G内存,因为其是32位地址总线,寻址空间32位:
地址总线可存在多种状态
给内存编号只能编到32个二进制位 2的32次方个字节=4G字节,
64位操作系统:理论上支持最大内存:2的64次方字节
操作系统管理内存
1.操作系统会对所有内存进行编号,还会给内存进行一定的规划
2.用户内存与操作系统内存分离开
代码编译后的二进制数据加载到内存中
编号=唯一的内存字节的地址
内存占用不确定
应用程序是由操作系统来调用
内存使用:操作系统内核,用户
内存:
系统内核
栈 可修改
自由可分配的内存
堆 可修改
数据段:全局变量或常量
代码段:代码声明的变量;代码经过编译过后存在代码段,不允许随便修改
栈保存:(以下只表示一部分)
当前调用哪个函数;
当前调用的函数运行到多少行;
这个函数有哪些变量,这些变量的值是什么
变量的本质:变量名就是一个代号(标识作用),变量的本质就是内存
指针保存的就是内存地址
gcc编译器的优化(让CPU操作指令更方便,更快;提高程序指令的执行的效率;对源代码做一定的优化)
变量地址分配顺序和代码中变量声明的顺序可能不一样)
内存变量分配的地址是连续的
同一类型的变量声明放在一起:相同类型的变量地址放在一起(比如整形变量一起,指针变量一起)
32位操作系统:指针变量(地址)占4个字节 4X8=32
64位操作系统:指针变量(地址)占8个字节 8X8=64
函数栈
按代码执行顺序往后,就越到栈顶,地址就越小,
静态变量和全局变量:数据段
函数指针
*+地址 通过地址找里面的值
p &pquadrate $2 = (int (*)(int)) 0x400564 <quadrate> 表示在代码端
(*quadrate) 指向代码段,在代码段里取值 认为指向的是一个函数
int quadraate(int a);是一个函数
int (*pquadrate)(int a)=&quadrate;将指针pquadtate指向函数quadrate!
int s=(*pquadrate)(a)可以调用quadtate函数,这种操作常用于回调函数
数组、指针运算
gdb命令:x(打印内存值)/3(输出3个值)d(十进制显示) 0xffffff(开始地址)
x/3d 0x7fffffffb8ec 从地址0x7fffffffb8ec连续打印按10进制数值输出的3个数
x/1cb 0x400710 从地址0x400710打印1个单位为bit的一个字符,c:char b:bit
int *p;
p[3] -> p+=3;
p++ 没加依次,地址向后移动4个字节(int型)
指针偏移 -> 效率高,性能好
int array[2]; array表示地址,是一个指针常量。 不能写array++;
声明指针不会创建用于存储的内存空间。
指针声明时,指向的位置不确定,程序运行时,如果你运气好可能不出错,但是下次动态分配内存的时候你可能就没这么幸运了。
例子:
int *a;
*a=12;
这是一个典型的错误:因为在分配内存时你无法确定 a 指向的位置,所以你下次 *a或者访问a时,可能带来:Program received signal SIGSEGV, Segmentation fault.
共同学习,写下你的评论
评论加载中...
作者其他优质文章