嵌入式基础(一)
计算机基础
终端相关
查看相关知识
Kernel - the innermost part of any modern operating system which directly talks to actual hardware.
Shell - wrapper around the actual Kernel. Whenever we run command, we actually talk to shell which in turn invokes appropriate Kernel instructions. Apart from this, the shell is capable of performing some other stuffs like finding appropriate program while having commands, some file name short hand, piping commands etc.
Linux/MAC流行的shell是bash;Windows通常使用cmd shell,最初兼容ms dos而构建;power shell全新命令行shell技术可以在Windows,Linux,MAC使用;
Terminal - in the era of earlier computing, computers (known as Mainframe) were giant. So, it was easy to have a single processing unit and connect it from many places. Terminal is the actual hardware with keyboard and output devices connected to mainframe.
Console - Special type of terminal which is directly connected to Mainframe for the purpose of OS Administration.
tty - TeleTypewriter used to send and receive data to and from Mainframe. Used before Video Terminals were available. But conventionally it has been still named as tty. Even the coommand stty
Linux相关
查看相关知识
1.Linux文件系统与目录
查看相关知识
- Linux系统目录呈现倒树型结构
- 使用
.
表示当前目录,..
表示上级目录 - 路径:1.绝对路径-起点为根目录;2.相对路径-起点为当前目录
- Windows系统路径使用
\
间隔,Linux系统路径使用/
间隔 - Linux主目录使用
~
标识
2.Linux常用命令
查看相关知识
clear
-清除终端软件所有文字信息pwd
-查看当前目录的位置cd 目录
目录-修改当前目录位置ls
-用于查看目录内容,其中ls -a
查看所有内容,ls -l
查看每个项目的详细信息touch
-创建空文件mkdir
-创建空目录(父目录必须存在),mkdir 路径 -p
逐级创建指定目录rm
-删除文件或目录,rm 文件名
删除文件,rm -rf 目录名
删除目录cp
-拷贝文件或目录,rm 源文件 目标文件
拷贝文件,cp -rf 源目录 目标目录
拷贝目录cat
-快速查看文件内容
3.vim编辑器
查看相关知识
三种工作模式:正常模式执行简单命令,例如复制粘贴等;插入模式:实现编辑功能;命令行模式:执行复杂命令
一般模式→编辑模式:输入
i
;一般模式→命令行模式:输入:
;退回至一般模式使用esc
1 | 一般模式: |
1 | 命令行模式: |
C语言相关
查看相关知识
一、历史背景
编程语言演变过程:机器语言(纯粹二进制)→汇编语言(本质是助记符语言,受平台约束)→高级语言(C语言,C++等)
二、语法
1.案例:
查看相关知识
1 | /*这是我的第一个程序,很开心,文件名hello.c*/ |
1 | 编译程序,计算机只能识别二进制内容,因此要将c语言程序转换成可以识别的二进制,整个转换过程称为编译,转换过程需要用的工具称为编译器,gcc是Linux系统最常用的c语言编译器 |
编译程序的详细步骤:
1 | 源文件→预处理→编译→汇编→链接→可执行文件 |
编译的最好方法
1 | gcc hello.c -o hello |
2.printf函数
查看相关知识
(1)使用格式
1 | printf("输出内容",...); |
(2)可以在双引号中使用占用符
1 | printf("%d",500); |
3.变量
查看相关知识
- 计算机的内存由大量的字节构成,每个字节都有一个编号,不同字节的编号不同,这个编号叫做字节的地址,所有字节的地址都是连续的,从0开始向正数方向扩展;
- 可以将相邻的几个字节合并成一个整体用来记录一个数字,内存里用来记录一个数字的所有字节叫做一个存储区;
- 存储区的地址为它所包含的字节里第一个字节的地址;
- c语言程序利用变量表示存储区,变量的定义让计算机为程序分配存储区;
- 语法格式:数据类型 变量名=变量值;
- 变量名既代表存储区,也代表数字,由环境决定;
- 存储区的地址也可以用于代表存储区,&变量名—变量名表示的存储区首地址,可以在
printf
函数调用语句里面使用%p
作为占位符把地址数据显示在屏幕上; - 64位操作系统内存地址是8字节-64位的,32位操作系统内存地址是4字节-32位的;
- 变量命名规则:不能以数字开头,只能以字母或者下划线;c语言关键字不能作为变量名称;大小写敏感;
4.数据类型
查看相关知识
数据类型 | 含义 | 占位符 |
---|---|---|
char | 1字节(字符在内存中存储,存储的是字符对应的数字) | %c/%hhd |
unsigned char | 1字节(ASCII码表) | %c/%hhu |
short | 2字节 | %hd |
unsigned short | 2字节 | %hu |
long | 4字节/8字节(64位系统) | %ld |
unsigned long | 4字节/8字节(64位系统) | %lu |
int | 4字节(c语言默认整数为int类型) | %d |
unsigned int | 4字节 | %u |
float | 4字节 | %f/%g |
double | 8字节(c语言默认浮点数为double类型) | %lf/%lg |
字面值 | 含义 | 字面值 | 含义 |
---|---|---|---|
‘\a’ | 响铃 | ‘\v’ | 垂直制表 |
‘\b’ | 退格 | ‘\f’ | 换页 |
‘\t’ | 水平制表 | ‘\r’ | 回车(回到所在行最前面) |
‘\n’ | 换行(回到下一行最前面) | ‘%%’ | % |
使用sizeof关键字获取变量或者数据类型对应的内存大小,sizeof赋值语句失效
1
2
3
4//语法格式
sizeof(变量名/数据类型/表达式);
printf("%lu,%lu\n",sizeof(int),sizeof(a));//%lu-sizeof占位符
sizeof(a=100);//a的值不会变为100
5.scanf函数
查看相关知识
scanf函数从键盘获取用户的输入,将获取的输入存储到内存的存储区(可以使用&变量名,数组名,指针表示)
1 | scanf("%d,%d",&a,&b);//输入100,200 + enter |
6.进制转换
查看相关知识
- 有符号类型的二进制数最左边的位为符号位,0表示非负数,1表示负数
- HEX:16进制,DEC:10进制,OCT:8进制,BIN:2进制
- BYTE:1字节,WORD:2字节,DWORD:4字节,QWORD:8字节
(1)二进制转十进制
- 非负二进制转十进制,将二进制中的每个1单独转十进制相加即可
- 负数二进制转十进制,取反加一,转十添负
(2)十进制转二进制
- 非负十进制转二进制,采用”除2取余,逆序排序”,先得到的余数为二进制低位,后得到的余数为二进制高位,除至商小于1
- 负数二进制转十进制,去负转二,取反加一
(3)二进制转八进制
- 将二进制从右至左每三位分一组,每组用0-7的数字替换
- 八进制字面值前缀:0,例如0520
- printf/scanf格式化占位符:%[#]o
(4)二进制转16进制
- 将二进制从右至左每4位分一组,每组用0-9数字或者a-f字母替换
- 16进制字面值前缀:0x,例如0xb520
- printf/scanf格式化占位符:%[#]x
7.运算符
查看相关知识
(1)算数运算符
四则运算+取余数:
+
,-
,*
,/
,%
赋值运算符
=
,一条语句可以使用多个赋值操作符,优先计算右面的操作符- 符合赋值操作符
+=
,/=
,-=
,*=
- 自增运算符
++
,自减运算符--
,只能与存储区配合使用,将存储区的内容加一或减一,val++
先使用再自增,++val
先自增再使用
(2)逻辑运算符
- 逻辑表达式的结果0-假,1-真
- 布尔类型只包含两个整数0和1,c语言中任何数据都可以作为布尔值使用,0作为布尔值的时候,表示假,其他数据作为布尔值的时候表示真
- 单目逻辑运算符
!
,可以根据一个布尔值计算出相反的布尔值,称逻辑取反 - 双目运算符
==
,!=
,>
,>=
,<
,<=
,&&
,||
如果一个逻辑表达包含多个双目逻辑操作符必须拆成多个简单逻辑表达式再合并 &&
,||
具有短路特征;短路与:若第一个表达式为假,则结果为假;短路或:若第一个表达式为真,则结果为真
(3)位运算符
~
按位取反,注意事项:注意数据的类型1
2printf("~0x5a = %#x\n",~0x5a);//0xffffffa5
printf("~0x5a = %#hhx\n",~0x5a);//0xa5&
按位与:任何数位与1与,结果不变;任何数位与0与,结果为0|
按位或:任何数位与0或,结果不变;任何数位与1或,结果为1^
按位异或:任何数位与0异或,结果不变;任何数位与1异或,结果相反>>
右移,a>>n表示a右移n位;有符号数,右移左补符号位;无符号数,右移左补0<<
左移,无论是有符号数还是无符号数右移的时候,右补0- 在不发生高位溢出的前提下,左移1位相当于乘2,右移1位相当于除以2
- 位操作符不会修改存储区内容
(4)三目操作符
- 布尔值 ?表达式一 :表达式二;在?后不要使用赋值操作符
(5)优先级
- 单目高于双目,乘除高于加减,算术高于逻辑,条件(? :)高于赋值高于逗号
- 多数运算符具有左结合性,单目、三目和赋值运算符具有右结合性
(6)类型转换
隐式类型转换,两种类型字节数不同,转换为高字节数的类型;所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。 char型和short型参与运算时,必须先转换成int型
1
printf("sizeof(1?1:0.9)=%lu\n",sizeof(1?1:0.9));//8字节
隐式类型转换,若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型
1
2
3//无类型的数必须是非负数
printf("(-7+3u)>0=%d\n",(-7+3u)>0);//(-7+3u)>0=1 3u表示无符号3
printf("(-7+3u)=%d\n",-7+3u);//-7+3u=-4强制类型转换,容易导致数据丢失,常用于指针
1
2int a=300;
char c=(char)a;
8.流程控制
查看相关知识
(1)顺序结构
从上至下,顺序执行各条语句
(2)分支结构
if分支结构
1
2
3
4
5
6
7if(逻辑表达式1){
语句块1;
}else if(逻辑表达式2){
语句块2;
}else{
语句块3;
}switch分支结构
1
2
3
4
5
6
7
8
9
10
11switch (控制表达式){
case 常量表达式1:
语句块1;
break;
case 常量表达式2:
语句块2;
break;
...
default:
语句块0;
}控制表达式—能够表示整数;常量表达式—可以表示整数的常量;各个常量表达式不可相同
若去掉break语句,则 自动执行下一个case所对应的代码
(3)循环结构
for循环
1
2
3for (表达式1;表达式2;表达式3){
循环体;
}- 执行的顺序:1.先执行表达式1,且该语句在整个循环过程中,只执行1次;2.执行表达式2,表达式2为逻辑表达式,运算的结果为布尔值;3.表达式2为假,则结束循环;若表达式2为真,则执行循环体,再执行表达式3
- for循环小括号内的每条语句都可以省略
- c99规范能够在循环的小括号内临时声明循环变量,该变量只能在循环体内部使用
break语句
一旦执行break语句,break语句之后的循环里的一切语句都不再执行
continue语句
continue语句,跳过本次循环,执行下次循环,continue之后的语句不再执行,直接进入下一次循环
goto语句
1
2
3
4
5
6
7
8
9
10
int main(void)
{
printf("1\n");
goto label;//直接跳转到label位置
printf("3\n");
label://标签
printf("4\n");
return 0;
}while循环
1
2
3while (条件表达式){
循环体;
}do-while循环
1
2
3do{
循环体;
}while(条件表达式);do-while循环保证循环体内部的语句至少执行1次
空语句—执行语句为一个分号;如果分号没有起到结束语句的作用就是空语句
9.数组
查看相关知识
(1)一维数组
数组可以用来代表多个连续的同类型存储区,这些存储区叫做数组的元素
格式:存储区数据类型 数组名[存储区个数]={};
数组通常不会作为整体使用,只会一个一个的使用其中的某个存储区
数组里的每个存储区有一个编号,这个编号叫做数组的下标,第一个存储区的下标为0
数组名称和下标一起可以用来表示数组里的存储区,格式:数组名[下标]
数组名不代表存储区,它代表数组里第一个存储区的地址,也是数组的首地址
获取某个存储区的首地址,格式:&存储区;a[0]表示下标为0的存储区,&a[0]表示下标为0的存储区的首地址
1
2
3
4
5
6
7int arr[10]={0};//全0
int arr[10]={};//全0
int arr[10]={1}//a[0]=1,其余全是0
int arr[]={1,2,3,4,5};//省略数组定义里的存储区个数
int size=sizeof(a)/sizeof(a[0]);//计算数组元素的个数
printf("数组a的地址为%p\n",a);//与a[0]地址相同
printf("数组a的地址为%p\n",&a[0]);c99规范可以使用变长数组
1
2
3int n;
scanf("%d",&n);
int a[n];//不可初始化 动态数组
(2)二维数组
- 二维数组由多个一维数组组成,二维数组的每一个元素都是一维数组,一维数组的每一个元素都是一个存储区
- 定义二维数组需要提供两个整数,前一个整数表示一维数组的个数,后一个整数表示一维数组里的存储区个数
- 表示二维数组的存储区,需要提供两个下标,前一个下标用来表示分组编号,后一个下标用来表示分组里的存储区编号
- 二维数组名称后只写一个下标,这个下标作为组下标使用,这个写法可以表示组下标对应的组里第一个存储区的地址
- 二维数组名称后加组下标也可以作为一维数组名称使用,这个一维数组里包含组下标对应组里所有的存储区
(3)数组作为形参(形参—函数小节)
1 | //数组作为形参 |
10.函数
查看相关知识
(1)函数使用三步骤
函数声明
若被调用函数在调用函数后面定义,则需要进行函数声明
1
extern 返回值类型 函数名(形参表)//可以隐藏参数名称,例如int x,可以写成int即可
函数定义
返回值类型—返回数据的类型,只能够返回一个数据;形参表—用来存储给函数的数据
如果被调用函数没有使用return关键字指定返回值,则函数的返回值为随机数
1
2
3返回值类型 函数名(形参表){
函数体;
}函数调用
可以从调用函数向被调用函数传递多个数据,这些数据的类型可以不同
被调用函数需要为每个传递过来的数据提供一个存储区,即形参表
1
函数名(实参表)
(2)递归函数
- c语言函数可以调用自己,自己调用自己的函数叫递归函数
- 递归函数编写步骤:1.假设递归函数已经可以使用 2.在递归调用语句前编写分支处理不可分解的情况(这种分支必须能够结束函数)
(3)补充
1 |
|
(4)作用域和生命周期
局部变量
- 定义在函数内的变量
- 作用域:定义的位置开始到函数结束
- 生命周期:函数某一次执行的时间范围
- 不能够被其他文件调用
全局变量
- 定义在函数外的变量
- 作用域:从定义的位置开始向下的所有语句
- 生命周期:整个程序的执行时间
- 能够被其他文件调用
- 全局变量未初始化,默认为0
静态局部变量
- 使用static关键字修饰
- 作用域:定义的位置开始到函数结束
- 生命周期:整个程序执行时间
- 未初始化的静态局部变量,默认为0
- 静态局部变量的初始化只在程序开始的时候执行一次
静态全局变量
- 使用static关键字修饰
- 作用域:从定义的位置开始向下的所有语句
- 生命周期:整个程序的执行时间
- 不能够被其他文件调用
- 未初始化的静态全局变量,默认为0
案例
1
2
3
4vim命令行模式:
vs+文件名--实现左右分屏
ctrl+ww--切换两个文件的操作
gcc var2.c var3.c -o var1
2
3
4
5
6
7
8
9
int g_a=520;//全局变量
static int s_a=521;//静态全局变量
static void func2(void){ //静态函数
printf("func2:s_a=%d\n",s_a);
}
void func(void){
printf("func:g_a=%d\n",g_a);
}1
2
3
4
5
6
7
8
9
extern int g_a;//声明其他文件的全局变量
extern void func(void);//声明其他文件的函数
int main(void)
{
printf("g_a=%d\n",g_a);
func();
return 0;
}
11.指针
查看相关知识
(1)基本知识
地址:字节的编号
指针:可以通过地址获取存储区数据
指针变量:存储地址数据的变量
指针变量只能用来记录地址数据
指针变量的唯一用途就是用来找另一个存储区的
定义指针变量的格式
1
2
3
4
5数据类型* 指针变量名;
int *pa,*pb;
数据类型 * 指针变量名;
数据类型 *指针变量名;
int* pa,pb;指针变量占据的内存大小,32位系统为4字节,64为系统为8字节
定义指针变量的时候必须在变量名称前加一个*
定义指针变量的时候需要提供一个类型名称,它表示这个指针是与什么类型的存储区捆绑了
指针变量初始化的时候*没有参与赋值过程
如果一个指针和一个存储区之间存在捆绑关系,则可以通过在指针名称前加*操作符表示它所捆绑的存储区
1
2
3
4
5
6
7
8
9
10
11
12
int main(void)
{
int a=100;
int* p=&a;
printf("&a=%p,p=%p\n",&a,p);//变量a的地址
printf("a=%d,*p=%d\n",a,*p);//100 100
printf("&p=%p\n",&p);//指针p的地址
*p=200;
printf("a=%d,*p=%d\n",a,*p);//200 200
return 0;
}没有记录有效地址的指针分为两类,空指针与野指针,这两种指针都不能使用*操作符取表示它所捆绑的存储区
1
2
3
4
5
6
7
8
9
10
11/*空指针*/
int *p=NULL;
printf("%d\n",*p)//error
/*野指针,禁止出现野指针*/
int *p;
printf("%d\n",*p)//error
/*安全措施*/
if (p==NULL){
printf("p是空指针\n");
return -1;
}指针支持加减整数和关系比较运算,运算结果由指针的类型决定
1
2
3
4int *pa=0x1000;
p++;//p=0x1004
char *p=0x1000;
p++;//p=0x1001
(2)指针与一维数组
如果一个指针记录了数组里第一个存储区的地址,即可通过指针找到数组的每个存储区
即可指针后使用下标可以用来表示数组里的存储区
数组名本身是一个指针,代表数组的首元素地址
arr[i]==*(arr+i),arr为数组名称
大部分情况下可以使用p代替a,在计算数组长度的时候不可以使用p代替a,且数组名不可修改
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23int main(void)
{
int a[5]={1,2,3,4,5};
int *p=a;
for(int i=0;i<5;i++){
printf("%d ",a[i]);
}
printf("\n");
for(int i=0;i<5;i++){
printf("%d ",*(a+i));
}
printf("\n");
for(int i=0;i<5;i++){
printf("%d ",p[i]);
}
printf("\n");
for(int i=0;i<5;i++){
printf("%d ",*(p+i));
}
int size=sizeof(p)/sizeof(p[0])//在32为系统下,指针变量占据内存大小为4字节,int类型占据4字节,因此结果为1
a++;//error
p++;//ok
}
(3)指针与函数参数
如果要跨函数使用存储区必须通过指针实现
指针作为形参可以修改实参的值
指针可以作为返回值,返回地址
不可以返回局部变量的地址
1
2
3
4
5
6
7
8
9
10
11
12
13
void swap(int *x,int *y){
int tmp=*x;
*x=*y;
*y=tmp;
}
int main(void){
int a=10,b=20;
printf("a=%d,b=%d\n",a,b);
swap(&a,&b);
printf("a=%d,b=%d\n",a,b);
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int* read(void);
int main(void){
int *p=read();
printf("*p=%d\n",*p);
return 0;
}
int g_a=1024;
static int s_a=2048;
int* read(void){
static int s_b=4096;
int b=8192;
return &g_a;//ok
//return &s_a; //ok
//return &s_b; //ok
//return &b; //error 局部变量地址不能作为返回值
}
(4)指针与const关键字
- 功能:常量化
- 修饰普通变量:const int a=100:不可对变量a的值进行修改
- 修饰指针:
- 常量指针const int *p=&a:不可以通过这种指针对它捆绑的存储区赋值,但可以对指针本身赋值
- 指针常量 int* const p=&a:不可以对指针本身赋值,但是可以对它捆绑的存储区做赋值
- 常量指针常量const int* const p=&a:都不可赋值
(5)泛型指针
定义指针变量的时候可以使用void作为类型名称,这种指针称为无类型指针;能够与任意类型的存储区捆绑
无类型指针不可使用*节引用
无类型指针必须首先强制类型转换成有类型指针才能够使用*节引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main(void)
{
int i=100;
char c='a';
double d=5.6;
void *p=NULL;
p=&i;
printf("%d\n",*(int*)p);
p=&c;
printf("%c\n",*(char*)p);
p=&d;
printf("%lf\n",*(double*)p);
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
int main(void){
int a=0x12345678;
void *p=&a;
printf("%#x\n",*(char *)p);//0x78
printf("%#x\n",*(char *)(p+1));//0x56
printf("%#x\n",*(char *)(p+2));//0x34
printf("%#x\n",*(char *)(p+3));//0x12
printf("%#x\n",*(short *)p);//0x5678
printf("%#x\n",*(short *)(p+2));//0x1234
return 0;
}
12.字符串
查看相关知识
字符串由一组连续的字符构成,使用双引号引起来,这些字符的末尾必须使用’\0’字符结束
“abcd”==”abcd\0”
在printf函数调用语句中,使用%s作为占位符,把字符串里的字符依次显示在屏幕上
编译器会把字符串当作第一个字符所在存储区的地址
1
2
3printf("%s\n","abcd");
printf("%s\n","abcd\0");
printf("hello,""world\n");//"hello,world"字符串表示形式
字符数组
char str[5]:数组名表示数组首地址,不可更改;字符数组内容可以修改
1
2
3char str[5]="abcd";
str[0]="A";
str="hello";//error,意思是将字符串"hello"首地址赋值给str
字符指针
char *str=”abcd”:str存储字符串的首地址,指针变量str内容可以修改,str所捆绑的存储区内容不可修改
1
2char *str="abcd";
*str='A';//error
字符串的输入输出
输出:1.printf(“%s\n”,字符串首地址);2.puts(字符串首地址)
1
2
3
4
5char str[5]="abcd";
printf("%s\n",str);//abcd
char* str_a="abcd";
printf("%s\n",str_a);//abcd
printf("%c\n",*str_a);//a1
2
3
4char str[100]="abcd";
puts(str);
char* str_a="abcd";
puts(str_a);输入:1.scanf(“%s”,要保存字符的起始地址),遇到空格就停;2.gets(要保存字符的起始地址),读一行,但忽略最后的回车;从键盘获取一个字符串存储到内存—只能存储到字符数组中;
由于scanf()和gets()无法知道字符串s大小,必须遇到换行符或读到文件结尾为止才接收输入,因此容易导致字符数组越界(缓冲区溢出)的情况,所以我们在定义char型数组时,应该确保其空间足够大
1
2
3
4char str[100]={0}
scanf("%s",str);
char* str_a=NULL;
scanf("%s",str_a);//error1
2
3
4char str[100]={0}
gets(str);
char* str_a=NULL;
gets(str_a);//error
字符串操作函数
c语言提供一组标准函数。实现对字符串的各种操作,这些函数包含于string.h头文件
1
2
3
4
5
6
7
8
9char* p="hello";
num=strlen(p);//strlen统计字符串里有效字符的个数
char str[20]="abc";
strcat(str,"xyz");//合并两个字符串,第一个参数必须是字符数组,第二个字符串追加到第一个参数末尾
strcat(str,p);//合并两个字符串,第一个参数必须是字符数组,第二个字符串追加到第一个参数末尾
char str2[20]="abcd";
strcpy(str2,"123456");//把第二个字符串内容拷贝到第一个字符串中,第一个参数必须为字符数组
int ret=0;
ret=strcmp("hello","world");//根据ASCII码,比较两个字符串的大小;返回值大于0,表示前一个字符串大字符指针数组
指针数组里包含一组同类型的指针存储区
字符指针数组包含多个字符指针,每个字符指针可以代表一个字符串
表示方法:
1
2
3
4
5
6/*第一种*/
char *p1="abc";
char *p2="def";
char* p[2]={p1,p2};
/*第二种*/
char* p[2]={"abc","def"};1
2
3
4
5
6
7
8
int main(void){
char* p[3]={"zhangsan","lisi","wangwu"};
for(int i;i<3;i++){
printf("%s\n",p[i]);
}
return 0;
}
细节
1
2char str1[] = { 'C', 'h', 'i', 'n', 'a' };
printf("%s\n", str1);//输出乱码,由于没有加\0
13.命令行参数-main
查看相关知识
主函数第一个参数是整型表示第二个参数中的指针个数,第二个参数是一个字符指针数组,这些字符串的内容来自执行程序时的命令
1
2
3
4
5
6
7
8
9
10
11
int main(int argc,char* argv[]){
for (int i=0;i<argc;i++){
printf("argc=%d,argv[%d]=%s\n",argc,i,argv[i]);
}
int a=atoi(argv[1]);//atoi函数--把字符串转换成整数;atof--把字符串转换成浮点数
int b=atoi(argv[2]);
printf("sum=%d\n",a+b);
return 0;
}1
2
3
4
5
6运行结果
./main 100 200
argc=3,argv[0]=./main
argc=3,argv[1]=100
argc=3,argv[2]=200
sum=300