搜档网
当前位置:搜档网 › Keil程序运行main函数之前的汇编

Keil程序运行main函数之前的汇编

Keil程序运行main函数之前的汇编
Keil程序运行main函数之前的汇编

Keil开发的ARM程序main函数之前的汇编分析

——BIN文件中RW段的数据移动

系统平台:

STM32系列STM32F103ZE,512KB内部FLASH,64KB片内存储;

FLASH地址范围0x0800 0000 ~ 0x0808 0000,用于存放代码;

片内存储地址范围0x2000 0000 ~ 0x2001 0000,用于存放数据;

Cortex-M3上电后来到复位中断(已将前4个字节的值存入MSP堆栈指针),转到__main 标号,完成RW段的移动、ZI段的初始化,建立堆栈,初始化库函数,然后跳转到main函数,开启C程序之旅,执行流程如图1所示。

图1 main函数之前的汇编程序执行流程图

本文主要讨论RW段的移动,RW段就是程序中赋了初值的变量,它的搬移我看到过两种方式。在BIN文件中,RO段和RW段之间有8个双字的Region$$Table,4个双字一组,分别用于完成RW段的搬移和ZI段的初始化。

(1)__scatterload_copy来完成

此时RW段的内容保存到内存开始的地方,本文中是0x20000000,用这一方式完成后,内存中存放的不是RW数据的内容,而是一个地址。这个地址是在FLASH中,即指向了其在RO段的地址,实际的内容是在RO段中。

(2)通过__uncompressed1实现

RW是程序中初始化的变量,但是这些变量有可能初值是0,因此为了节省空间,实际在BIN文件中RW段是压缩过的。调用__uncompressed1解压缩RW段的数据内容,并将其

保存到内存开始的地方。

图2 BIN文件中压缩RW段内容

图2是BIN文件中RW段的数据内容,影印部分显示,大小是164字节。其中0x0001 C72C前面8个双字的内容是Region$$Table,将其列出如下。

0x0801 C72C BIN文件中RW段的开始地址

0x2000 0000 RW段要存放到RAM中的地址

0x0000 0334 要存放到RAM中的RW段数据大小

0x0800 0184 执行函数__scatterload_copy或者__uncompressed1

上面4个双字完成RW段的搬移。

0x0801 C7D0 BIN文件的末尾,ZI段的开始

0x2000 0304 ZI段放到RAM中的起始位置

0x0000 F4BC ZI段的大小

0x0800 01E0 执行函数__scatterload_zeroinit

这4个双字完成ZI段的初始化。

图3 RW段内容解压缩后再RAM中排布

将BIN文件中RW解压缩以后(这个解压缩从反汇编可以看到,但是没有看明白),实际内容如图3所示,大小变为820个字节,改补0的地方都已经补足了。

c语言中命令行参数argc,argv

main( int argc, char ** argv ) argv:指针的指针 argc:整数 char **argv or char *argv[] or char argv[][] 为了能形象的说明这两个参数的含义,我们先用一个实例来进行讲解: 假设程序的名称为test,当只输入test,则由操作系统传来的参数为: argc = 1,表示只有一程序名称; argc只有一个元素,argv[0]指向输入的程序路径及名称:./ test 当输入test para_1,有一个参数,则由操作系统传来的参数为: argc = 2,表示除了程序名外还有一个参数; argv[0]指向输入的程序路径及名称; argv[1]指向参数para_1字符串 当输入test para_1 para_2 有2个参数,则由操作系统传来的参数为: argc = 3,表示除了程序名外还有两个参数; argv[0]指向输入的程序路径及名称; argv[1]指向参数para_1字符串; argv[2]指向参数para_2字符串; 以此类推……………… void main( int argc, char *argv[] ) char *argv[]: argv是一个指针数组,元素个数是argc,存放的是指向每一个参数

的指针,第一个元素即argv[0]为程序运行的全路径名,从二个元素(argv[1])开始,是每一个参数的名称,最后一个元素为NULL。总的来说,即: * argv: 字符串数组 argv[0] 为程序运行的全路径名 argv[1] 为执行程序名后的第一个字符串; argv[2] 为执行程序名后的第二个字符串; ... argv[argc]为NULL。 int argc:表示argv的大小,是实际参数个数+1,其中+1是因为argv[0]是编译后的可执行文件名 main() 参数: Turbo C2.0启动时总是把argc、argv、env(存放环境变量)这三个参数传递给main()函数, 可以在用户程序中说明(或不说明)它们, 如果说明了部分(或全部)参数, 它们就成为main()子程序的局部变量。 请注意: 一旦想说明这些参数, 则必须按argc, argv, env 的顺序, 如以下的例子: main() main(int argc) main(int argc, char *argv[]) main(int argc, char *argv[], char *env[]) 其中第二种情况是合法的, 但不常见, 因为在程序中很少有只用argc, 而不 用argv[]的情况。 以下提供一样例程序EXAMPLE.EXE, 演示如何在main()函数中使用三个参数: /*program name EXAMPLE.EXE*/ #i nclude

