第一阶段 C基础Word格式.docx
《第一阶段 C基础Word格式.docx》由会员分享,可在线阅读,更多相关《第一阶段 C基础Word格式.docx(20页珍藏版)》请在冰豆网上搜索。
![第一阶段 C基础Word格式.docx](https://file1.bdocx.com/fileroot1/2023-1/26/6ae96318-5a69-49be-9ff1-f315a01c1b0a/6ae96318-5a69-49be-9ff1-f315a01c1b0a1.gif)
终端:
ibus-setup-->
yes-->
inputmethod-->
chinses-pinyin-->
ok
汉字输入切换快捷键:
ctrl+空格
7.vi编辑器的使用
(1)vi文件名.c打开文件或者新建文件
使用vi打开文件后
分为3种模式:
命令模式命令行模式(底行模式)输入模式(插入模式)
(2)命令行模式下:
保存w退出q
q!
不保存退出
w+文件名将当前文件内容存放到新文件里面
vsp文件名同一个终端打开另一个文件
sp文件名
复制多行:
首行行号,尾行行号y
跳到836行:
836
取消高亮:
nohl
替换操作:
:
%s/将被替换字符/替换字符/g
首行号,尾行号s/将被替换字符/替换字符/g
注意:
不加/g表示替换每行收索到的第一个字符串
命令模式下:
shift+zz保存退出
复制1行:
将光标放在这一行任意位置yy
粘贴:
p
复制n行:
将光标放在首行,输入nyy
跳到首行gg
跳到尾行G
撤销u
在终端复制一个文件:
cp源文件目标文件
注意:
将以上情况所有的y换成d就是剪切
8.在vi中使所写程序对齐
第一步:
光标在首行,shift+v,跳到尾行shift+g完成全选
第二步:
按下“=”键
9.gcc的使用:
(1)-E选项(预处理阶段)
gcc-E-oconst.iconst.c//说明:
-E选项是编译器在预处理结束就结束,不进行接下来的编译处理
-o选项是指定输出文件的名字为const.i此文件是经过预处理之后的文件,可以vi查看该文件经预处理之后的结构
(2)-S选项(编译阶段)
gcc-S-oconst.sconst.i//说明:
-S选项是在使编译器进行完编译就结束,编译将预处理得到的文件转换成汇编文件
(3)-c选项(汇编阶段)
gcc-cconst.s-oconst.o//说明:
-c选项是把编译阶段生成的.s文件生成目标文件(二进制文件)
(4)连接阶段
gccconst.o-oconst//说明:
最后阶段是将目标文件连接得到可执行文件
10.关于函数库
函数库包括静态库和动态库两种;
静态库:
是代码在编译时就已经连接到应用程序中;
动态库(共享库):
是在程序运行时被加载,动态库必须存在应用程序所要运行的系统中。
第二天计算机基础
1.二进制八进制
eg:
1010转换成八进制
12
001,01012
2.8421码
3216841
补充1:
二进制小数和十进制小数的表示
十进制小数:
12.3456
小数部分:
3/10+4/100+5/1000+6/10000......
二进制小数:
11.011111
1/2+1/4+1/8+1/16......
二者表示方法不一样,所以小数在计算存储的时候是存在误差的,这些误差是会累积的,在涉及大量浮点数计算的时候,可能会出错
3.man命令
manascii//查看ascii表
man3库函数名//查找库函数
4.define不是关键字
sizeof是关键字,c中32个关键字
c语言中4中存储类型:
auto,extern,static,register
5.字符串常量
char*p="
hello"
;
*(p+1)='
w'
//出错
charp[]="
//正确
6.++运算:
++i作为前缀:
i值先自增,在参与运算;
i++作为后缀:
先取出i值参与运算,待整个表达式运行完成之后,i自增
intk=9;
k=k+++++k;
分析:
由于++的优先级高于+,所以先算++k,即:
k=9+1=10
+是由左至右结合,所以,变成k=10+10
计算结果k=20;
最后整个表达式结束k再++;
所以,最终结果是21
7.intx=100;
if(x=0)//表达式值为假
8.ctrl+shift+n//在当前终端下,打开另一个终端,并且新终端的路径和当前终端路径一样
9.配置共享文件夹
(1)虚拟机VMware-->
VM-->
InstallVMwareTools
(2)终端下
cd/media
cd/VMwareTools\
cpVMwareTools-9.2.2-893683.tar.gz~
cd~
tar-zxvfVMwareTools-9.2.2-893683.tar.gz
cdvmware-tools-distrib/
sudo./vmware-install.pl
(3)在虚拟机VMware下VMware-->
setting-->
Options-->
SharedFolders-->
Alwaysenabled-->
add-->
设置windows下共享文件夹
(4)cd/mnt/hgfs
ls看到共享的文件夹
linux下文件传到window下:
cp文件/mnt/hgfs/文件夹
cp目录/mnt/hgfs/文件夹-a
window下传到linux下:
直接复制到共享的文件夹下
10.标识符
(1)以数字字母或者下划线组成
(2)不能以数字开头
(3)不能与关键字重名
11.动态类型:
auto
寄存器存储类型变量
函数形参、
静态类型:
全局变量
静态局部变量
静态全局变量
12.查看一个可执行程序的运行时间
time./可执行文件
register提高程序的执行效率
第三天
1.深入理解数据类型
数据类型分为4种:
基本数据类型:
intcharfloatemun
构造数据类型:
数组、结构体、共用体
空类型:
指针类型:
指针
int[]
//数组类型
int(*)[]//指针数组类型
int*[]
//数组指针类型
int*
//指针类型
int*()
//指针函数
int(*)()//函数指针
2.运算符结合方式
左结合:
&
||先运算左边的表达式值,再运算右边表达式的值
右结合:
反之
3.sizeof(各种类型或者变量)
4.运算符优先级
!
>
算术运算符>
关系运算符>
&
和||
5.终端下
vim-t数据类型eg:
vim-tdev_t
ctrl+]//跟踪宏定义
第四天
1.利用do~while来当做{}使用,避免在使用宏定义的时候出现问题
参考内核中优秀的代码,记录下来借鉴使用
#include<
stdio.h>
voidfun(void)
{
printf("
hello\n"
);
}
#defineMAROC(y)do{if(y==0)fun();
}while(0);
//
//#defineMAROC(y)if(y==0)fun();
//直接使用这个宏的话会出现问题
intmain(intargc,constchar*argv[])
intx=1;
inty=0;
if(x)
MAROC(y)
else
world\n"
do{
if(y==0)
fun();
}while(0);
return0;
2.对数组初始化可以使用memset函数
inta[10];
memset(a,0,sizeof(a));
或者
bzero(a,sizeof(a));
3.求数组中元素的个数
元素个数=sizeof(数组名)/sizeof(数据类型)
第五天
1.指针
int*p[2];
//数组p本身就是一个地址量,现在又int*,所以p是指针的指针,属于二级指针
int**p1;
p1=p;
理解:
由于p是数组,所以p代表&
p[0],又由于p[0]是int*,所以,&
p[0]是int**,即:
p是二级指针
2.*p++和(*p)++是不同的
(*p)++是取出内容再自加;
3.数组下标越界出现死循环
第六天指针
1.int**p;
ints[10]={0};
p=&
s;
//这种写法是不正确的,&
s+1则地址偏移10*4;
p+1,偏移4个字节,所以寻址方式不一样
2.由字符型的指针来访问存储中的每一个字节
unsignedinta=0x12345678;
unsignedchar*p;
p=(unsignedchar*)&
//注意:
p是指向unsignedchar类型的指针,unsignedint在内存中存储占据4个字节
//可以使用unsignedchar类型指针来操作unsignedint内存中的单个字节
%x\n"
*p);
*(p+1));
*(p+2));
%x\n\n"
*(p+3));
*(p)=0x55;
*(p+3)=0xfa;
3、const只存在在汇编之前,汇编之后const的修饰就不起作用了
4、void类型,是未定义类型;
未确定用来做什么的类型
第七天指针
1.inta[3][3],int(*p)[3],int**pp的区分:
a是一个二级指针地址,但是a+1是跳转一个有三个元素的一维数组的大小;
pp是一个二级指针变量,里边存储着的是一个地址值,pp+1是跳转4个字节大小;
a和pp两者寻址方式不一样;
数组指针访问二维数组:
2.数组名和指针变量寻址方式:
inta[3];
int*p;
p=a;
*(a+1)=10;
*(p+1)=20;
//两者寻址方式不一样
假设a=0x1234这个地址值,那么a+1是在0x1234的基础加上4等于0x1238,是属于直接寻址
而,*(p+1)则是取出p中存放的地址值,再在此地址值上加上偏移值
3.进程的内核结构
Linux中使用的是虚拟内存技术,使得每个进程都有自己独立的内存空间,该地址空间是4GB,其中用户空间能够访问0~3GB,内核空间3GB~4GB;
通常情况下,应用程序只能访问用户空间的虚拟内存。
用户空间包括以下几个功能区域:
(1)只读段:
包括程序代码(.init和.text)和只读数据(.rodata)
(2)数据段:
存放全局变量和静态变量
(3)栈:
由系统自动分配,存放函数的参数值、局部变量值、返回地址等
(4)堆:
存放动态分配的数据,一般由程序员分配和释放
(5)共享库的内存映射区:
Linux动态链接器和其他共享库代码的映射区;
cat/proc/进程号/maps
查看某一个进程的内存分布情况
4.字符串常量赋值操作出现问题:
charstr[]="
str中的内容是存在栈区,是由系统自动分配的,在栈区的内容是可以改变的;
而char*p="
helloworld"
中"
字符串常量是存储在静态只读区的(.text),是不可以改变的,指针变量p只是指向这块静态存储区,而不能改变其内容;
可查看汇编语句来分析;
所以,*(str+3)='
z'
//是可以赋值的,栈区的内存是可读可写的
*(p+3)='
//这样赋值是不可以的;
5、指针操作总结
int*p=&
int*p=(int*)0x1234;
//确定地址是什么
int*q=&
int*p=q;
int*p=NULL;
p=&
p=(int*)0x1234;
char*q;
p=(int*)q;
p=(int*)a;
//要知道自己干嘛呢
*p++//指针运算符*和++的优先级相同,自右向左结合,所以,先是*p,然后再++
(*p)++
int**p=&
p;
a=10==**p=10
p=(int*)&
//
*(p+1)==a[1]==p[1]
*(a+1)
constint*p;
//*p只读
intconst*p;
int*constp;
//p只读
constint*constp;
//p*p只读
//*((int*)&
a)=10;
void和void*p:
是未确定用来做什么的类型
6、关于const
const只存在于汇编之前,预处理阶段,汇编之后const修饰只读的功能就不存在了
intconsta=9;
//修饰变量a中值是不可改变的,但是想改变的话,使用下面的方法
*((int*)&
//使用指针来绕开const的修饰,但是不建议这么用
7、指针函数
指针函数不可以返回局部变量的地址
可返回的地址有三种:
(1)静态变量的地址
(2)字符串常量的地址
(3)堆上的地址,例如:
malloc分配的空间的地址可以返回
8、define和#define
define不是关键字
#define也不是关键字,是属于预处理器
9、函数指针和指针函数
10、signal函数分析
可以这么理解:
void(*)(int)
signal(intsig,
handler)//是一个返回值是函数指针类型,参数也是带有函数指针类型
void(*signal(intsignum,
void(*handler)(int)
)
)(int);
void(*p)(int)//最外层函数是这种类型的
void(*handler)(int)
//是函数指针类型,其所指向的内容为返回值为void,函数参数int,即:
voidhandler(int)
signal(intsignum,函数指针类型)//这个函数返回的是一个函数指针类型,此函数的参数是int和函数指针类型
返回函数指针,该函数怎么写?
?
答:
见专题二
第八天函数
1、函数的复制传参
在main函数中,定义两个变量a,b
intfun(inta,intb)
returna+b;
intmain(intargc,constchar**argv)
inta,b;
fun(a,b);
return0;
局部自动变量是存储在栈区的,函数刚开始执行时,sp指向main函数的栈区,当调用函数fun的时候,将传入的参数拷贝到fun函数的栈区,所以对fun函数的栈区操作,不会影响到主函数中的变量的值;
2、函数地址传递
如果函数fun定义如下:
intfun(inta,int*p)
*p=*p+a;
return*p;
main函数中调用如下
fun(a,&
b);
程序栈区的存储分布情况:
3、由1、2的分析,结构体作为函数的参数传入到函数中时,如果结构体比较大的话,会占用大量的栈区,最后可能会栈溢出;
所以,在操作结构体时,尽量传入结构体的指针来操作;
4、malloc使用注意:
malloc分配的内存空间是在堆区,堆区的内存系统不会自动释放和回收,需要程序员手动分配和释放。
malloc使用模版:
unsignedchar*p=NULL;
if(NULL==(p=(unsignedchar*)malloc(szieof())))
分配失败;
.
free(p);
p=NULL;
第十天测试
1、鞍点,一个二维数组中,一行中的最大值,一列中的最小值
2、
///////////////////////////////////////////////////////////////////////////////////////
补充:
1、printf函数首先是将数据放到缓冲区中,不立刻打印出来,而是要遇到'
\n'
的时候才能够打印出缓冲区中的数据
unistd.h>
inti=0;
//不立刻打印出来
sleep(3);
//延时3秒之后
\n"
//遇到\n才打印出来