显然,直接在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;
}
*/