• my gcc project


    显然,直接在vs2005的Disassembly窗口中查看是不方便的。其实,cl.exe提供了一个/FAs的编译选项,而添加这一选项最简单的办法为:首先找到“项目属性->Configuration Properties->C/C++->Command Line->Addtional options”,然后在其中添入"/FAs",然后F5编译,继而在源程序的同一目录下,便可找到对应的.asm文件了。这非常有用,到时候在分析栈框结构时将要用到。
    命令行 列表文件内容
    /FA 仅汇编文件
    /FAc 汇编文件与机器码
    /FAs 汇编文件与源代码
    /FAcs 汇编文件、机器码和源代码
    http://c.biancheng.net/view/3867.html

    gcc -S -O2 -fverbose-asm test.c
    -S 输出汇编 --fverbose-asm 代码和汇编一起

    http://c.biancheng.net/view/2377.html

    位域操作 goto jump 跳转

    #include <stdio.h>
    #include <stdbool.h>
    #include <string.h>
    #include <setjmp.h>
    #define format "%d
    %s
    %f
    %f
    %f
    "
    
    struct Test {
     int a0: 1;
     int a1: 1;
     int a2: 1;
     int a3: 1;
     int b0: 1;
     int b1: 1;
     int b2: 1;
     int b3: 1;
    }test;
    typedef struct{
     int a0: 1;
     int a1: 1;
     int a2: 1;
     int a3: 1;
     int b0: 1;
     int b1: 1;
     int b2: 1;
     int b3: 1;
    }SqList; 
    
    struct student
    {
    	int num;
    	char name[20];
    	float score[3];
    };
    void change( struct student stu );
    
    
    typedef char BOOL;
    #define Dboolean char
    /*typedef struct Test screen;*/
    typedef int BOOLEAN;
    /*typedef enum { true, false} DBOOL;*/
    //需要修改的变量  中间 加 *     
    //访问结构中的  .必须换成 ->
    BOOL set(int a,SqList * b)
    {
      int i;
      i = 0;
    
       switch(a)
            {
                    case 0:{ 
                            b->a0 = 1;
                            i = 0;
                            break;}
                    case 1:{ 
                            b->a1 = 1;
                            i = 1;
                            break;}
                    case 2:{ 
                            b->a2 = 1;
                            i = 2;
                            break;}
                    case 3:{ 
                            b->a3 = 1;
                            i = 3;
                            break;}
                    case 4: { 
                            b->b0 = 1;
                            i = 4;
                            break;}
                    case 5:{ 
                            b->b1 = 1;
                            i = 5;
                            break;}
                    case 6:{ 
                            b->b2 = 1;
                            i = 6;
                            break;}
                    case 7:{ 
                            b->b3 = 1;
                            i = 7;
                            break;}
                 //   default:printf("error");;
            }
        return i;
    }
    BOOL get(int a, SqList  b)
    {
      int i;
         i = 0;
       switch(a)
            {
                    case 0: if (b.a0){
                            i = 1;
                            break;}
                    case 1:if (b.a1){
                            i = 1;
                            break;}
                    case 2:if (b.a2){
                            i = 1;
                            break;}
                    case 3:if (b.a3){
                            i = 1;
                            break;}
                    case 4: if (b.b0){
                            i = 1;
                            break;}
                    case 5:if (b.b1){
                            i = 1;
                            break;}
                    case 6:if (b.b2){
                            i = 1;
                            break;}
                    case 7:if (b.b3){
                            i = 1;
                            break;}
                 //   default:printf("error");;
    
            }
        return i;
    }
    /*
    C语言中函数参数传递的三种方式
    (1)传值,就是把你的变量的值传递给函数的形式参数,实际就是用变量的值来新生成一个形式参数,因而在函数里对形参的改变不会影响到函数外的变量的值。
    (2)传址,就是传变量的地址赋给函数里形式参数的指针,使指针指向真实的变量的地址,因为对指针所指地址的内容的改变能反映到函数外,也就是能改变函数外的变量的值。
    (3)传引用,实际是通过指针来实现的,能达到使用的效果如传址,可是使用方式如传值。
    说几点建议:如果传值的话,会生成新的对象,花费时间和空间,而在退出函数的时候,又会销毁该对象,花费时间和空间。
    因而如果int,char等固有类型,而是你自己定义的类或结构等,都建议传指针或引用,因为他们不会创建新的对象。
    
    例1:下面这段代码的输出结果为:
    解析:
    该题考察函数传参问题。
    1,指针传参 -> 将变量的地址直接传入函数,函数中可以对其值进行修改。
    2,引用传参 -> 将变量的引用传入函数,效果和指针相同,同样函数中可以对其值进行修改。
    3,值传参 -> 在传参过程中,首先将c的值复制给函数c变量,然后在函数中修改的即是函数的c变量,然后函数返回时,系统自动释放变量c。而对main函数的c没有影响。
    
    转载:https://blog.csdn.net/weibo1230123/article/details/75541862
    */
    /*
    //引用交换
    void swip(int &a, int &b)
    {
    	int temp = a;
    	a = b;
    	b = temp;
    }
    //值传递
    void swip1(int a, int b)
    {
    	int temp = a;
    	a = b;struct student stu
    	b = temp;
    	cout << "swip1 a = " << a << "swip1 b = " << b << endl;
    }
    //地址传递值传递
    void swip2(int *a, int *b)
    {
    	int temp = *a;
    	*a = *b;
    	*b = temp;
    }
    int main1()
    {
    	int a = 10, b = 20;
    	swip1(a, b);
    	cout << "a = " << a << "b = " << b <<endl;
    	system("pause");
    	return 0;
    }
    作者:红狐
    链接:https://www.zhihu.com/question/401936673/answer/1289719170
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
    switch case语句在C/C++中的逻辑跟if else是有些区别的,区别在于case并不是完全按照条件来判断,而是按照顺序来判断的。流程是这样的:如果匹配到了会顺序执行下面的逻辑,例如:int a = 2;switch(n){case 0: printf("I am 0
    ");case 1:printf("I am 1
    ");case 2: printf("I am 2
    ");case 3:printf("I am 3
    ");default:printf("Sorry");}这里的运行结果将是:I am 2I am 3Sorry这是因为匹配到了2,会把后面的顺序执行掉,直到遇到break语句;所以标准的switch case语句是每个case后必须加break,如下:int a = 2;switch(n){case 0: printf("I am 0
    ");         break;case 1:printf("I am 1
    ");         break;case 2: printf("I am 2
    ");         break;case 3:printf("I am 3
    ");         break;default:printf("Sorry");}因此,题主的结果将会是,因为在第一句就是default,所以无论是什么都会匹配到,所以会顺序执行,一直到break,结果就是errorgood;另外上面有个回答说类型问题,其实不存在判断错,C会默认做类型转换,把char型转为int型进行比较,n--是先用后减,只有跳出switch语句之后才会执行--操作,所以switch比较的时候还是'e',int数字为101。
    */
    ////////////////////////////////////////////////////跳转
    jmp_buf jump_buffer;
    
    void func(void)
    {
             printf("Before calling longjmp
    ");
             longjmp(jump_buffer, 1);
             printf("After calling longjmp
    ");
    }
    void func1(void)
    {
             printf("Before calling func
    ");
             func();
             printf("After calling func
    ");
    }
    /*
    first calling set_jmp
    Before calling func
    Before calling longjmp
    second calling set_jmp 
    
    while (1){
         if (setjmp(jump_buffer) == 0){
             读取表达式
                求值表达式
                打印表达式的值
         
         }else {
             进行错误处理,初始化求值环境  
        }
    }
    */
    ////////////////////////////////////////////////////跳转
    
    int main()
    {
     SqList screen = {1,1,1,1,1,1,1,1};
     enum boolean{NO, YES}b;
     enum boolean bb = YES;
      if (screen.a1){
     printf("enum NO: %d
    ", NO);
     printf("boolean b: %d 
    ",b);
     printf("boolena b = %d, bb = %d 
    ",b = NO, ++bb);
     printf("sizeof(b): %lu, sizeof(enum boolean): %lu sizeof(struct test screen): %lu 
    ", sizeof(b), sizeof(enum boolean),sizeof(screen));
      }    
     printf("%d, %d, %d ,%d, %d, %d , %d, %d
    ",screen.a0,screen.a1,screen.a2,screen.a3, screen.b0,screen.b1,screen.b2,screen.b3);
     screen.a0 = 1;
     screen.a1 = 0;
     screen.a2 = 0;
     screen.a3 = 0;
     screen.b0 = 0;
     screen.b1 = 0;
     screen.b2 = 0;
     screen.b3 = 0;
     printf("%d, %d, %d ,%d, %d, %d , %d, %d
    ",screen.a0,screen.a1,screen.a2,screen.a3, screen.b0,screen.b1,screen.b2,screen.b3);
      goto test;//跳过 set get
    
                                                         /*==用于判断是否相等 才执行*/
      if (set(1,&screen)==1){ 
      printf("set yes 
    ");
          }
     if (get(1,screen)==1) { 
         printf("get 
    ");
       }  
     test:
     printf("%d, %d, %d ,%d, %d, %d , %d, %d
    ",screen.a0,screen.a1,screen.a2,screen.a3, screen.b0,screen.b1,screen.b2,screen.b3);
    ////////////////////////////////////////////////////跳转
      if (setjmp(jump_buffer) == 0){
                       printf("first calling set_jmp
    ");
                       func1();
             }else {
                       printf("second calling set_jmp
    ");
             }
    ////////////////////////////////////////////////////跳转
    /*	struct student stu;
    	stu.num = 12345;
    	strcpy(stu.name, "Tom");
    	stu.score[0] = 67.5;
    	stu.score[1] = 89;
    	stu.score[2] = 78.6;
    	change(stu);# test.c:54:                         i = 4;
    	movl	$4, -4(%rbp)	#, i# test.c:54:                         i = 4;
    	movl	$4, -4(%rbp)	#, i
    	printf(format, stu.num, stu.name, stu.score[0], stu.score[1],stu.score[2]);
    	printf("
    ");
    */
     return 0;
    }
    /*
    void change(struct student stu)
    {
    	stu.score[0] = 100;
    	strcpy(stu.name, "jerry");
    }
    */
    

    ================================================================
    传递可以修改的typedef struct

    #include <stdio.h>
    #include <malloc.h>
    
    typedef struct STRC_def{
    int i;
    int j;
    }STRC;
     
     
    int Func1(STRC * pSTRC);
    int Func2(STRC aSTRC);
     
     
    int main()
    {
     
    STRC * a =(STRC *)malloc(sizeof(STRC));//使用堆内存
    STRC b;//使用栈内存
    a->i=0;//初始化
    a->j=0;
    b.i=0;
    b.j=0;
    Func1(a);//传递指针
    Func2(b);//传递变量
    printf("a: %d %d
    b: %d %d
    ",a->i,a->j,b.i,b.j);//结果应该是 a: 1 2 
     b: 0 0
    //因为传递指针使用的是同一个存储位置,而传递变量使用的是内容复制的存储位置
    return 0;
    }
     
    int Func1(STRC * pSTRC)
    {
    pSTRC->i=1;
    pSTRC->j=2;
    return 0;
    }
     
    int Func2(STRC aSTRC)
    {
    aSTRC.i=3;
    aSTRC.j=4;
    return 0;
    }
    

    ================================================================================

    #include <stdio.h>
     
    struct point{int x; int y;};
    struct rect {
            struct point pt1;
            struct point pt2;
    };
     
    struct rect screen;
    struct point midlle;
    struct point makepoint(int, int);
     
    int main()
    {
            #define XMAX 300
            #define YMAX 400
            screen.pt1 = makepoint(0, 0);
            screen.pt2 = makepoint(XMAX, YMAX);
     
            struct point origin = {30}, *pp;
            origin.y = 40;
            //origin = {.x = 30, .y = 40}; //error
            //origin = {30, 40}; //error
            pp = &origin;
            printf("origin: .x,.y is (%d, %d)
    ", origin.x, origin.y);
            printf("origin: (*pp).x is (%d, %d)
    ", (*pp).x, (*pp).y);
            printf("origin: pp->x   is (%d, %d)
    
    ", pp->x, pp->y);
     
            return 0;
    }
     
    struct point makepoint(int x, int y)
    {
            struct point temp;
     
            temp.x = x;
            temp.y = y;
            return temp;
    }
    /*
    struct point addpoint(struct point p1, struct point p2)
    {
            p1.x += p2.x;
            p1.y += p2.y;
            return p1;
    }
     
    int pt_in_rect(struct point p, struct rect r)
    {
            return p.x >= r.pt1.x && p.x <= r.pt2.x
                && p.y >= r.pt1.y && p.y <= r.pt2.y;
    }
     
    #define min(a,b) ((a) < (b) ? (a) : (b))
    #define max(a,b) ((a) > (b) ? (a) : (b))
    // 矩形规范化
    struct rect canon_rect(struct rect r)
    {
            struct rect temp;
     
            temp.pt1.x = min(r.pt1.x, r.pt2.x);
            temp.pt1.y = min(r.pt1.y, r.pt2.y);
            temp.pt2.x = max(r.pt1.x, r.pt2.x);
            temp.pt2.y = max(r.pt1.y, r.pt2.y);
            return temp;
    }
    */
    
  • 相关阅读:
    dedecms list 判断 每隔3次输出内容
    dede 后台登录以后一片空白
    SSO单点登录在web上的关键点 cookie跨域
    简单批量复制百度分享链接
    PHP强大的内置filter (一)
    MySql数据备份与恢复小结
    linux命令 screen的简单使用
    xdebug初步
    本地虚拟机挂载windows共享目录搭建开发环境
    MySQL 5.6 警告信息 command line interface can be insecure 修复
  • 原文地址:https://www.cnblogs.com/marklove/p/14278880.html
Copyright © 2020-2023  润新知