http://www.cs.utsa.edu/~wagner/CS2213/swap/swap.html 原地址

Parameters, by value and by reference: Both C and Java use only parameters that pass by value, which means that the value of the actual parameter is used to initialize the formal parameter. For simple variables C allows one to pass the address of the variable explicitly. (Java does not allow this.) This is sometimes called passing a parameter by reference. C++ allows this also, but C++ also allows an implicit pass by reference, which will be described at the end of this writeup.

In C, the mechanism above is what is used for parameters in the scanf function, which have the extra & (the "address of" operator) in front of them.


A swapping values: In C and in Java, we can always swap values with the use of three assignment statement and no function or paramters. The code on the left shows this, while the code on the right shows how the same task can be accomplished using the C exclusive-or operator ^. (Notice that is this case you don't need the variable t.)

C Simple Swap Program -- Assignments C Simple Swap Program -- Exclusive-Or

#include <stdio.h> int main() {
int a = 23, b = 47;
int t;
printf("Before. a: %d, b: %d\n", a, b);
t = a;
a = b;
b = t;
printf("After. a: %d, b: %d\n", a, b);
return 0;
}

#include <stdio.h> int main() {
int a = 23, b = 47; printf("Before. a: %d, b: %d\n", a, b);
a ^= b;
b ^= a;
a ^= b;
printf("After. a: %d, b: %d\n", a, b);
return 0;
}
Runs of the two programs
% cc -o swap_simple0 swap_simple0.c
% swap_simple0
Before. a: 23, b: 47
After. a: , b:
% cc -o swap_simple1 swap_simple1.c
% swap_simple1
Before. a: 23, b: 47
After. a: , b:

A swapping function: To understand how explicit pass by reference of parameters works in C, consider implementing a swap function in C, that is, a function that passes in two variables and swaps their values. The code on the left below shows one failed attempt at an implementation. The code on the right uses pointers, that is, explicitly passes the address of variables, and manipulates the numbers that are at that address, using the * operator (the "dereference" operator that fetches the contents of the given address).

C Swap Program -- Fails C Swap Program with Pointers -- Works

#include <stdio.h> void swap(int i, int j) {
int t = i;
i = j;
j = t;
} int main() {
int a = 23, b = 47;
printf("Before. a: %d, b: %d\n", a, b);
swap(a,b);
printf("After. a: %d, b: %d\n", a, b);
return 0;
}

#include <stdio.h> void swap(int *i, int *j) {
int t = *i;
*i = *j;
*j = t;
} void main() {
int a = 23, b = 47;
printf("Before. a: %d, b: %d\n", a, b);
swap(&a, &b);
printf("After . a: %d, b: %d\n", a, b);
}
Runs of the two programs
% cc -o swap0 swap0.c
% swap0
Before. a: 23, b: 47
After. a: 23, b: 47
% cc -o swap1 swap1.c
% swap1
Before. a: 23, b: 47
After. a: 47, b: 23

With the program on the left, no swapping took place. The values of a and b are passed to swap, and the function does swap them, but when the function returns, nothing has changed in the main function.

To get an idea of what this code does, print it out, draw the two integers a and b, and enter 23 and 47 in them. Now draw the two pointers i and j, along with the integer t. When swap is called, it is passed the addresses of a and b. Thus, i points to a (draw an arrow from i to a) and j points to b (draw another arrow from b to j). Once the pointers are initialized by the function call, *i is another name for a, and *j is another name for b. Now run the code in swap. When the code uses *i and *j, it really means a and b. When the function completes, a and b have been swapped.

Suppose you accidentally forget the & when the swap function is called, and that the swap line accidentally looks like this: swap(a, b);. This causes a segmentation fault. When you leave out the &, the value of a is passed instead of its address. Therefore, i points to an invalid location in memory and the system crashes when *i is used.

This is also why scanf crashes if you forget the & on variables passed to it. The scanf function is using pointers to put the value it reads back into the variable you have passed. Without the &scanf is passed a bad address and crashes. Reference parameters are one of the most common uses of pointers in C. Another way to say this is to say that the calling function is telling the called function where to find the variable.


Swapping in Java: The swapping just above using reference parameters in C doesn't work in Java, since Java doesn't have these kind of parameters, but often an application really only needs to swap two values in an array. In this case one can pass the array and the two indexes to swap as three parameters, and this will work in Java. The "bubble sort" program below illustrates this.

Java BubbleSort Program Run of the Program
public class BubbleSort {
// swap: interchange inside array
static void swap(int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
} // bubbleSort: very short code, but ineffient
static void bubbleSort(int[] a) {
for (;;) {
boolean sorted = true;
for (int i = 0; i < a.length - 1; i++)
if (a[i] > a[i+1]) {
sorted = false;
swap(a, i, i + 1);
}
if (sorted) break;
}
} static void printArray(int[] a) {
for (int i = 0; i < a.length; i++) {
if (i%4 == 0) System.out.println();
System.out.print(a[i] + " \t");
}
System.out.println();
} public static void main(String[] args) {
int size = Integer.parseInt(args[0]);
System.out.println("Bubblesort, size = " +
size);
int[] r = new int[size];
for (int i = 0; i < size; i++)
r[i] = (int)(Math.random()*size*10 + 1);
long startTime =System.currentTimeMillis();
bubbleSort(r);
System.out.println("Elapsed time(millis) "+
(System.currentTimeMillis()-startTime));
// printArray(r);
}
}
% javac BubbleSort.java
% java BubbleSort 60
Bubblesort, size = 60
Elapsed time (millis) 1 5 7 9 18
21 27 41 44
67 104 104 109
116 118 151 151
170 175 181 182
196 196 207 220
231 240 241 242
244 247 251 274
279 290 302 325
329 339 341 363
366 369 376 380
385 411 435 440
471 484 492 504
505 547 556 559
564 583 588 591
% java BubbleSort 100
Bubblesort, size = 100
Elapsed time (millis) 3
% java BubbleSort 1000
Bubblesort, size = 1000
Elapsed time (millis) 394
% java BubbleSort 10000
Bubblesort, size = 10000
Elapsed time (millis) 39518
% java BubbleSort 20000
Bubblesort, size = 20000
Elapsed time (millis) 158317
% java BubbleSort 40000
Bubblesort, size = 40000
Elapsed time (millis) 646717

Swapping in Java Using Wrapped Integers: In Java we can get the swap function to work if we use wrapped integers and pass references to them to the function. However, the Java wrapper class for int is Integer and it doesn't allow you to alter the data field inside. Thus we need our own wrapper class, which I have called MyInteger below. The program here is only presented as what could be done, not as an example of how to do swaps. If one passes the address of an object to a function, then changes to the inside of that object will persist after returning from the function

Java Swapping Using a Wrapper Class

// MyInteger: similar to Integer, but can change value
class MyInteger {
private int x; // single data member
public MyInteger(int xIn) { x = xIn; } // constructor
public int getValue() { return x; } // retrieve value
public void insertValue(int xIn) { x = xIn;} // insert
} public class Swapping {
// swap: pass references to objects
static void swap(MyInteger rWrap, MyInteger sWrap) {
// interchange values inside objects
int t = rWrap.getValue();
rWrap.insertValue(sWrap.getValue());
sWrap.insertValue(t);
} public static void main(String[] args) {
int a = 23, b = 47;
System.out.println("Before. a:" + a + ", b: " + b);
MyInteger aWrap = new MyInteger(a);
MyInteger bWrap = new MyInteger(b);
swap(aWrap, bWrap);
a = aWrap.getValue();
b = bWrap.getValue();
System.out.println("After. a:" + a + ", b: " + b);
}
}
% javac Swapping.java
% java Swapping
Before: a: 23, b: 47
After: a: 47, b: 23

Swapping in C++: Of course the C swapping methods will work in C++ also, but C++ has the very important concept of references, which we probably won't study in this course. However, below is a C++ swap program using this feature. Notice that the code for the actual swap is simple: swap(a, b);. In a similar way, the simple form of C++ input, such as cin >> x >> y; requires these kind of parameters.

C++ Swap Program Using References

#include <iostream>
using std::cout; void swap(int& i, int& j) {
int t = i;
i = j;
j = t;
} int main() {
int a = 23, b = 47;
cout << "Before. a: " << a << ", b: " << b << "\n";
swap(a, b);
cout << "After. a: " << a << ", b: " << b << "\n";
return 0;
}
Run of the program
% CC -o swap_CC swap.cpp
% swap_CC
Before: a: 23, b: 47
After: a: 47, b: 23

Swapping in C Using the Preprocessor: Another very good way to swap in C (perhaps the best way) uses the C preprocessor, which we will study later. For now, a preprocessor function like swap below does a textual substitution, before the actual compiler is invoked. The second listing below is what is sent to the compiler. (This is why there is no semicolon at the end of swap(int, a, b), since in the compiled code it would become a redundant semicolon at the end of a block (although not an error).)

C Swap Program Using Preprocessor

#define swap(type, i, j) {type t = i; i = j; j = t;} int main() {
int a = 23, b = 47;
printf("Before swap. a: %d, b: %d\n", a, b);
swap(int, a, b)
printf("After swap. a: %d, b: %d\n", a, b);
return 0;
}
Preprocessed Output

% cc -E swap_p.c
int main() {
int a = 23, b = 47;
printf("Before swap. a: %d, b: %d\n", a, b);
{ int t = a ; a = b ; b = t ; }
printf("After swap. a: %d, b: %d\n", a, b);
return 0;
}
Run of the program
% cc -o swap_p swap_p.c
% swap_p
Before swap: a: 23, b: 47
After swap: a: 47, b: 23