!函数返回值

函数返回值 int Count() { int i,j; i=100; j=200; return i+j; } 测试函数: void Test() { int k=Count(); printf("\n k[%d]\n"); } C/C++的函数返回值一般是放在寄存器eax里的,而不是在栈里。 你的这一句int k = Count()的汇编语句就是这样: mov [esp - 4], eax //eax里是300,esp - 4是局部变量k的位置 你可以在vc里做个实验: int add(int a, int b) { __asm { mov eax,a // 把参数1存入eax add eax,b // eax += 参数2, 结果在eax里 } } int main() { printf("%d\n", add(3, 4)); return 0; } 楼主需要了解下寄存器这一概念,我就不把C/C++函数的汇编代码给发出来了。 还有在汇编层面来看,函数的返回值根本就没有定论,函数可以通过多种方式返回。保存返回值在eax里只是C/C++的一个约定而已。

返回值可以放在栈里,但你在C的语言层面上可能做不到,其实随着函数的结束,mov esp, ebp这条指令过后,函数内部的局部变量就报废了。如果你之后没改变过栈的内容,你可以用栈来存返回值,但比起用寄存器来存储,存储和读取要慢的多。 自己突发奇想在vc下试了下用栈“返回”值,写了段代码: #include void __declspec(naked) __stdcall return_a_value() { int local; local = 1990; // 栈空间 __asm ret } int main() { int local = 1; return_a_value(); // 用栈返回值 printf("%d\n", local); return 0; } 汇编看c之一,简单函数调用 简单的函数调用,通过简单的函数调用反汇编可以清楚了解如下 1.栈到底是什么,如何操纵栈的? 2.参数和临时变量是以什么形式在哪存放? 3.如何传递返回值? 举例: #include

函数返回值

函数返回值 1.不带返回值的函数:return; 不带返回值的函数的返回类型为void,这样的函数会在函数的最后一个语句完成时隐式调用return;也可以在函数的结尾显式地调用return; 对于任意一个函数,只要执行了return语句,函数就强制结束了。 对于返回类型为void的函数,如果不显式地调用return;则只有在函数结束时才会隐式调用。可以在函数执行的某一阶段,显式地调用return;来结束函数,不再执行return语句之后的函数部分。 由于break语句只能用于循环和switch语句中,因此,想要结束if语句直接退出函数,可用return; 只有一种情况下,返回类型为void的函数可以使用return expression这一形式,那就是返回另一个返回类型同样是void的函数的调用结果。 如: void A() void B() { { .... .... .... .... return; return A(); } }//因为A返回类型为void,所以可以这样调用。 2.具有返回值的函数:return expression; 代码: int max(int x,int y) #include { int main() int z; { if(x>=y) int a,b,c; z=x; scanf("%d%d",&a,&b); else c=max(a,b); z=y; printf("%d\n",c); return z; return 0; } } 在main函数中调用max函数,函数调用语句为max(a,b); 仔细研究一下max(a,b)。 对于一个表达式来说,它要完成一定的功能,还要返回一个操作结果(即表达式的值)。如i++,它的功能是使变量i的值加1,它的值是i自增前的值。同样的,函数调用也同样如此:max(a,b)的功能是把实参a,b的值传递给形参并执行函数中的各个语句;max(a,b)的值是一个int类型的值。 ++i的值是i自增后的值,相当于i=i+1,return i;对于i++来说,它的值是i自增前的值,那么如何获得这个值呢?编译器是这样做的:编译器自动创建一个临时变量并用i自增前的值来初始化这个临时变量。用这个临时变量的值来作为i++这个表达式的值。 同样的,执行max(a,b)后,首先完成参数传递并执行函数max中的各条语句。接着创建一个int型的临时变量并用return expression中expression的值来初始化这个临时变量。临时变量的类型为函数的返回值类型,即函数名之前的类型名。对max()函数来说就是int。

main函数的命令行参数

