Zadání

Vymyslete funkci swap( parametr1, parametr2 ), která prohodí svoje parametry. Zdrojové kódy vašich programů (*.c) pošlete mailem na jirka@lixis.cz , přeložím si je sám.

Řešení

Krásné řešení nad rámec zadání vymyslel Ondřej Hrzán. Funkce swap() prohodí svoje parametry nezávisle na typu.

swap.c
#include <stdio.h>
#include <string.h>

#define NORMAL   "\033[0m"
#define BLUE  "\x1B[34m"
#define GREEN  "\x1B[32m"

void swap(void* value1, void* value2, size_t size)
{
  unsigned char *a, *b, c;
  a = value1;
  b = value2;
  for (size_t i = 0; i < size; i++) {
    c = b[i];
    b[i] = a[i];
    a[i] = c;
  }
}

struct Nevim
{
  int cislo;
  char text[20];

};

int main()
{
  // Swapping ints
  printf("Před:\n");
  int a = 2;
  int b = 5;
  printf("a = %s%d%s\nb = %s%d%s\n",BLUE,a,NORMAL,GREEN, b, NORMAL);
  swap(&a,&b,sizeof(a));
  printf("Po:\n");
  printf("a = %s%d%s\nb = %s%d%s\n",GREEN,a,NORMAL,BLUE, b, NORMAL);
  printf("\n");

  // Swapping longs longs
  printf("Před:\n");
  long long c = 99;
  long long d = 77;
  printf("c = %s%lld%s\nd = %s%lld%s\n",BLUE,c,NORMAL,GREEN,d,NORMAL);
  swap(&c,&d,sizeof(c));
  printf("Po:\n");
  printf("c = %s%lld%s\nd = %s%lld%s\n",GREEN,c,NORMAL,BLUE,d,NORMAL);
  printf("\n");
  // Swapping structs
  struct Nevim struct_a, struct_b;
  struct_a.cislo = 10;
  struct_b.cislo = 20;

  strcpy(struct_a.text, "Kchámo Brácho");
  strcpy(struct_b.text, "Nevim hele");

  printf("Před:\n");
  printf("struct_a.cislo = %s%d%s\nstruct_b.cislo = %s%d%s\n\nstruct_a.text = %s%s%s\nstruct_b.text = %s%s%s\n",BLUE,struct_a.cislo,NORMAL,GREEN,struct_b.cislo,NORMAL,BLUE,struct_a.text,NORMAL,GREEN,struct_b.text,NORMAL);

  swap(&struct_a,&struct_b,sizeof(struct_a));

  printf("Po:\n");
  printf("struct_a.cislo = %s%d%s\nstruct_b.cislo = %s%d%s\n\nstruct_a.text = %s%s%s\nstruct_b.text = %s%s%s\n",GREEN,struct_a.cislo,NORMAL,BLUE,struct_b.cislo,NORMAL,GREEN,struct_a.text,NORMAL,BLUE,struct_b.text,NORMAL);

}
Překlad a spuštění
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/hrzan/swap_ukol$ gcc -o swap swap.c
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/hrzan/swap_ukol$ ./swap
Před:
a = 2
b = 5
Po:
a = 5
b = 2

Před:
c = 99
d = 77
Po:
c = 77
d = 99

Před:
struct_a.cislo = 10
struct_b.cislo = 20

struct_a.text = Kchámo Brácho
struct_b.text = Nevim hele
Po:
struct_a.cislo = 20
struct_b.cislo = 10

struct_a.text = Nevim hele
struct_b.text = Kchámo Brácho
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/hrzan/swap_ukol$
Poznámka: Ondra udělal i hezké obarvení výstupu programu, které AsciiDoctor neumí. Lepší je obrázek.

swap


Další originální řešení vymyslela Eliška Hlaváčková:

hlavackova.c
#include <stdio.h>

// deklaruju swap
void swap(void *a, void *b, size_t size) {
    // docasna promenna
    void *temp = malloc(size);

    // kopiruju a do docasny promenny
    memcpy(temp, a, size);
    // kopiruju b do a
    memcpy(a, b, size);
    // kopiruju z docasne do b
    memcpy(b, temp, size);

    // smazu pamet docasne promenne
    free(temp);
}

