【问题标题】:issue converting character pointer to void pointer for swap function问题将字符指针转换为用于交换函数的 void 指针
【发布时间】:2016-06-02 13:22:58
【问题描述】:

我正在尝试在一个 char * 字符串中交换字符。我希望交换函数接受一个 void *[] 是通用的,但我得到了一个奇怪的行为,我不知道为什么。

我的主要:

int main(int argc, char *argv[])
{
    size_t n_bytes = 100;
    int bytes;
    char *my_input;
    int numeric = 0;

    my_input = (char *) malloc(n_bytes + 1);

    /* if -n option is set, sort numerically versus lexicographically. */
    if (argc > 1 && strcmp(argv[1], "-n") == 0) numeric = 1;
    while(getline(&my_input, &n_bytes, stdin) && strlen(my_input) > 1)
    {
        swap((void **) my_input, 0, 2);
    }

    free(my_input);
    return 0;
}

使用 printf-ing 交换功能以进行“调试”:

void swap(void *v[], int i, int j)
{
    void *temp;
    printf("i: %d j: %d\n", i, j);
    for(int x = 0; x < strlen(v); x++)
    {
        printf("%c\n", v[x]);
    }
    temp = v[i];
    v[i] = v[j];
    v[j] = temp;
    printf("first letter: %c", v[j]);
}

打印循环中出现的是用户输入的字符串的第一个字符(例如,如果 input == "hello",打印的第一个字符将是 'h')。打印的其余部分始终是垃圾,而不是其余字符。打印 v[j] 中保存的内容的 printf 打印出交换后的值,无论第一个字符是什么。我猜我错过了一个明显的概念,但似乎无法弄清楚。

【问题讨论】:

  • 1.将类型不正确的数据传递给printf 会导致未定义的行为%c 接受 int,而不是 void*。 2.在循环条件下使用strlen()可能会导致性能不佳。
  • 不同类型使用不同数量的内存。除非我遗漏了一些东西,否则你如何期望交换函数知道如何交换未知大小的东西——只使用void *
  • void * 是通用指针,但 void ** 不是。
  • 编译时出现警告。

标签: c pointers void-pointers


【解决方案1】:

您正在处理“char 数组”,而不是“char 指针数组”,对吧?

void swapChar(char *v, size_t i, size_t j)
{
    char temp;
    printf("i: %zu j: %zu\n", i, j);
    int x;
    for(x = 0; x < strlen(v); x++)
    {
        printf("%c\n", v[x]));
    }
    temp = v[i];
    v[i] = v[j];
    v[j] = temp;
    printf("first letter: %c\n", v[j]));
}

如果你想让它通用,你必须告诉它元素的大小:

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

void swap(char *v, size_t i, size_t j, size_t size)
{
    char *temp = malloc(size);
    memcpy(temp, v + i * size, size);
    memcpy(v + i * size, v + j * size, size);
    memcpy(v + j * size, temp, size);
    free(temp);
}

int main(int argc, char *argv[])
{
    char string[] = "Test string";
    swap(string, 0, 1, sizeof *string);
    puts(string);
    return 0;
}

但是通用版本不能“printf”任何东西,因为swap() 不知道如何解释字节。例如,0000000011111111 是一个short 还是两个chars?你还没有告诉它。

您还可以在 C11 中使用 _Generic 宏编写一些脏东西。如果您的程序不必严格遵守,您可以利用typeof()

【讨论】:

【解决方案2】:

您已经定义了一个单维 char 数组或 char *,并且您正在尝试转换为 vaid*[],它是一个二维数组。将 void*[] 替换为 char* 并将 void *temp 替换为 char temp 应该可以在您的程序中使用。 (void *) 用于传递通用指针类型,您必须在访问指针之前转换回原始类型。也只需按原样传递输入字符串即可替换 (void **) 转换。

【讨论】:

  • void *v[] in function argument 等价于 void **v 并且不是数组。
  • 正确。我的意思是你可以像字符串数组一样使用。例如字符**。谢谢。
猜你喜欢
  • 2012-11-21
  • 1970-01-01
  • 2011-07-31
  • 1970-01-01
  • 2019-05-09
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多