main函数的命令行参数 前面所用到的main函数都是不带参数的,即main()。其实main函数也可以有参数,只是它的参数之一是指针数组。 1.main函数中可以写两个形参,一般形式如下:main(int argc,char *argv[ ]); 2.说明:第一个形参argc是一个整型变量,第二个形参argv是一个指针数组,其元素指向字符型数据。 1 若以下程序所生成的可执行文件名为filel.exe ; 当输入以下命令行执行该程序 时,FILE1 CHINA BEIJING SHANGHAI程序的输出结果是()。 main( int argc,char *argv[]) { while(argc-->0) { ++argv; printf("%s",*argv);} } A)CHINA BEIJING SHANGHAI B)FILE1 CHINA BEIJING C)C B S D)F C B 2 假定下列程序的可执行文件名为prg.exe,则在该程序的子目录下输入命令行: main(int argc,char *argv[ ]) { int i; if(argc<=0) return; for(i=1;i后程序的输出结果是()。 A)hello good B)hg C)hel D)hellogood 3 假定以下程序经编译和连接后生成可执行文件PROG.EXE,如果在此可执行文件所在录的DOS提示符下键入:PROG ABCDEFGH IJKL<回车>,则输出结果为()。 main( int argc, char *argv[])) { while(--argc>0) printf("%s",argv[argc]); printf("\n"); } A) ABCDEFG B) IJHL C) ABCDEFGHIJKL D) IJKLABCDEFGH 4 不合法的main函数命令行参数表示形式是()。 A) main(int a,char *c[]) B) main(int arc,char **arv) C) main(int argc,char *argv) D) main(int argv,char *argc[]) 5 有以下程序:程序编译连接后生成的可执行文件是exl.exe,若运行时输入带参数的命令行是exl abcd efg 10<回车>则运行的结果是()。 #include main(int argc,char *argv[]) { int i,len=0; for (i=1; i,则运行结果为()。 main(int argc, char *argv[]) { int n,i=0; while(argv[1][i]!= '\0') { n=fun(); i++;} printf("%d\n",n*argc); } int fun() { static int s=0; s+=1; return s; } A)6 B)8 C)3 D)4

C语言编程实战-4-命令行参数(main函数)处理

