1

ポインター (特に void ポインター) を使用してスワップ関数を記述しようとしていますが、コードが機能しません。これが私のコードです:

void swap(void *p1,void *p2) 
{
    int temp;   
    temp=*((int*)p2);
    p2=p1; 
    p1=&temp;
}

int main() 
{
    int i=4;
    int j=5; 
    cout<<i<<j<<endl;
    swap(&i,&j); 
    cout<<i<<j<<endl;
    return 0;
}

どこが間違っていますか?

4

7 に答える 7

6

代入でポインターを逆参照していないため、コードは機能しません。そのはず

*((int*)p2)=*((int*)p1);
*((int*)p1)=temp;

void*を指しているという仮定をしていることに注意してくださいint。これは明らかに常にそうであるとは限りません。基本的に、 に置き換えvoid*int*、キャストを削除することもできます。

API のより一般的なケースは次のようになります。

void swap(void *p1,void *p2, size_t sz)

内部的には、API は size のバッファを割り当て、aszmemcpy作成し、再び を使用してスワップを作成する必要がありmemcpyます。

于 2012-12-20T15:44:03.573 に答える
2

関数の本体では、 と の値を交換していp1ますp2。あなたはそれをしたくありません。p1whatとp2 point toの値を交換します。

void swap(int *p1, int *p2)
{
  int tmp = *p1;
  *p1 = *p2;
  *p2 = tmp;
}

私はあなたがvoid *あなたの議論に使いたかったことを知っています. しないでください。とにかく割り当てを実行するには、それらを適切なターゲットタイプにキャストする必要があります。

int tmp = *(int *) p1;
*(int *) p1 = *(int *) p2;
*(int *) p2 = tmp;

うん。引数を作成しても、何も節約できませんvoid *

明らかに C++ を書いているので、テンプレートを使用して関数をジェネリックにすることができます。

template<typename T>
void swap(T *p1, T *p2)
{
  T tmp = *p1;
  *p1 = *p2;
  *p2 = tmp;
}

さらに良いことに、テンプレートと参照を使用すると、ポインターをまったく処理しなくなります。

template<typename T>
void swap(T &p1, T &p2)
{
  T tmp = p1;
  p1 = p2;
  p2 = tmp;
}
于 2012-12-20T15:57:46.113 に答える
0

メモリー機能の使用

void swap (void *vp1, void *vp2, const int size) {
char *buffer = (char *)malloc(sizeof(char)*size);
memcpy(buffer, vp1, size);
memcpy(vp1, vp2, size);
memcpy(vp2, buffer, size);
free(buffer);
}

int main()
{
int a = 10, b = 20;
printf("%d %d"a,b);
swap(&a, &b, sizeof(int));
printf("%d %d"a,b);

}

Output is:

10 , 20
20 , 10

データ型がわからない場合は、void を使用します。

于 2012-12-20T15:53:33.120 に答える
0

コンテンツではなく、ポインターのコピーを変更しています。次のようなことを行う必要があります(アイデアを示すだけです。これはキャストなしでは機能せず、それでも良い考えではありません):

temp = *p2
*p2 = *p1;
*p1 = temp;

ポインターを交換する場合は、ポインターへのポインターが必要になります。

void swap(void** ptr1, void** ptr2);

またはポインタへの参照:

void swap(void*& ptr1, void*& ptr2);

または、明らかに C++ を使用しているため、参照とテンプレートを使用して任意のタイプのデータを交換できます。しかし、言語の基本をすべて理解していると確信していますか?

幸運を

于 2012-12-20T15:50:53.767 に答える
0

これを試して:

#include <iostream>
using namespace std;

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

int main() {
  int a, b;
  cin >> a >> b;
  swap( &a, &b );
  cout << a << " " << b;
  return 0;
}

ポインター a と b を逆参照する前に、まずそれらを に変換する必要がありますint*。後は、スワップを実行するだけです。

注:void*パラメータとして渡す必要はありません。sを渡すint*と、それも正しくなります (そしてより読みやすくなります)。

注[2]: C++ でプログラミングしているため、ポインター参照の代わりに使用できます。

于 2012-12-20T16:23:57.217 に答える
0

ドライバ関数コードで p1 と p2 の内容を交換しても機能しません。これはおそらく、メモリアドレスの開始位置をスワップしようとしていて、OS がそれを制限しているためです。?? ただし、メモリ機能は機能します。

于 2019-04-09T14:31:50.817 に答える