C语言中还有哪些交换变量值的方法?
#include<stdio.h>
void swap(int *a, int *b);
int main(){
int a = 3;
int b = 10;
swap(&a,&b);
printf("a=%d,b=%d\n",a,b);
}
void swap(int *a, int *b){
int t = *a;
*a = *b;
*b = t;
}
https://www.jianshu.com/p/77983e413239
供参考:
#include<stdio.h>
void swap(int* a, int* b); // 临时变量法
void swap1(int* a, int* b); // 迭代法
void swap2(int* a, int* b); // 异或运算
int main() {
int a = 3;
int b = 10;
swap(&a, &b);
printf("方法一:a=%d,b=%d\n", a, b);
swap1(&a, &b);
printf("方法二:a=%d,b=%d\n", a, b);
swap2(&a, &b);
printf("方法三:a=%d,b=%d\n", a, b);
return 0;
}
void swap(int* a, int* b) {
int t = *a;
*a = *b;
*b = t;
}
void swap1(int* a, int* b)
{
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
void swap2(int* a, int* b)
{
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
program -> ext_def_list
ext_def_list -> ext_def_list ext_def
ext_def -> opt_specifiers ext_dec_list SEMI
| opt_specifiers SEMI
ext_decl_list -> ext_decl
| ext_decl_list COMMA ext_decl
ext_decl -> var_decl
opt_specifiers -> specifiers
| (EMPTY)
specifiers -> type_or_class
| specifiers type_or_class
type_or_class -> type_specifier
type_specifier -> TYPE
new_name -> NAME
var_decl -> new_name
| star var_decl
上面语法中,大写的表示终结符, TYPE是C语言数据类型关键字例如long, int , float 等对应的token. NAME是所有C语言变量名的token, STAR代表符号’*’. 接下来我们看看语句:
long int *x, y;
的解析流程。
在解析开始时,我们先把ext_def_list压入堆栈。然后做一次shift操作,把long对应的token TYPE读入并压入堆栈:
ext_def_list TYPE
通过 type_specifier -> TYPE 进行reduce:
ext_def_list type_specifier
通过 type_or_class -> type_specifier 进行reduce:
ext_def_list type_or_class
通过specifiers -> type_or_class 进行reduce:
ext_def_list specifier
接着把int对应的token TYPE shift 进来:
ext_def_list specifier TYPE
通过 type_specifier -> TYPE 进行reduce:
ext_def_list specifiers type_specifier
通过 type_or_class -> type_specifier 进行reduce:
ext_def_list specifiers type_or_class
通过 specifiers -> specifiers type_or_class 进行reduce,于是解析堆栈头部的两个非终结符就去掉了:
ext_def_list specifiers
通过 opt_specifiers -> specifiers 进行 reduce:
ext_def_list opt_specifiers
接着分别把* 和 x 对应的token shift 到解析堆栈中:
ext_def_list opt_specifiers STAR NAME
通过 new_name -> NAME 进行 reduce:
ext_def_list opt_specifiers STAR new_name
通过 var_decl -> new_name 进行reduce:
ext_def_list opt_specifiers STAR var_decl
再通过 var_decl -> STAR var_decl 进行reduce:
ext_def_list opt_specifiers var_decl
通过 ext_decl -> var_decl 进行reduce:
ext_def_list opt_specifiers ext_decl
再通过 ext_decl_list -> ext_decl reduce一次:
ext_def_list opt_specifiers ext_decl_list
接着把 , y两个符号对应的token shift到解析堆栈中:
ext_def_list opt_specifiers ext_decl_list COMMA NAME
通过 new_name -> NAME 进行 reduce:
ext_def_list opt_specifiers ext_decl_list COMMA new_name
根据 var_decl -> new_name 进行 reduce:
ext_def_list opt_specifiers ext_decl_list COMMA var_decl
通过 ext_decl -> var_decl 进行reduce:
ext_def_list opt_specifiers ext_decl_list COMMA ext_decl
通过 ext_decl_list -> ext_decl_list COMMA ext_decl 进行 reduce:
ext_def_list opt_specifiers ext_decl_list
把 ; 对应的终结符 SEMI shift到解析堆栈:
ext_def_list opt_specifiers ext_decl_list SEMI
通过 ext_def -> opt_specifiers ext_list SEMI 进行reduce, 这样堆栈的头三个元素就出栈了:
ext_def_list ext_def
通过 ext_def_list -> ext_def_list dex_def 进行reduce:
ext_def_list
再通过 program -> ext_def_list 进行 reduce:
program
由于全局非终结符被压入堆栈,由此解析结束,语句能被我们的语法所接受,阅读博客的朋友可以通过视频查看算法的实现和调试过程。
在解析过程中,reduce进行了之后,便是代码生成的适当时机,代码生成除了将高级语言转换为低级语言外,还有很重要的一部是根据语言的类型系统创建符号表。我们写完代码后,设置断点,单步调试,查看变量值,这些功能无不需要符号表的支持。
符号表和类型系统是编译原理中,极具技术丰厚度,难度,和智识趣味的一部分,他们将是下几节我们深入讨论的内容。
走到这里,大家是否觉得,编译原理是一门博大精深的逻辑知识系统。随着学习和研究的不断推进,我越来越为编译原理各种算法的巧妙性,完备性所折服,不得不感慨,那些大牛前辈长得是什么大脑,怎么会构建出如此精妙逻辑系统,站在这些巨人的肩膀上,扩展了我们的知识视野,也体会到了“风物长宜放眼量”的愉悦。
说到知识体系和方法论,我所认识也是最佩服的一个大牛就是比特币首富李笑来,他构建了一套行之有效的方法论,能帮我们实现价值提升,挣更多的钱,下面是他的方法论课程,叫通往财富自由之路,也就199一年,不到200块钱,获得财富自由的心法,不值得吗!
在C语言中,除了常见的使用临时变量进行交换外,还有以下几种交换变量值的方法:
void swap(int *a, int *b) {
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
void swap(int *a, int *b) {
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
void swap(int *a, int *b) {
*a = *a * *b;
*b = *a / *b;
*a = *a / *b;
}
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
以上就是除了常见的使用临时变量进行交换外,C语言中的其他交换变量值的方法。