命令行(main函数)参数处理 我们在执行某某命令的时候,经常会传入一些参数,告诉程序做不同的处理。如使用gcc编译程序时,我们经常会在后边指定c源码文件,如gcc test.c。我们自己写的程序,如何能够算其它命令一样,能够接收和处理不同的参数呢?答案是肯定的。我们今天来介绍自写程序对命令行参数的处理。 一个标准的C程序,其主函数通常是这样子定义的: int main(int argc,char *argv[]) { //用户代码 return xxx; } main函数有两个参数:argc与agv,前者是一个整数,表示命令行给程序参数的个数,后者是一个字符串数组,用于顺次存放命令行传给程序的参数,通过argc与argv,我们就能实现对命令行参数的处理。 对每一个程序而言,程序的名称总会作为命令行的第一个参数传给它的主函数,那怕命令行中并没有传任何参数。因此,主函数的参数argc最小值为1,argv[0]总是存放命令程序名。因此,假使test是我们程序的名字,如果执行: test 则main函数得到的参数是:argc = 1, argv = {“test”}; 如果执行: test arg1 arg2 则main函数得到的参数是:argc = 3, argv = {“test”, “arg1”, “arg2”}; 如此类推。 通过上面的讲解,我们不难在main函数中实现对命令行参数的代码。我们接下来做一个编程任务: 写一个程序,该程序接收两个参数,这两个参数都是整数,程序中需将这两个整数的和与差计算并输出到屏幕上。假设程序的名称为cal,在命令行执行: cal 10 15 则程序输出: 10 + 15 = 25 10 – 15 = -5 如果输入的参数不合法,则提示参数错误。 代码实现: #include

C#多线程函数如何传参数和返回值

C#多线程函数如何传参数和返回值 提起多线程,不得不提起委托(delegates)这个概念. 我理解的委托就是具有同样参数和返回值的函数的集合. 比如 public delegate void MyDelegate(int arg); 就是这种形式的函数 void Myfuntion(int i); 的集合. 如何将一个函数加入委托的集合? MyDelegate dele = new MyDelegate(Myfuntion1); 再增加一个 dele += new MyDelegate(Myfuntion2); ... 委托函数 dele 就是具有整数参数和空返回值的函数 Myfuntion1,2的集合. 调用这个委托函数 dele(1); 就是逐个调用 Myfuntion1,2,... 一般线程函数的声明和启动 Thread t = new Thread(new ThreadStart(MyFunction)); t.Start(); 正是调用了没有参数和返回值的委托函数 ThreadStart 其中的参数MyFunction 是这个委托函数中的一员. 很明显这样无法传参数和返回值,那我们该怎么办? 答案就在委托的BeginInvoke() 方法上, BeginInvoke() 也是(异步)启动一个新线程. 例如 MyDelegate dele = new MyDelegate (MyFunction); dele.BeginInvoke(10,"abcd"); void MyFunction(int count, string str); 可以实现参数的传递. 如何收集线程函数的返回值? 与BeginInvoke 对应有个 EndInvoke 方法,而且运行完毕返回 IAsyncResult 类型的返回值.这样我们可以这样收集线程函数的返回值 MyDelegate dele = new MyDelegate (MyFunction); IAsyncResult ref = dele.BeginInvoke(10,"abcd"); ...

函数参数返回值总结

函数的参数、返回值总结 (一)参数 ◆函数分: 有参函数:函数名(实参列表) 无参函数:函数名() ◆有参函数调用语句中的实参应与被调函数中的形参在个数、类型、顺序上一致。 ◆参数传递时,实参向形参一一对应进行单向的值传递。值:可是数值(变量或数 组元素)或数值的地址值(指针或数组名)。 (二)返回值 函数的返回值即为函数调用后的结果,可有如下返回结果的方法: (1)通过return语句返回一个值; (2)利用地址做参数返回一个或多个值; (3)利用全局变量返回一个或多个值。 (三)例 1、170页实验内容(1):打印由正三角和倒三角组成的图形。 有一个参数,无返回值。实参向形参传递一个数值。 #include /* 有一个参数,无返回值的函数,打印正三角 */ void f1(int n) /* 形参只能是变量,用来接收实参传来的数值 */ { int i,j,k; for(k=1;k<=n;k++) {for(i=1;i<=10-k;i++) printf(" "); for(j=1;j<=k;j++) printf(" *"); printf("\n");} } /* 有一个参数,无返回值的函数,打印倒三角*/ void f2(int n) {int i,j,k; for(k=n;k>=1;k--) {for(i=1;i<=10-k;i++) printf(" "); for(j=1;j<=k;j++) printf(" *"); /*双引号内应为“空格加半角星号”*/ printf("\n");} } main() { int n; scanf("%d",&n);

主函数main

①主函数main() ②保存单链表函数save() ③重载操作菜单函数load() ④显示单链表内容函数display () ⑤插入元素函数insert () ⑥删除元素函数decelt () ⑦修改元素函数modify() 各函数间关系如下: #include "stdafx.h" #include #include typedef char ElemType; struct LNode { ElemType data; struct LNode *next; }; //***********************************************************置空表setnull() void setnull(struct LNode **p) { *p=NULL; } //************************************************************求长度length() int length(struct LNode **p) { int n=0; struct LNode *q=*p; while (q!=NULL) { n++; q=q->next; }

return(n); } //*************************************************************取结点get() ElemType get(struct LNode **p,int i) { int j=1; struct LNode *q=*p; while (jnext;j++; } if (q!=NULL) /**//*找到了第i个结点*/ return(q->data); else { printf("位置参数不正确!\n"); return NULL; } } //************************************************************按值查找locate() int locate(struct LNode **p,ElemType x) { int n=0; struct LNode *q=*p; while (q!=NULL && q->data!=x) /**//*查找data域为x的第一个结点*/ { q=q->next; n++; } if (q==NULL) /**//*未找到data域等于x的结点*/ return(-1); else /**//*找到data域等于x的结点*/ return(n+1); }

带参数main函数

main函数也可以带参数。带参数main函数的定义格式如下: void main(int argc, char *argv[]) { ... ... } argc和argv是main函数的形式参数。这两个形式参数的类型是系统规定的。如果main函数要带参数,就是这两个类型的参数;否则main函数就没有参数。变量名称argc和argv 是常规的名称,当然也可以换成其他名称。 那么,实际参数是如何传递给main函数的argc和argv的呢?我们知道,C程序在编译和链接后,都生成一个exe文件,执行该exe文件时,可以直接执行;也可以在命令行下带参数执行,命令行执行的形式为: 可执行文件名称参数1 参数2 ... ... 参数n 执行文件名称和参数、参数之间均使用空格隔开。例如,在linux下运行程序./a.out 1 2 ,可执行文件名称为./a.out,参数1为字符串1,参数2为2。 如果按照这种方法执行,命令行字符串将作为实际参数传递给main函数。具体为: (1) 可执行文件名称和所有参数的个数之和传递给argc;所以上面的argc=3 (2) 可执行文件名称(包括路径名称)作为一个字符串,首地址被赋给argv[0],参数1也作为一个字符串,首地址被赋给argv[1],... ...依次类推。 本回答专业性由科学教育分类达人陶文认证 满意回答 运行方法: (假设你的程序为Untitled1.exe) 打开命令提示符: 转到你的Untitled1.exe的目录, 输入下列命令: Untitled1.exe a basdfsa 1314324 -k -f 回车就可以运行了。 这时,在Main函数里定义的 int main(int argc, char *args[]) 里的argc = 6,就是表示有六个参数, 对应的 args[0] = "Untitled1.exe"; args[1] = "a"; args[2] = "basdfsa"; args[3] = "1314324"; args[4] = "-k"; args[5] = "-f"; 就是这样子了。

函数的参数

如果把函数比喻成一台机器,那么参数就是原材料,返回值就是最终产品;函数的作用就是根据不同的参数产生不同的返回值。 函数的参数 在函数定义中出现的参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数,简称形参。 函数被调用时给出的参数包含了实实在在的数据,会被函数内部的代码使用,所以称为实际参数,简称实参。 形参和实参的功能是作数据传送,发生函数调用时,实参的值会传送给形参。 形参和实参有以下几个特点: 1) 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。 2) 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。 3) 实参和形参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误。

函数调用中发生的数据传送是单向的,只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。 【示例】计算1+2+3+...+(n-1)+n 的值。 1.#include 2.int sum(int n){ // 有参函数 3.int i; 4.for(i=n-1; i>=1; i--){ 5. n+=i; 6.} 7.printf("The inner n = %d\n",n); 8.return n; 9.} 10.int main(){ // 无参函数 11.int m, total; 12.printf("Input a number: "); 13.scanf("%d",&m); 14. total =sum(m); 15.printf("The outer m = %d \n", m); 16.printf("1+2+3+...+%d+%d = %d\n", m-1, m, total); 17.return0; 18.} 运行结果: Input a number: 100↙ The inner n = 5050 The outer m = 100

C语言函数说明与返回值

C语言函数说明与返回值 在学习C语言函数以前,我们需要了解什么是模块化程序设计方法。 人们在求解一个复杂问题时,通常采用的是逐步分解、分而治之的方法,也就是把一个大问题分解成若干个比较容易求解的小问题,然后分别求解。程序员在设计一个复杂的应用程序时,往往也是把整个程序划分为若干功能较为单一的程序模块,然后分别予以实现,最后再把所有的程序模块像搭积木一样装配起来,这种在程序设计中分而治之的策略,被称为模块化程序设计方法。 在C语言中,函数是程序的基本组成单位,因此可以很方便地用函数作为程序模块来实现C语言程序。 利用函数,不仅可以实现程序的模块化,程序设计得简单和直观,提高了程序的易读性和可维护性,而且还可以把程序中普通用到的一些计算或操作编成通用的函数,以供随时调用,这样可以大大地减轻程序员的代码工作量。 函数是C语言的基本构件,是所有程序活动的舞台。函数的一般形式是: type-specifier function_name(parameter list) parameter declarations { body of the function } 类型说明符定义了函数中return语句返回值的类型,该返回值可以是任何有效类型。如果没有类型说明符出现,函数返回一个整型值。参数表是一个用逗号分隔的变量表,当函数被调用时这些变量接收调用参数的值。一个函数可以没有参数,这时函数表是空的。但即使没有参数,括号仍然是必须要有的。参数说明段定义了其中参数的类型。

