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;
}
*/
原文地址:https://www.cnblogs.com/marklove/p/14278880.html