Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C:给定已知的地址和类型,如何打印存储在其中的值?_C_Pointers_Memory Address - Fatal编程技术网

C:给定已知的地址和类型,如何打印存储在其中的值?

C:给定已知的地址和类型,如何打印存储在其中的值?,c,pointers,memory-address,C,Pointers,Memory Address,我正在做C语言编程的家庭作业 #include <stdio.h> typedef struct JustArray { char *x; } JustArray; int main() { JustArray Items[12]; char *d = "Test"; Items[0].x = (char *) &d; printf("Pointer: %p\n", &d); printf("Address:

我正在做C语言编程的家庭作业

#include <stdio.h>

typedef struct JustArray {
    char *x;
  } JustArray;

int main()
{
    JustArray Items[12];
    char *d = "Test";

    Items[0].x = (char *) &d;
    printf("Pointer: %p\n", &d);
    printf("Address: %u\n",&d);
    printf("Value: %s\n", d);
/*------------------------------------*/
//Knowing address of d from above, print value stored in it using Items[0].x. Cannot use &d, *d, or d.
    char *ptr;
    ptr = Items[0].x;
    printf("%p\n", Items[0].x);
    printf("%p\n", &ptr);
    printf("%s\n", ptr);

    return 0;
}
#包括
typedef结构数组{
char*x;
}正义阵列;
int main()
{
数组项[12];
char*d=“测试”;
项[0]。x=(字符*)&d;
printf(“指针:%p\n”,&d);
printf(“地址:%u\n”,&d);
printf(“值:%s\n”,d);
/*------------------------------------*/
//从上面知道d的地址,使用项[0].x打印存储在其中的值。无法使用&d、*d或d。
char*ptr;
ptr=Items[0].x;
printf(“%p\n”,项[0].x);
printf(“%p\n”和&ptr);
printf(“%s\n”,ptr);
返回0;
}

ptr的输出也需要“测试”,但它显示了一些奇怪的字符。分配的目的是找到一种方法来使用项[0].x中的地址信息,并在控制台中打印其值“Test”。我找不到这样做的方法…

这里的关键是要注意这一行的作用:

Items[0].x = (char *) &d;
首先请注意,
d
是一个
char*
(即在本例中是一个以null结尾的字符串),因此
&d
(引用它)必须产生一个
char**
类型的值(即指向char的指针或指向字符串的指针)。必须对字符*进行转换,C类型检查器才能接受代码。[请注意,这被认为是非常糟糕的做法,因为您将一种类型的值强制转换为另一种类型的值是毫无意义的。不过这只是一个练习,正是这种“糟糕的做法”让它成为一个挑战,所以我们暂时忽略它。]

现在,要再次返回
d
,只需给出
项[0].x
,我们需要对上述代码行的操作进行排序“反转”。我们必须首先将
项[0].x
转换为其有意义的类型
char**
,然后取消对结果的引用一次,以获得
char*
类型的值(即以null结尾的字符串)


还有维奥拉

记住指针的值是地址。指针的内容(即其解引用、指向的值、由其寻址)是位于另一个位置的值(类型被指向)。因此,int*的值是另一个变量(int类型)的地址,该变量存储在另一个地址中。请注意,C中的每个基本变量都是存储在某个地址中的数据的名称

int p = 1;
上面的p是int类型的var。它的值为1,由p直接给出(因此p==1)。p有一个地址(比如0x11111),可以通过&p访问(so&p==0x11111)。因此,p是一个变量的名称,其值为int(1),地址为0x11111(由&p给出)。这意味着值1(是int)存储在地址0x11111中

上面的q是int*类型的变量(指向int的指针,意思是“指向int类型变量的地址”)q有一个地址作为值(在本例中是0x22222),它直接由q给出(因此q==0x22222)但q也有一个地址(比如0x33333),可以通过&q访问该地址(所以&q==0x33333)。因此,q是一个变量的名称,其值是int的地址(0x22222,由q给出),其地址是0x33333(由&q给出)。基本上,值0x22222(是地址)存储在地址0x33333中

您可以使用前缀运算符*对q进行解引用,即访问其内容,即存储在地址0x22222中的值,即q的值。基本上我们有:q==0x22222,&q==0x33333,*q==[存储在地址0x22222中的值是什么]。现在考虑这个问题:

int* r = &p;
请记住,p的值为1(p本身给出的int)和地址0x11111(由&p给出)。现在,我声明了一个指向int的指针r,并用地址p(0x11111)初始化它。因此,r是一个指针,其值是一个地址(0x11111),但它也有一个地址(比如0x44444)

作为指针前缀的运算符*允许我们访问作为其值的地址值。所以*r会给我们1,因为1是存储在地址0x11111中的值,它同时是r的值和p的地址。所以r==&p(0x11111==0x11111)和*r==p(1==1)

现在让我们回到您的代码。当您声明一个char*时,您已经有了一个指针,因此如果您将%p设置为所需格式,那么它的打印将是一个地址;如果您将%s设置为所需格式,那么它的打印将是一个字符串。(%s使函数printf在内容中迭代,内容的起始地址是给定指针的值(当到达“\0”时停止)。我修复了您的代码(为了可读性,对其进行了一点修改)。问题是您将指针的地址而不是指针本身发送到函数printf


考虑如何从
ptr
重新创建
d
的值(您需要执行与设置
项[0]的值相反的过程)。x
)使用大写字母命名变量,如
Items
,这是您要避免的事情。这读起来像是类定义,但显然不是这样。@tadman中没有类定义C@M.M“为什么看到大写字母会让人困惑呢?”tadman在我看来,这表明你自己有问题,也许你是在让你的Java转换为这些错误会影响你的C编程或者其他什么
int* q = 0x22222;
int* r = &p;
#include <stdio.h>

typedef struct justArray
{
    char* x;
}
JustArray;

int main()
{
    //d is a pointer whose content is an address, not a char 'T'
    char* d = "Test";
    printf("Pointer: %p\n", d); //print the address (no need for &)
    printf("Address: %lu\n", (long unsigned) d); //print the address again as long unsigned)
    printf("Value: %s\n", d); //print a string because of the %s

    JustArray Items[12];
    Items[0].x = d;
    printf("%p\n", Items[0].x); //Items[0].x == d, so it prints the same address

    char* ptr = Items[0].x;
    printf("%p\n", ptr); //ptr == Items[0].x, so it prints again the same address
    printf("%s\n", ptr); //prints the string now because of the %s

    return 0;
}
Pointer: 0x400734
Address: 4196148
Value: Test
0x400734
0x400734
Test