我的c语言编程基于Linux操作系统,使用VmWare的Ubuntu20.04版本
VmWare --虚拟机--通过软件模拟出一个完整硬件的环境。
Ubuntu--linux操作系统的一个发行版本。
操作系统
1.操作系统是一个软件
2.管理硬件资源
3.为上层的应用层序提供简单易用的接口。
采用Linux操作系统是由于其有以下优点
1.开源、免费
2.内核可裁剪
3.linux一切皆文件
4.linxu文件系统像是一颗倒置树
5.支持多用户、多任务
一、linux基础指令
1.打开终端
ctrl + alt + t --打开终端,默认为用户目录
hqyj@ubuntu:~$
用户名@主机名:~
~:用户目录 等价于 /home/hqyj(可读可写)
/:根目录
sudo --可临时获取root权限
2.导航命令--- pwd(我在哪) ls(观察四周) cd(去哪)
pwd --打印当前的绝对路径 ---从根目录到当前目录 --- print work dirctory
ls --打印当前路径的所有内容(隐藏文件->以.开头的文件)
ls -a --打印当前路径的所有内容(包含隐藏文件)
ls -l --打印当前路径的所有内容+详细信息
ls -la (中间要空格,不空格则找不到)
linux中有7大文件类型 -- lsp - bcd
l -- 链接文件
s -- 套接字文件
p -- 管道文件
- :普通文件
b --块设备文件
c -- 字符设备文件
d -- 目录文件
ls [选项] 路径 --查看指定路径的所有内容
cd -- change dirctory --跳转到指定的路径
cd + 路径(这个路径指相对路径)
。。---代表上一级目录(用户目录)
。----代表当前目录
cd---跳转到用户目录
cd /----跳转至家目录
3.目录文件
mkdir 文件名 --在当前路径创建一个目录文件
mkdir -p /文件名1/文件名2/... --同时创建多级子目录
rmdir 目录文件名 --删除指定的空目录文件
rm -r(递归) 目录文件名 --(递归)删除非空目录文件
练习1:在用户目录下创建一个Class目录文件 ,然后再在Class文件中创建一个230101目录文件。
cd ~(跳转到家目录),mkdir Class(创建Class目录文件),cd Class(跳转到
Class),mkdir 230101(创建230101目录文件)
4.普通文件
touch 文件名 ---创建普通文件
rm 普通文件名 --删除普通文件
cat 普通文件名 --查看文件的内容
5.文件的复制 和剪切 --cp mv
cp 原普通文件名 目标普通文件名 ---如果目标普通文件存在,直接把原文件的内容复制过去,如果不存在则先创建
cp -r 源目录文件名 目标目录文件名
mv 源文件名 目标文件名
mv 文件名 ..回到上一级
备注:如果原文件和目标文件在同一路径下,则相当于改名
6.编辑器 -vi/vim geidt
* vi/vim
vi + 文件名
vim + 文件名
注意:如果该文件已经存在则打开该文件,如果该文件不存在则创建
命令行模式:
j --光标向下移动一行
k --光标向上移动一行
h --光标向左移动一列
l --光标向右移动一列
yy --复制当前光标所在的行
nyy --复制当前光标之后的n行 ---n是一个整数,代表要复制多少行
dd --剪切当前光标所在的行
ndd --剪切当前光标之后的n行 ---n是一个整数,代表要复制多少行
u --撤销上一步操作
ctrl + r --反撤销
p --在当前光标之后开始粘贴
:w --保存
:q --退出
:wq --保存并退出
:x -- 保存并退出
:q! --强制退出,不保存修改内容
:n --将光标跳转到第n行
:%s/old/new/g --用new将文件中所有的old替换
/string --在当前文件查找string -按n键来查找下一个
命令模式->插入模式:
i --从当前光标之前开始插入
a --从当前光标之后开始插入
A --从当前行末开始插入
o --从当前行下一行开始插入
插入模式->命令模式:Esc
* gedit
gedit + 文件名
注意:如果该文件已经存在则打开该文件,如果该文件不存在则创建
7.编译器--gcc
gcc test.c //默认生成一个a.out可执行文件
./a.out //执行a.out
gcc test.c -o test //生成test可执行文件
./可执行文件名 //运行可执行文件
gcc编译步骤:
预处理 --头文件的展开 宏替换
编译 --将语言转换成汇编语言
汇编 --汇编语言转换成机器语言 .o
链接 --间所有的.o链接在一起生成可执行文件
二、计算机的组成
输入设备 --键盘、麦克风
输出设备 --显示器、扬声器
存储设备 --磁盘、内存、寄存器
程序控制器 --PC
逻辑\算术运算器 -ALU
1个字节 = 8位
1byte = 8bit
三、计算中数据的表现形式
十进制:0-9 --满十进一
123 = 1 * 10^2 + 2*10^1 + 3*10^0
二进制:0-1 --满二进一 前缀:0b
94 ->0b01011110 = 1 * 2 ^ 6 + 0 * 2^5 + 1 * 2^4 + 1 * 2^3 + 1* 2^2 + 1* 2^1 + 0*2^0
74 ->0b01001010
84 ->0b0101 0100
277 ->100010101
八进制:0 - 7 --满8进一 前缀:0
94 ->0b001 011 110 ->0136
74 ->0b001 001 010->0112
84 ->0b001 010 100->0124
十六进制:0 - 9 、A、B、C、D、E、F --满16进一 前缀:0x
94 ->0b 0101 1110->0x5E
74 ->0b0100 1010->0x4A
84 ->0b0101 0100->0x54
字符型:ASCII
在linux查询ascii码表:man ascii
C语言编程规范
C语言本身并不提供输入输出,所有的输入输出都是调用标准库函数实现的。
#include <stdio.h>
int main()[主函数]
{
printf(“hello world\n”);//分号是英文分号,代表一条语句结束
return 0;
}
所有的C程序都是从主函数开始的,从主函数结束
当程序执行过程中,遇到return关键字代表程序结束
在C语言中{}代表一个模块,模块与模块之间注意缩进(gg=GG,自动缩进)
必须是英文字符,否则编译出错
- 词法符号
- 标识符-程序员按照命名规则自定的词法符号-名字
命名规则:
- 由数字、字母、下划线组成;
- 不能以数字开头;
- 不能与关键字重名。
关键字大概有32个
数据类型:char short int float long double signed unsigned-8个
存储类型:auto static extern register const volatile-6个
结构体类型:struct union enum-3个
语句:if else switch case break default while do for continue goto return -12个
空类型:void
取别名:typedef
求字节:sizeof
注意:C语言严格区分大小写
-
运算符
算术运算符+ - * / % ++ --
%:取余运算符(注意左右两边必须是整数)
10%2=0;10%3=1
注意:左右两边操作数必须是整数
printf(“%d\n”,9%2);//1
自增运算符要特别注意,前加加与后加加的区别,避免编程或者计算出错
++:自增运算符
单独使用:
自增1,针对变量 int a=10;a++/++a;//a=a+1,a=11
后加加与前加加没有区别,都是自增1
非单独使用:
前加加:先自增再取值
int a=10;
int b=++a;//先a=a+1,a=11,b=a=11
后加加:先取值再自增
int a=10;
int b=a++;//b=a=10,a=a+1,a=11
int a = 10;
int b = a++ + ++a;//b=22
{c=10,c++,c=11,d=++c,c=12,d=12,e=c++,c=13,e=12,
f=c++ + ++c,c=13+1+1=15,f=14+14=28}
2.关系运算符 > < >= <= == !=
int a = 1 < 2;
如果关系为真,则运算结果为1
如果关系为假,则运算结构为0
3.逻辑运算符 && || ! 注意:在c语言中用来0代表逻辑上的假,用非0代表真。
&&:逻辑与
(表达式1)&&(表达式2)
运算规则: 如果表达式1和表达式2都为真则运算结果为1
如果表达式1和表达式2其中一个为假则运算结果为0
全真为真1
有假则假0
int a = (1 < 2)&&(2 > 0);
int b = -1 && -2;
||:逻辑或
(表达式1)||(表达式2)
运算规则 :有真则真1,
全假为假0.
int a = (1 > 2)||(1 == 1);
! :逻辑非
!(表达式)
运算规则:如果表达式为真,则运算结果为0
如果表达式为假,则运算结果为1
短路法则:
逻辑与:当表达1为假时,运算结果为0,表达式2不会被执行
逻辑或:当表达1为真时,预算结果为1,表达式2不会被执行
4.位运算符 & | ^ ~ << >>
&:位与
(表达式1)&(表达式2)
运算规则:全1则1,有0则0
10&11
1010
&1011
1010 ->10
|:位或
(表达式1)|(表达式2)
运算规则:全0则0,有1则1
10|11
1010
|1011
1011 ->11
^:异或
(表达式1)^(表达式2)
运算规则:相异为1,相同为0
10 ^ 11
1010
^1011
0001 ->1
~:位非
~(表达式)
运算规则:按位取反,1为0,0为1
~10
~1010
0101 —>5
->-11
机器码:对于一个有符号数来说,最高位用来表示符号位,1表示负数,0表示正数
原码:机器码
反码:
正数:原码
负数:符号位不变,其余位按位取反。
补码:
正数:原码
负数:反码+1
注意:计算中存储数据都是存的数据的补码
char a = 10;
char b = 11;
原码:0000 1011
反码:0000 1011
补码:~0000 1011
补码:1111 0100
反码:1111 0011
原码:1000 1100
<< :左移
(表达式1)<<(表达式2)
正数:高位舍去,低位补0
负数:高位舍去,低位补0,最后最高位置1
10 << 2//40
0000 1010->00101000->2^5+2^3=40
-10 << 2//-40
1000 1010->(反码)1111 0101->(补码)1111 0110->1101 1000(左移两位)->1101 0111(-1为补码)->1010 1000(取反)->-(2^5+2^3)->-40
>> :右移
(表达式1)>>(表达式2)
正数:低位舍去,高位补0
右移:低位舍去,高位补1(用补码来运算)
10 >> 2;
0000 1010->0000 0010->2
-10 >>2;
1000 1010->(反码)1111 0101->(补码)1111 0110->1111 1101(右移两位)->1111 1100(-1为补码)->1000 0011(取反)->-3
练习:
char b = -11;
b = b >> 2;
5.求字节 sizeof
求数据类型或变量的字节。
int a ;
sizeof(int) == sizeof(a);
sizeof(char);
sizeof(float);
注意:sizeof的运算结果是一个长整型的数据
printf(“%ld”,sizeof);
6.赋值运算符 = += -= *= /= &=
int a = 10;
a+=10; //a = a + 10; a = 20;
int b = 10;
b *= 10;//b = b * 10; b = 100;
7.逗号运算符 ,
运算规则:以逗号最右边的值作为运算结果。
int a = (10,11);//11
int b = (10,11,12,13);//13
8.三目运算符 ?:
(表达式1)?(表达式2):(表达式3)
运算规则:判断表达式1,如果表达式1的结果为真,则表达式2作为运算结果,
如果表达式1的结果的假,则表达式3作为运算结果
三、c语言中数据的表现形式
1.常量--程序运行过程不能被改变的数据--只读--不能做等号的左值
整型常量:123,-11
实型常量:
十进制小数形式:3.14,-4.156
指数形式:0.314e1 ,31.4e-1
规范化指数形式:小数点前第一位为0,小数点后第一位不为0
字符型常量:''括起来的单个字符,'a'
转义字符 \n -换行 \t –tab(制表)
'\n' '\t'
字符串常量: ""括起来的一串字符
"hello world"
符号常量:
#define PI 3.14 //放在程序的开头
#define N 100
2.变量--程序运行过程能被改变的数据-保存数据
定义变量的一般形式:
<存储类型> <数据类型> 变量名;
存储类型:
auto:自动类型
在定义局部变量时,用auto显示声明代表该变量在栈区(先入后出的一种存储方式)随机分配一片存储空间。
如果在定义变量时缺省存储类型,改变变量默认为auto类型
register:寄存器类型
register声明的变量,在程序运行时直接加载到寄存器上,但是计算机上寄存器有限,可能会加载失败,失败之后自动转为auto类型。
register int a = 10;//可能失败->auto int a = 0; int a = 0;
extern:引用类型 --该变量不能初始化,代表该变量在别处定义,要在此处使用。
extern int a;
1.在一个文件中扩张全局变量的作用范围。
2.在一个源程序中扩展一个文件的全局变量的作用范围。
static:静态类型
1.修饰全局变量,限制全局变量只能在本文件中使用,该变量不能被其他文件引用。
2.修饰局部变量,将局部变量的生命周期,延长到整个程序结束,并且该变量只会被定义一次。
1. 请写出static关键字尽可能多的作用,至少两点。
答:1、限制作用域,避免其它程序文件调用本文件static修饰的变量或函数;
2、指定变量的数据存储区;
3、延长生命周期等
2. 请写出const关键字的作用。
答:1、欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
2、对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
3、在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值。
const:修饰只读
const 修饰变量,只能读,不能写。
该变量不能做为等号左值。
const int a = 10;
a = 11;//报错
* const char *p; char const *p;
const 修饰*p,不能通过指针修改所指向空间的内容。
* char * const p;
const 修饰p, 这种类型的指针指向不能被改变。
int * const p ;
int a;
p = &a;
* const char * const p
这种类型的指针,既不能修改指针的指向,也不能修改指针所指向的内存空间里面的内容。
数据类型:
整型:
char:字符型 一个字节
unsigned:0 - 2^8 -1(0-255)
signed :-2^7 - 2^7 -1(-128-127)
注意:在定义变量时,如果缺省符号,默认为有符号
short:短整型 2个字节
unsigned:0 - 2^16 -1(0-65535)
signed :-2^15 - 2^15 -1(-32768-32767)
int :整型 4个字节
unsigned:0-2^32-1
signed:-2^31-2^31-1
long : 长整型 8个字节(64位) 4个字节(32位)
浮点型:
float:单精度浮点型 4个字节
精确度:6-7
double:双精度浮点型 8个字节
精确度:15-16
int a = 10;
float f = 10.1;
double d = 10.1;
char c;//如果不说明符号,默认有符号数,特别需要注意这点,计算范围
unsigned char c;
c = 97;
c = 'a';
short a = 32767;
a++;
printf("%d\n",a);
3.变量的初始化 --在定义的时候赋值
int a = 10;
int a,b,c,d =10;
4.变量的赋值
int a,b,c,d;
char c;
a = 10;
c = 'a';
5.全局变量 和局部变量
* 全局变量
定义位置:定义在所有模块({})之外的变量
生命周期:从定义开始,到程序结束
作用范围:整个源文件
没有初始化:默认为0
* 局部变量
定义位置:定义在模块({})之内的变量
生命周期:从定义开始到模块结束
作用范围:在定义它的模块之内。
没有初始化:随机值。
练习:定义两个整型变量,并交换他们值
int a = 10,b = 11;
交换后,a = 11,b = 10;
四、输入输出
* c语言本身并不提供输入输出,所有的输入输出都是通过调用标准库函数实现的->stdio.h
* ->#include <stdio.h>
1.标准输出函数 -printf("格式控制字符串",输出列表)
格式控制字符串:格式控制符 + 其他字符
格式控制符:
%d --按十进制有符号整数格式输出
%u --按十进制无符号整数格式输出
%md --按十进制有符号整数格式输出,指定占m位域宽,默认右对齐.否则按照原样输出
%-md --按十进制有符号整数格式输出,指定占m位域宽,左对齐.否则按照原样输出
%ld --按十进制有符号整数格式输出长整型的数据
%o --按八进制无符号整数格式输出
%#o --按八进制无符号整数格式输出-带前缀
%x --按十六进制无符号整数格式输出
%#x --按十六进制无符号整数格式输出
%p --输出一个地址
%f --输出单精度浮点型数据--隐含六位小数
%.nf --输出单精度浮点型数据--指定保留n位有效数据
%lf --输出双精度浮点型数据
%c --输出单个字符
%s --输出一个字符串
%.ns --输出一个字符串的前n个字符
%% --输出一个%
其他字符:按照原样输出
输出列表:从左到右与控制符一一对应,每一个用,隔开
int a = 10;
printf("%d %d %d %d",a++,++a,a++,++a);
函数在调用时,参数会从右到左依次入栈(先入后出的存储结构),后++会备份,出栈时,有备份打印备份,无备份打印真值。
| | 真值 | 备份 | |
| ---- | ---- | ---- | ---- |
| a++ | 14 | 13 | |
| ++a | 13 | | |
| a++ | 12 | 11 | |
| ++a | 11 | | |
练习:
int a = 10;
printf("%d %d %d %d",++a,a++,++a,a++);
| | 备份 | 真值 |
| ---- | ---- | ---- |
| ++a | | 14 |
| a++ | 12 | 13 |
| ++a | | 12 |
| ++a | | 12 |
| a++ | 10 | 11 |
2.标准输入函数 --scanf("格式控制字符串",地址列表)
格式控制字符串:格式控制符 + 其他字符
格式控制符:
%ld --输入长整型的数据
%lf --输入双精度浮点型数据
其它字符:按照原样输入
地址列表:->&变量 ->变量的类型必须与格式控制符从左到有一一对应
int a =0;
char b= 0;
float c = 0;
scanf("%d%c%f",&a,&b,&c);
long l = 0;
sancf("%ld",&l);
注意1:在输入数值型数据时,空格、回车、tab都算是的非法字符相当于输入结束。
注意2:在输入字符型数据时,空格、回车、tab都算是的有效字符->脏字符
注意3:在输入时,格式控制字符串后面不要加\n
返回值:是按照格式正确输入的个数。