int main() {
    int x = 5, y = 10;

    printf("pred vymenou: x = %d, y = %d\n", x, y);

    // volam swap
    swap(&x, &y, sizeof(int));

    printf("po vymene: x = %d, y = %d\n", x, y);

    return 0;
}

Drobná chyba je v tom, že překladač hudruje, nemůže najít deklaraci funkcí malloc(), memcpy() a free().

gcc -o hlavackova hlavackova.c
hlavackova.c: In function ‘swap’:
hlavackova.c:6:18: warning: implicit declaration of function ‘malloc’ [-Wimplicit-function-declaration]
    6 |     void *temp = malloc(size);
      |                  ^~~~~~
hlavackova.c:6:18: warning: incompatible implicit declaration of built-in function ‘malloc’
hlavackova.c:2:1: note: include ‘<stdlib.h>’ or provide a declaration of ‘malloc’
    1 | #include <stdio.h>
  +++ |+#include <stdlib.h>
    2 |
hlavackova.c:9:5: warning: implicit declaration of function ‘memcpy’ [-Wimplicit-function-declaration]
    9 |     memcpy(temp, a, size);
      |     ^~~~~~
hlavackova.c:9:5: warning: incompatible implicit declaration of built-in function ‘memcpy’
hlavackova.c:2:1: note: include ‘<string.h>’ or provide a declaration of ‘memcpy’
    1 | #include <stdio.h>
  +++ |+#include <string.h>
    2 |
hlavackova.c:16:5: warning: implicit declaration of function ‘free’ [-Wimplicit-function-declaration]
   16 |     free(temp);
      |     ^~~~
hlavackova.c:16:5: warning: incompatible implicit declaration of built-in function ‘free’
hlavackova.c:16:5: note: include ‘<stdlib.h>’ or provide a declaration of ‘free’

Spraví to #include <stdlib.h> a _#include <string.h>.

opravený zdroják
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// deklaruju swap
void swap(void *a, void *b, size_t size) {
    // docasna promenna
    void *temp = malloc(size);

    // kopiruju a do docasny promenny
    memcpy(temp, a, size);
    // kopiruju b do a
    memcpy(a, b, size);
    // kopiruju z docasne do b
    memcpy(b, temp, size);

    // smazu pamet docasne promenne
    free(temp);
}

int main() {
    int x = 5, y = 10;

    printf("pred vymenou: x = %d, y = %d\n", x, y);

    // volam swap
    swap(&x, &y, sizeof(int));

    printf("po vymene: x = %d, y = %d\n", x, y);

    return 0;
}
Kompilace a spuštění
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/hlavackova$ gcc -o hlavackova hlavackova.c
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/hlavackova$ ./hlavackova
pred vymenou: x = 5, y = 10
po vymene: x = 10, y = 5
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/hlavackova$

A funguje to bez chyby.


Originální řešení bez pomocné proměnné od Jiřího Černáka

swapnotemp.c
#include <stdio.h>

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}


void swapnotemp(int *a, int *b) {
    *a = *a + *b;
    *b = *a - *b;
    *a = *a - *b;
}


