繁体   English   中英

指针和指针指针的麻烦

[英]Trouble with pointers and pointers to pointers

我在理解一段代码的工作原理时遇到了一些麻烦。 以下是stdlib实现qsort的比较函数:

int scmp(const void *p1, const void * p2)
{
  char *v1, *v2;

  v1 = (char *) p1;
  v2 = (char *) p2;
  return strcmp(v1,v2);
}

当然,这仅适用于字符串。 我的问题是:为什么下面的代码有效?

int scmp(const void *p1, const void * p2)
{
  char *v1, *v2;

  v1 = *(char **) p1;
  v2 = *(char **) p2;
  return strcmp(v1,v2);
}

在我看来,在第二个版本中,我强有力地将一个char*char** 问题是变量仍然包含char变量的地址。 当我应用* ,我理解C将通过获取p1的内容来处理此命令,然后在存储在其中的地址之后读取8个字节(在我的拱门上),以便最终获得char*类型的值。 在我看来,这应该导致将8个字符组合成无效的内存地址。

尽管如此,这两个功能同样有效。 我哪里错了?

假设您想使用qsortint数组进行排序。

int numbers[] = {10, 50, 35, 62, 22};

首先,创建一个可以比较两个int的函数。

int intCompare(void* p1, void* p2)
{
   int n1 = *(int*)p1;
   int n2 = *(int*)p2;
   return (n1 < n2);
}

然后,您可以使用:

qsort(numbers, 5, sizeof(int), intCompare);

numbers传递给qsort ,它会被衰减为int*并作为void*传递。 当我们需要从intComparevoid*中提取数字时,我们需要在取消引用指针并比较值之前将其转换为int*

把这个类比换成字符串,假设您想要排序:

char* strings[] = { "abc", "xyz", "def" };

qsort的调用将是:

qsort(strings, 3, sizeof(char*), scmp);

strings传递给qsort ,它会被衰减为char**并作为void*传递。 qsort传递给scmp的指针的基础类型将是char**类型,而不是char* 因此,使用是正确的:

int scmp(const void *p1, const void * p2)
{
  char *v1, *v2;

  v1 = *(char **) p1;
  v2 = *(char **) p2;
  return strcmp(v1,v2);
}

第一个版本在某些情况下由于幸运巧合而起作用。 这是一个示例程序,它显示了几个不起作用的情况,而第二个版本应该始终有效。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// First version of scmp
int scmp1(const void *p1, const void * p2)
{
  char *v1, *v2;

  v1 = (char *) p1;
  v2 = (char *) p2;
  return strcmp(v1,v2);
}

// Second version of scmp
int scmp2(const void *p1, const void * p2)
{
  char *v1, *v2;

  v1 = *(char **) p1;
  v2 = *(char **) p2;
  return strcmp(v1,v2);
}

void test1()
{
   char* strings[] = { "abc", "xyz", "def" };
   qsort(strings,  3, sizeof(char*), scmp1);
   for( int i = 0; i < 3; ++i )
   {
      printf("%s\n", strings[i]);
   }
   printf("\n");
}

void test2()
{
   char* strings[] = { "abc", "xyz", "def" };
   qsort(strings,  3, sizeof(char*), scmp2);
   for( int i = 0; i < 3; ++i )
   {
      printf("%s\n", strings[i]);
   }
   printf("\n");
}

void test3()
{
   char** strings = malloc(3*sizeof(char*));
   strings[0] = "abc";
   strings[1] = "xyz";
   strings[2] = "def";

   qsort(strings,  3, sizeof(char*), scmp1);
   for( int i = 0; i < 3; ++i )
   {
      printf("%s\n", strings[i]);
   }

   free(strings);
   printf("\n");
}

void test4()
{
   char** strings = malloc(3*sizeof(char*));
   strings[0] = "abc";
   strings[1] = "xyz";
   strings[2] = "def";

   qsort(strings,  3, sizeof(char*), scmp2);

   for( int i = 0; i < 3; ++i )
   {
      printf("%s\n", strings[i]);
   }

   free(strings);
   printf("\n");
}

int main()
{
   // Does not work.
   test1();

   // Should work always.
   test2();

   // Does not work.
   test3();

   // Should work always.
   test4();
}

输出(使用gcc 4.8.4):

abc
xyz
def

abc
def
xyz

abc
xyz
def

abc
def
xyz

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM