简体   繁体   English

将字符串转换为 void 指针

[英]converting a string to a void pointer

I'm trying to figure out how to "transform" strings (char*) to void* and viceversa.我试图弄清楚如何将字符串(char*)“转换”为 void*,反之亦然。 When I execute this my output is just the first printf and ignores the second one, it doesn't even write "after = "当我执行这个时,我的输出只是第一个 printf 而忽略了第二个,它甚至没有写“after =”

PS This little program is just to understand, I know i could actually use swap(&s[0],&s[1]). PS 这个小程序只是为了理解,我知道我实际上可以使用 swap(&s[0],&s[1])。 I need to know how to properly cast a void pointer into an array of strings.我需要知道如何正确地将 void 指针转换为字符串数组。 I'm working on a uni project where I need to create my own quick_sort algorythm and I need the swap function inside of it to work with void pointers.我正在开发一个 uni 项目,我需要创建自己的 quick_sort 算法,并且我需要其中的交换函数来处理 void 指针。

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

static void swap(char** x,char** y);

static void swap(char** x,char** y){
    char* temp=*x;
    *x=*y;
    *y=temp;
}

int main()
{
    char* s[2];
    s[0]="weee";
    s[1]="yooo";
    void* array=s;
    printf("before %s %s\n",s[0],s[1]);
    swap((&array)[0],(&array)[1]);
    printf("after = %s %s",(char*)array,(char*)array);
    return 0;
}

I think I'm missing something big Thanks in advance :D我想我错过了一些重要的东西提前谢谢:D

void *array = s; declares array to be a void * .array声明为void * Then &array is the address of that void * , so &array[1] would access a void * after it.然后&array是那个void *的地址,所以&array[1]会在它之后访问一个void * But there is no void * after it, since void *array defines a single void * .但是后面没有void * ,因为void *array定义了一个void *

array could be properly defined to alias s with char **array = s;可以使用char **array = s;array正确定义为别名s ; , after which swap(&array[0], &array[1]); , 之后swap(&array[0], &array[1]); would work as desired.会按需要工作。

If you define array as void **array = (void **) s;如果将数组定义为void **array = (void **) s; , then swap(&array[0], &array[1]); , 然后swap(&array[0], &array[1]); will produce diagnostic messages because the types are wrong.将产生诊断消息,因为类型错误。 You could use swap((char **) &array[0], (char **) &array[1]);你可以使用swap((char **) &array[0], (char **) &array[1]); . .

Then, if you print the strings with printf("after = %s %s", array[0], array[1]);然后,如果您使用printf("after = %s %s", array[0], array[1]);打印字符串, this will work, although it is not entirely proper code. ,这将起作用,尽管它不是完全正确的代码。 Using array[0] as an argument passes a void * where printf is expecting a char * for the %s .使用array[0]作为参数传递一个void *其中printf期望%schar * However, the C standard guarantees that void * and char * have the same representation (encode their values using bytes in memory in the same way), and it further says (in a non-normative note) that this is intended to imply interchangeability as arguments to functions.但是,C 标准保证void *char *具有相同的表示形式(使用内存中的字节以相同的方式对其值进行编码),并且它进一步表示(在非规范性注释中)这旨在暗示可互换性函数的参数。

The void* doesn't seem to fulfil any particular purpose here, just swap the pointers: swap(&s[0],&s[1]); void*在这里似乎没有实现任何特定目的,只需交换指针: swap(&s[0],&s[1]); . .

You could also do this:你也可以这样做:

char** ptr = &s[0];
printf("before %s %s\n",ptr[0],ptr[1]);
swap(&ptr[0],&ptr[1]);
printf("after = %s %s",ptr[0],ptr[1]);

If you for reasons unknown insist on using void* then note that as your code stands, it points at the first char* in your array of char* .如果您出于未知原因坚持使用void*请注意,就您的代码而言,它指向char*数组中的第一个char* However, it isn't possible to perform pointer arithmetic on void* since that would entail knowing how large a " void " is.但是,不可能对void*执行指针运算,因为这需要知道“ void ”有多大。 The void* doesn't know that it points at an array of pointers. void*不知道它指向一个指针数组。 Therefore array[i] is nonsense.因此array[i]是无稽之谈。

Also, the void* are set to point at char* so you simply cannot pass it to a function expecting a char** .此外, void*设置为指向char* ,因此您根本无法将其传递给需要char**的函数。 You'd have to rewrite the whole program in a needlessly obfuscated way, so just abandon that idea.你必须以一种不必要的混淆方式重写整个程序,所以放弃这个想法。

In this declaration the array s used as an initializer is implicitly converted to a pointer to its first element of the type char ** .在此声明中,用作初始化器的数组s被隐式转换为指向其第一个char **类型元素的指针。

void* array = s;

In the call of the function swap在函数swap的调用中

swap((&array)[0],(&array)[1]);

the first argument can be the pointer array itself that will be implicitly casted to the pointer type of the corresponding parameter第一个参数可以是指针array本身,它将被隐式转换为相应参数的指针类型

swap( array, (&array)[1]);

But you need to correctly pass the second argument.但是您需要正确传递第二个参数。 To do this you need to cast the pointer array explicitly like为此,您需要像这样显式地转换指针array

swap( array, ( char ** )array + 1 );

In the call of printf you need also correctly to supply argument expressions.在调用printf时,您还需要正确地提供参数表达式。

Here is your updated program这是您更新的程序

#include <stdio.h>

static void swap(char** x,char** y);

static void swap(char** x,char** y){
    char* temp=*x;
    *x=*y;
    *y=temp;
}

int main()
{
    char* s[2];
    s[0]="weee";
    s[1]="yooo";
    void* array=s;
    printf("before %s %s\n",s[0],s[1]);
    swap( array, ( char ** )array + 1 );
    printf("after = %s %s", *(char**)array, ( (char**)array )[1]);
    
    return 0;
}

The program output is程序输出为

before weee yooo
after = yooo weee

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

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