int main() {
    int x, y;

    printf("Enter the value of x: ");
    scanf("%d", &x);

    printf("Enter the value of y: ");
    scanf("%d", &y);

    int n = x, m = y;

    printf("Before swapping: x = %d, y = %d\n", x, y);

    // Call the swap function
    swap(&x, &y);

    printf("After swapping: x = %d, y = %d\n", x, y);

    printf("Before swapping: n = %d, m = %d\n", n, m);

    // Call the swap function
    swapnotemp(&n, &m);

    printf("After swapping: n = %d, m = %d\n", n, m);

    return 0;
}
Kompilace, spuštění a testování
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/cernak$ gcc -o swapnotemp swapnotemp.c
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/cernak$ ./swapnotemp
Enter the value of x: 45
Enter the value of y: 65
Before swapping: x = 45, y = 65
After swapping: x = 65, y = 45
Before swapping: n = 45, m = 65
After swapping: n = 65, m = 45
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/cernak$ ./swapnotemp
Enter the value of x: 5000000000
Enter the value of y: 4000000000
Before swapping: x = 705032704, y = -294967296
After swapping: x = -294967296, y = 705032704
Before swapping: n = 705032704, m = -294967296
After swapping: n = -294967296, m = 705032704
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/cernak$ ./swapnotemp
Enter the value of x: 4294967256
Enter the value of y: 8000
Before swapping: x = -40, y = 8000
After swapping: x = 8000, y = -40
Before swapping: n = -40, m = 8000
After swapping: n = 8000, m = -40
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/cernak$ ./swapnotemp
Enter the value of x: 2147473648
Enter the value of y: 2147483648
Before swapping: x = 2147473648, y = -2147483648
After swapping: x = -2147483648, y = 2147473648
Before swapping: n = 2147473648, m = -2147483648
After swapping: n = -2147483648, m = 2147473648
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/cernak$ ./swapnotemp
Enter the value of x: 2147483648
Enter the value of y: 15
Before swapping: x = -2147483648, y = 15
After swapping: x = 15, y = -2147483648
Before swapping: n = -2147483648, m = 15
After swapping: n = 15, m = -2147483648
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/cernak$ ./swapnotemp
Enter the value of x: 2147483647
Enter the value of y: 15
Before swapping: x = 2147483647, y = 15
After swapping: x = 15, y = 2147483647
Before swapping: n = 2147483647, m = 15
After swapping: n = 15, m = 2147483647
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/cernak$

A teď Jiří zkus zjistit, proč to nefunguje? Myslím, že na to přijdeš snadno.


Jednoduchý program od Adama Suchánka, je úsporný a dělá, co má dělat. Gratuluji.

suchanek_swap.c
#include <stdio.h>
void swap (int *a, int *b)
{
  int c = *a;
  *a = *b;
  *b = c;
}

int main (void)
{
  int a = 8, b = 7;
  swap(&a, &b);
  printf("%d, %d\n", a, b);
  return 0;
}
Kompilace, spuštění a testování
prvni_pmp  suchanek_prvni_pmp  suchanek_prvni_pmp.c
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/suchanek$ gcc -o suchanek_swap suchanek_swap.c
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/suchanek$ ./suchanek_swap
7, 8
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/suchanek$

Michaela Nývltová dělala pomocí Online Compileru.

ukol3.c
// Online C compiler to run C program online
#include <stdio.h>

void swap(int *p_a, int *p_b) {
    int docasna = *p_a;
    *p_a = *p_b;
   *p_b = docasna;
}

int main() {
 int a = 12;
 int b = 2;

printf("puvodni promena a = %d a promena b = %d\n", a ,b );

swap (&a, &b);

printf("prohozena promena a = %d a prohozena b = %d", a ,b );
}
Překlad a testování
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/nyvltova$ gcc -o ukol3 ukol3.c
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/nyvltova$ ./ukol3
puvodni promena a = 12 a promena b = 2
prohozena promena a = 2 a prohozena b = 12jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/nyvltova$

Funguje to.


Jan Ježek poslal toto:

vymena.c
#include <stdio.h>
int main() {
  double prvni,druhe, misto;
  printf("Zadejte první číslo: ");
  scanf("%lf", &prvni);
  printf("Zadejte druhé čislo: ");
  scanf("%lf", &druhe);

  misto = prvni;
  prvni = druhe;
  druhe = misto;

  printf("Po výmneně: ");
  printf("\n           %.lf\n", prvni);
  printf("           %.lf", druhe);
  return 0;
}
Překlad a test
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/jezek$ gcc -o vymena vymena.c
jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/jezek$ ./vymena
Zadejte první číslo: 15
Zadejte druhé čislo: 89
Po výmneně:
           89
           15jirka@jirka-Precision-T3610:~/vyuka_sspvc/pmp/jezek$

Program sice funguje zdá se bez chyb, ale neodpovídá zadání. Není zde definována žádná funkce, která by vyměnovala mezi sebou proměnné.