cs:app学习笔记(2):swap

来源:互联网 发布:淘宝处罚考试在哪里 编辑:程序博客网 时间:2024/05/16 14:44

  • swap
    • 两个数的交换
      • 说明
        • inplace_swap
        • swap
        • test_swap
      • 运行结果
    • 字符串首尾交换
      • csapp 所示的错误代码
        • 运行结果
        • 结果分析
      • 修改后的程序
        • 运行结果

swap

两个数的交换

#include <stdio.h>void inplace_swap(int *x, int *y){    *x = *x ^ *y;    *y = *x ^ *y;    *x = *x ^ *y;}void swap(int *x, int *y){    int swap;    swap = *x;    *x = *y;    *y = swap;}void test_swap(int a, int b){    printf ("initial a = %d b = %d\n",a, b);    inplace_swap(&a, &b);    printf ("inplace swap a = %d b = %d\n",a, b);    swap(&a, &b);    printf ("normal swap a = %d b = %d\n",a, b);}int main(int argc, char const *argv[]){    int a = 2, b = 1;    test_swap(a, b);    return 0;}

说明

inplace_swap

  • 第一个是使用位运算来进行两个数的交换,也就是就地交换,不需要另外设置一个变量达到交换的目的。
void inplace_swap(int *x, int *y){    *x = *x ^ *y;    *y = *x ^ *y;    *x = *x ^ *y;}
  • 但是在cs:app上所说的,这种交换没有任何的优势,只是一个智力游戏罢了。

swap

  • 使用指针进行交换与传递。
void swap(int *x, int *y){    int swap;    swap = *x;    *x = *y;    *y = swap;}

test_swap

void test_swap(int a, int b){    printf ("initial a = %d b = %d\n",a, b);    inplace_swap(&a, &b);    printf ("inplace swap a = %d b = %d\n",a, b);    swap(&a, &b);    printf ("normal swap a = %d b = %d\n",a, b);}int main(int argc, char const *argv[]){    int a = 2, b = 1;    test_swap(a, b);    return 0;}

运行结果

initial a = 2 b = 1inplace swap a = 1 b = 2normal swap a = 2 b = 1

字符串首尾交换

cs:app 所示的错误代码

#include <stdio.h>void inplace_swap(int *x, int *y){    *x = *x ^ *y;    *y = *x ^ *y;    *x = *x ^ *y;}void reserve_array(int a[], int cnt){    int first, last;    for (first = 0, last = cnt-1;        first <= last;        first++,last--)        inplace_swap(&a[first], &a[last]);}void test_reserve_array(int a[], int len){    int i, j;    for (i = 0; i < len; i++)        printf ("%d ", a[i]);    printf("\n");    reserve_array(a, len);    for (i = 0; i < len; i++)        printf ("%d ", a[i]);    printf("\n");}int main(int argc, char const *argv[]){    int l[5]  = {0, 1, 2, 3, 4};    int m[6] = {0, 1, 2, 3, 4, 5};    printf ("wrong swap: \n");    printf ("No 1: \n");    test_reserve_array(l, 5);    printf ("No 2: \n");    test_reserve_array(m, 6);    return 0;}

运行结果

wrong swap: No 1: 0 1 2 3 4 4 3 0 1 0 No 2: 0 1 2 3 4 5 5 4 3 2 1 0 

结果分析

  • 当数组元素为偶数时,结果正确。
  • 当数组元素为奇数时,结果错误,中间元素为零。
  • 原因在于:
  • “`
    for (first = 0, last = cnt-1;
    first <= last;
    first++,last–)
中的`first <= last;`当奇数时,first与last相同,`&a[first], &a[last]` 是同一个地址,调用`inplace_swap` 就会出错。具体例子,详见下面的程序。 ``` c #include <stdio.h>void inplace_swap(int *x, int *y){    *x = *x ^ *y;    printf ("first step:%d %d \n",*x,*y);    *y = *x ^ *y;    printf ("second step:%d %d \n",*x,*y);    *x = *x ^ *y;    printf ("third step:%d %d \n",*x,*y);}void swap(int *x, int *y){    int swap;    swap = *x;    *x = *y;    *y = swap;}void test_swap(int a, int b){    printf ("initial a = %d b = %d\n",a, b);    inplace_swap(&a, &b);    printf ("inplace swap a = %d b = %d\n",a, b);    swap(&a, &b);    printf ("normal swap a = %d b = %d\n",a, b);}int main(int argc, char const *argv[]){    int a = 5, b = 5;    printf ("when inplace_swap(&a, &b):\n");    inplace_swap(&a, &b);    printf ("inplace swap a = %d b = %d\n",a, b);    printf ("\n\n");    printf ("when inplace_swap(&a, &a):\n");    inplace_swap(&a, &a);    printf ("inplace swap a = %d b = %d\n",a, b);    return 0;}

运行结果:

when inplace_swap(&a, &b):first step:0 5 second step:0 5 third step:5 5 inplace swap a = 5 b = 5when inplace_swap(&a, &a):first step:0 0 second step:0 0 third step:0 0 inplace swap a = 0 b = 5
  • 传入同一个地址,就会在first step 中奖变量全部修改掉。注意指针的问题。

修改后的程序

#include <stdio.h>void inplace_swap(int *x, int *y){    *x = *x ^ *y;    *y = *x ^ *y;    *x = *x ^ *y;}void reserve_array(int a[], int cnt){    int first, last;    for (first = 0, last = cnt-1;        first < last;        first++,last--)        inplace_swap(&a[first], &a[last]);}void test_reserve_array(int a[], int len){    int i, j;    for (i = 0; i < len; i++)        printf ("%d ", a[i]);    printf("\n");    reserve_array(a, len);    for (i = 0; i < len; i++)        printf ("%d ", a[i]);    printf("\n");}int main(int argc, char const *argv[]){    int l[5]  = {0, 1, 2, 3, 4};    int m[6] = {0, 1, 2, 3, 4, 5};    printf ("right swap: \n");    printf ("No 1: \n");    test_reserve_array(l, 5);    printf ("No 2: \n");    test_reserve_array(m, 6);    return 0;}
  • <= 改成 <

运行结果

right swap: No 1: 0 1 2 3 4 4 3 2 1 0 No 2: 0 1 2 3 4 5 5 4 3 2 1 0 
原创粉丝点击