当一个函数没有明确说明类型时, C语言的编译程序自动将整型( i n t)作为这个函数的缺省类型,缺省类型适用于很大一部分函数。当有必要返回其它类型数据时,需要分两步处理: 首先,必须给函数以明确的类型说明符;其次,函数类型的说明必须处于对它的首次调用之前。只有这样,C编译程序才能为返回非整型的值的函数生成正确代码。 4.1.1 函数的类型说明 可将函数说明为返回任何一种合法的C语言数据类型。 类型说明符告诉编译程序它返回什么类型的数据。这个信息对于程序能否正确运行关系极大,因为不同的数据有不同的长度和内部表示。 返回非整型数据的函数被使用之前,必须把它的类型向程序的其余部分说明。若不这样做,C语言的编译程序就认为函数是返回整型数据的函数,调用点又在函数类型说明之前,编译程序就会对调用生成错误代码。为了防止上述问题的出现,必须使用一个特别的说明语句,通知编译程序这个函数返回什么值。下例示出了这种方法。 第一个函数的类型说明sum()函数返回浮点类型的数据。这个说明使编译程序能够对sum( ) 的调用产生正确代码。 函数类型说明语句的一般形式是: type_specifier function_name (; ) 即使函数使用形参,也不要将其写入说明句。若未使用类型说明语句,函数返回的数据类型可能与调用者所要求的不一致,其结果是难以预料的。如果两者同处于一个文件中,编译程序可以发现该错误并停止编译。如果不在同一个文件中,编译程序无法发现这种错误。类型检查仅在编译中进行,链接和运行时均不检查。因此,必须十分细心以确保绝不发生上

VBA函数返回值

VBA之函数返回值 1.返回一个值 Function define_yy(ByVal names As String, ByVal workbooks As String) As String Dim str_return As String '返回值 Dim i, t As Integer ........ ........ ........ ........ ........ define_yy = str_return End Function 对于函数返回值的要点已经用粗体表示出来了.调用此函数的格式为: call modle_connection.define_yy() (这个是不需要返回值的调用方法) bb=modle_connection.define_yy(a,b) (这是需要返回值的方法) 注:modle_connection为程序块名 2.返回值为多个值,可以采用返回数组的类型 Function return_data(ByVal strSEL As String, ByRef x As Integer) As String() '需要有括号,代表数组 Dim cn As New ADODB.Connection Dim rs As New ADODB.Recordset Dim bb(1000, 20) As String Dim i As Integer, j As Integer cn.Open strCN rs.Open strSEL, cn i = 1 Do While Not rs.EOF If x = 1 Then bb(i, 1) = rs(0) Else For j = 1 To x bb(i, j) = rs(j - 1) Next j End If i = i + 1 rs.MoveNext Loop x = i - 1 return_data = bb() 'BB()本身也需要定义为数组

int main参数详解

int main(int argc,char* argv[])详解 argc是命令行总的参数个数 argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数 命令行后面跟的用户输入的参数,比如: int main(int argc, char* argv[]) { int i; for (i = 0; i>i; return 0; } 执行时敲入 F:\MYDOCU~1\TEMPCODE\D1\DEBUG\D1.EXE aaaa bbb ccc ddd 输出如下: F:\MYDOCU~1\TEMPCODE\D1\DEBUG\D1.EXE aaaa bbb ccc ddd -------------------------------------------------------------------- char *argv[]是一个字符数组,其大小是int argc,主要用于命令行参数argv[] 参数,数组里每个元素代表一个参数; 比如你输入 test a.c b.c t.c 则 argc = 4 argv[0] = "test" argv[1] = "a.c" argv[2] = "b.c" argv[3] = "t.c" -------------------------------------------------------------------------------------------- argc记录了用户在运行程序的命令行中输入的参数的个数。 arg[]指向的数组中至少有一个字符指针,即arg[0].他通常指向程序中的可执行文件的文件名。在有些版本的编译器中还包括程序 文件所在的路径。 ------------------------------------------------------------------------- 在调用一个可执行程序时,某些情况下需要向程序传递参数。如我们可以在控制台中键入notepad.exe, 回车后将执行记事本程序。如果我们希望在打开notepad时同时打开一个文本文件,可以在notepad.exe

函数练习题(C语言)带答案

C语言函数练习题 一、选择题 1. 一个完整的C源程序是【】。 A)要由一个主函数或一个以上的非主函数构成 B)由一个且仅由一个主函数和零个以上的非主函数构成 C)要由一个主函数和一个以上的非主函数构成 D)由一个且只有一个主函数或多个非主函数构成 2. 以下关于函数的叙述中正确的是【】。 A)C语言程序将从源程序中第一个函数开始执行 B)可以在程序中由用户指定任意一个函数作为主函数,程序将从此开始执行 C)C语言规定必须用main作为主函数名,程序将从此开始执行,在此结束 D)main可作为用户标识符,用以定义任意一个函数 3. 以下关于函数的叙述中不正确的是【】。 A)C程序是函数的集合,包括标准库函数和用户自定义函数 B)在C语言程序中,被调用的函数必须在main函数中定义 C)在C语言程序中,函数的定义不能嵌套 D)在C语言程序中,函数的调用可以嵌套 4. 在一个C程序中,【】。 A)main函数必须出现在所有函数之前 B)main函数可以在任何地方出现 C)main函数必须出现在所有函数之后 D)main函数必须出现在固定位置 5. 若在C语言中未说明函数的类型,则系统默认该函数的数据类型是【】 A)float B)long C)int D)double 6. 以下关于函数叙述中,错误的是【】。 A)函数未被调用时,系统将不为形参分配内存单元 B)实参与形参的个数应相等,且实参与形参的类型必须对应一致 C)当形参是变量时,实参可以是常量、变量或表达式 D)形参可以是常量、变量或表达式 7. C程序中各函数之间可以通过多种方式传递数据,下列不能用于实现数据传递的方式是 【】。 A)参数的形实结合 B)函数返回值 C)全局变量 D)同名的局部变量 8. 若函数调用时参数为基本数据类型的变量,以下叙述正确的是【】。 A)实参与其对应的形参共占存储单元 B)只有当实参与其对应的形参同名时才共占存储单元 C)实参与对应的形参分别占用不同的存储单元 D)实参将数据传递给形参后,立即释放原先占用的存储单元

