我有一个函数,它获取一个整数作为参数。我想把一个char数组的地址发送给它,然后从它的地址打印数组。我的意思是:
void printSomeThing(int x){
printf("Variable is: %sn", /*What to type here?*/);
//I want this printf to write "file.txt"
}
....
int main(){
char filename[10] = "file.txt";
char *filePointer = filename; //So it points to filename[0]'s address.
int x = /*How to convert the address of the pointer (or the char array) to an integer?*/
printSomeThing(x);
}
因此,我想将char数组的地址发送给函数,并打印该地址的值。
注意:我无法更改printSomeThing
参数。它必须是int
。
在指针地址和整数之间转换的正确方法是使用uintptr_t
整数类型。这是一种保证足够大以容纳地址的类型(与int
不同(。此代码相当安全且可移植:
#include <stdio.h>
void printSomeThing(uintptr_t x){
printf("Variable is: %sn", (char*)x);
}
int main(){
char filename[10] = "file.txt";
char *filePointer = filename; //So it points to filename[0]'s address.
uintptr_t x = (uintptr_t)filePointer;
printSomeThing(x);
}
如果是sizeof(int) != sizeof(char*)
,那么通常情况下,您尝试做的事情是不可能的。
然而,有一种方法仍然可以使这一点发挥作用。在我告诉你如何实现这一点之前,让我重申一下其他人说过的话:你不应该使用int作为指针这不是个好主意。我要展示的只是:一个展示。仅仅因为它可以做并不意味着它应该做。
实现这一功能的一种方法是将内存映射到小于1 << (sizeof(int) * 8)
的地址。然后,将您想要的字符串复制到该内存位置。现在,您可以将此指针传递给printSomething(int)
函数。
这个解决方案有一个问题:它不是可移植的,所以它并不总是有效的。我无法在macOS上使用clang,但它在这里确实有效。这是我用过的代码。
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
void printSomething(int x){
printf("Variable is: %sn", (char*) x);
}
int main(){
char filename[10] = "file.txt";
char *allocd = mmap((void*) 0x10000, sizeof(filename)+1,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
strcpy(allocd, filename);
printSomething((int) allocd);
}
另一个可能只能用作演示的解决方案是要求gcc在低内存地址定义一个节。这个答案的作用与此类似。这可能也不可移植。
考虑到您不想只将指针传递给数组,我认为最好的方法是将其强制转换为无符号长,以便将其提供给函数。
然而,编译器可能会抱怨您在printf中向字符串模式传递了一个整数值,但这是由于您正在使用的设计。
如果你不需要使用printSomeThing(int i)
,那么只需传递char*本身,或者如果你需要传递其他东西,则使用void,并使用某种标志来告诉函数你传递了什么类型的