搞定C系语言的的swap的更多相关文章

  1. 一篇搞定SQLAlchemy--关系对象映射

    要使用SQLAlchemy,必须先下载这个模块 pip3 install sqlalchemy 或 pycharm File--> Settings-->project...-->P ...

  2. 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】

    说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...

  3. 彻底搞定C语言指针(精华版)

    1.语言中变量的实质 要理解C指针,我认为一定要理解C中“变量”的存储实质, 所以我就从“变量”这个东西开始讲起吧! 先来理解理解内存空间吧!请看下图: 内存地址→ 6 7 8 9 10 11 12 ...

  4. 3小时搞定一个简单的MIS系统案例Northwind,有视频、有源代码下载、有真相

    一.瞎扯框架.架构 楼主自从1998年从C语言.MASM.Foxbase开始学计算机开始接触这个行当16年以来,2001年干第一份与程序.软件.然后是各种屌的东西开始,差不多干了13年了,这13年来, ...

  5. 如何用python搞定验证码中的噪点

    背景:朋友在为"关山口男子职业技术学校"写一款校园应用,于是找MoonXue写一个学生选课系统的登录接口.为了搞定这个接口,不得不先搞定这个系统的验证码. 验证码大概是这个样子 看 ...

  6. 彻底搞定char/wchar_t/unicode

    彻底搞定char/wchar_t!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! (2013-07-17 10:18:28) 转载▼     从char/wchar_t到TCHAR(1) ...

  7. APP设计师拿到APP产品原型开始,七步搞定APP设计(转)

    任何一款成功的APP都需要以坚实的产品概念作为基础,因为概念决定了产品最终完成的潜力. 一般情况下,交到app设计师手里的都是移动app产品原型图.当然这个是在移动产品经理反复斟酌,并且与大家开会讨论 ...

  8. 彻底搞定 C/C++ 指针

    1.语言中变量的实质 要理解C指针,我认为一定要理解C中“变量”的存储实质, 所以我就从“变量”这个东西开始讲起吧! 先来理解理解内存空间吧!请看下图: 内存地址→ 6 7 8 9 10 11 12 ...

  9. 【转】轻松搞定FTP之FlashFxp全攻略

    转载网址:http://www.newhua.com/2008/0603/39163.shtml 轻松搞定FTP之FlashFxp全攻略 导读: FlashFXP是一款功能强大的FXP/FTP软件,融 ...

随机推荐

  1. oracle-数据库的各种-锁-详解

    数据库是一个多用户使用的共享资源.当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性. 如果是单用户的 ...

  2. javascript(7)

    js中基于对象==js面向对象 js中没有类class,但是它 JavaScript是一种面向(基于)对象的动态脚本语言,是一种基于对象和事件驱动并具有安全性能的脚本语言.它具有面向对象语言所特有的各 ...

  3. [原创]java导出excel

    一.需求背景 在项目开发中,经常会遇到导出Excel报表文件的情况,因为很多情况下,我们需要打印Excel报表,虽然在网页上也可以生成报表,但是打印网上里的报表是无法处理排版问题的,所以最好的方式,还 ...

  4. linux shell date 时间运算以及时间差计算方法

    最近一段时间,在处理Shell 脚本时候,遇到时间的处理问题. 时间的加减,以及时间差的计算. 获取当前时间戳 date +%s . 时间加减 这里处理方法,是将基础的时间转变为时间戳,然后,需要增加 ...

  5. HDU-6035:Colorful Tree(虚树+DP)

    这里有三道长得像的题: 一:HDU6036: There is a tree with nn nodes, each of which has a type of color represented ...

  6. bzoj 3522: Hotel dfs

    题目大意 在无边权树上求三个点,使两两点的距离等.求方案数\((n\leq 5000)\) 题解 我们知道三个点在树上的关系只有两种 三点共链 三点不共连 (这不是废话吗) 我们发现三点共链肯定不满足 ...

  7. [CTSC 2012] Cheat

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2806 [算法] 首先建立广义后缀自动机 注意到问题具有单调性 , 不妨对于每组询问二 ...

  8. 监测GPU使用情况命令

    每2秒监测一次:watch -n 2 nvidia-smi

  9. AtCoder Regular Contest 073 E:Ball Coloring

    题目传送门:https://arc073.contest.atcoder.jp/tasks/arc073_c 题目翻译 给你\(N\)个袋子,每个袋子里有俩白球,白球上写了数字.对于每一个袋子,你需要 ...

  10. 贪心+等价转化 HDU 1489

    等价转换,题意简单来讲如下:在一条直线均匀分布N个村庄,每个村庄要么买酒,要么卖酒,且村庄的买酒和卖酒供需平衡,总和为0,把k个单位的酒从一个村庄运到相邻的村庄需要k个单位的劳动力,输出最小的劳动力. ...