关于main函数的(int argc,char argv[])

main(int argc,char *argv[ ]) argv为指针的指针 argc为整数 char **argv or: char *argv[] or: char argv[][] main()括号内是固定的写法。 下面给出一个例子来理解这两个参数的用法: 假设程序的名称为prog, 当只输入prog,则由操作系统传来的参数为: argc=1,表示只有一程序名称。 argc只有一个元素,argv[0]指向输入的程序路径及名称:./prog 当输入prog para_1,有一个参数,则由操作系统传来的参数为: argc=2,表示除了程序名外还有一个参数。 argv[0]指向输入的程序路径及名称。 argv[1]指向参数para_1字符串。 当输入prog para_1 para_2 有2个参数,则由操作系统传来的参数为: argc=3,表示除了程序名外还有2个参数。 argv[0]指向输入的程序路径及名称。 argv[1]指向参数para_1字符串。 argv[2]指向参数para_2字符串。 void main( int argc, char *argv[] ) char *argv[] : argv 是一个指针数组,他的元素个数是argc,存放的是指向每一个参数的指针, 他的第一个元素即argv[0]为编译生成的可执行文件名(包括路径eg:"F:\VC\Ex1\Debug\Ex1.exe"),从二个元素(argv[1])开始,是每一个参数int argc 表示argv的大小,是实际参数个数+1,其中+1是因为argv[0]是编译后的可执行文件名main()主函数 每一C 程序都必须有一main()函数, 可以根据自己的爱好把它放在程序的某个地方。有些程序员把它放在最前面, 而另一些程序员把它放在最后面, 无论放 在哪个地方, 以下几点说明都是适合的。 1. main() 参数 在Turbo C2.0启动过程中, 传递main()函数三个参数: argc, argv和env。 * argc: 整数, 为传给main()的命令行参数个数。 * argv: 字符串数组。 在DOS 3.X 版本中, argv[0] 为程序运行的全路径名; 对DOS 3.0 以下的版本, argv[0]为空串("") 。 argv[1] 为在DOS命令行中执行程序名后的第一个字符串; argv[2] 为执行程序名后的第二个字符串; ... argv[argc]为NULL。 *env: 安符串数组。env[] 的每一个元素都包含ENVV AR=value形式的字符串。其中ENVV AR为环境变量如PA TH或87。value 为ENVV AR的对应值如C:\DOS, C: \TURBOC(对于PA TH) 或YES(对于87)。 Turbo C2.0启动时总是把这三个参数传递给main()函数, 可以在用户程序中说明(或不说明)它们, 如果说明了部分(或全部)参数, 它们就成为main()子程序的局部变量。

事件处理函数中返回值

事件处理函数中返回值 事件处理函数返回值其实指当事件发生时,浏览器会执行默认的操作,而当事件处理函数会返回一个结果,而当这个结果为true时,浏览器会继续执行默认操作,否则会停止执行。如果还是不懂的话,我们看一下下面这个实例: 当点击超链接标签时,如果check()的值为true,那么浏览器会跳转到abc.html页面中去,如果check()的值为false,点击超链接标签就不会跳转 这里return其实是对事件对象中的returnValue属性值的设置,而该属性就决定了该事件操作是否继续操作,当retrunValue为true时则继续操作,为false时则中断操作。 然而直接执行函数check,不使用return返回将不会对eturnvalue进行设置所以会默认地继续执行操作,比如如下实例 上面的实例就是不管check()的结果是true还是fasle,浏览器都会跳转到abc.html 页面中去。所以必须使用return返回。 事件处理函数返回值在表单中也存在这种情况,如下图

判断用户名是否为空,如果为空就不提交表单,否则就提交表单...跟上面理解是一样的。 讲到这里有很多同学在这里还能理解,但是呢,换个地方,换个事件绑定方式就不能理解了。 比如:在DOM对象上绑定事件: 很多人不能理解的是:在html元素上绑定事件时,return用了两次,才能阻止表单的提交,为什么在DOM对象上绑定事件时只用了一次return就能阻止表单提交,这里我们就要看看为什么了。 我们看看直接打印btn.onclick的结果,发现我们在html元素上绑定的事件处理函数fn是出现在DOM对象上事件处理函数的里面。 所以onclick=”return fn()”等价于 btn.onclick=function(){ return fn() },而fn()的结果true/false就决定表单是否提交。 总结:事件函数返回值; 如果返回true或者不返回,浏览器执行默认操作; 如果返回false,阻止浏览器默认操作。

c c++ main 函数命令行参数的使用 知识小结

c/c++ main 函数命令行参数的使用知识小结 2012-12-31 13:13:43 我来说两句作者:wu_lai_314 收藏我要投稿C程序最大的特点就是所有的程序都是用函数来装配的。main()称之为主函数,是所有程 序运行的入口。其余函数分为有参或无参两种,均由main()函数或其它一般函数调用,若调用 的是有参函数,则参数在调用时传递。 C/C++语言中的main函数,经常带有参数argc,argv,如下: int main(int argc, char** argv)int main(int argc, char* argv[])从函数参数的形式上看,包含一个整型和一个指针数组。当一个C/C++的源程序经过编译、链接后,会生成扩展名为.EXE的可执行文件,这是可以在操作系统下直接运行的文件,换句话说,就是由系统来启动运行的。对main()函数既然不能由其它函数调用和传递参数,就只能由 系统在启动运行时传递参数了。 在操作系统环境下,一条完整的运行命令应包括两部分:命令与相应的参数。其格式为: 命令参数1参数2....参数n? 此格式也称为命令行。命令行中的命令就是可执行文件的文件名,其后所跟参数需用空格分隔,并为对命令的进一步补充,也即是传递给main()函数的参数。 命令行与main()函数的参数存在如下的关系: 设命令行为:program str1 str2 str3 str4 str5 其中program为文件名,也就是一个由program.c经编译、链接后生成的可执行文件program.exe,其后各跟5个参数。对main()函数来说,它的参数argc记录了命令行中命令与参数的个数,共6个,指针数组的大小由参数argc的值决定,即为char*argv[6],指针数组的取值情况如图6-15所示。

Main函数参数argc,argv说明

Main函数参数argc,argv说明 C/C++语言中的main 函数,经常带有参数argc,argv,如下:int main(int argc, char** argv) int main(int argc, char* argv[]) 这两个参数的作用是什么呢?argc 是指命令行输入参数的个数,argv 存储了 所有的命令行参数。假如你的程序是hello.exe,如果在命令行运行该程序,(首 先应该在命令行下用cd 命令进入到hello.exe 文件所在目录)运行命令为:hello.exe Shiqi Yu 那么,argc 的值是3,argv[0]是”hello.exe”,argv[1]是”Shiqi”,argv[2]是”Yu”。 下面的程序演示argc 和argv 的使用: #include int main(int argc, char ** argv) { int i; for (i=0; i 假如上述代码编译 为hello.exe,那么运行 hello.exe a b c d e 将得到 Argument 0 is hello.exe. Argument 1 is a. Argument 2 is b. Argument 3 is c. Argument 4 is d. Argument 5 is e.运行 hello.exe lena.jpg 将得到 Argument 0 is hello.exe. Argument 1 is lena.jpg.================================#include #include #include int main(int argc ,char * argv[]){int i;char arg[6][15]={0};printf(“argc: %d /n”,argc);for(i=0;i{sprintf(arg[i],”%s” ,argv[i]);}//for(i=1;i//printf(“%s/n”,arg[i]);execlp(“/bin/mkdir”,”mkdir”,arg[1],NULL); return 1;}======================================清单 2. BusyBox 使 用argv[0] 来确定调用哪个应用程序// test.c #include int main( int argc, char

相关主题