[英]How does this C code print the correct String?
我有的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct island{
char *name;
struct island *previous;
} island;
void printIsland(island is){
printf("%s\n", is.name);
if(is.previous != NULL){
printf("Previous island: %s", *(is.previous));
}
}
int main(){
// the file to be read.
FILE *islandsFile = fopen("islands.txt","r");
// temporary location to store the name read from the file.
char name[40];
// temporary pointer to an island which has been already read for linking.
island *previousIsland = NULL;
while(fscanf(islandsFile,"%s",name) != EOF){
// allocate space for a new island and point to it with (*newIsland) pointer
island *newIsland =malloc(sizeof(island));
// assign name
newIsland->name = strdup(name);
newIsland->previous = previousIsland;
// now previousIsland is the newIsland..
previousIsland = newIsland;
printIsland(*newIsland);
puts("");
}
fclose(islandsFile);
}
该文件是这样的:
islandone
islandtwo
islandthree
输出将是:
islandone
islandtwo
Previous island: islandone
islandthree
Previous island: islandtwo
但是为什么呢
printf("Previous island: %s", *(is.previous))
打印岛名? 您可能还希望我能打印出什么,我不知道,因为我确实不小心尝试了。 如何打印岛名?
确保将结构放置在内存中,并且在其第一个元素之前不填充。 这意味着,例如,指向该结构的指针和指向该结构的第一个元素的指针是同一件事。
printf
没有任何能力来实际检查传递给它的内容,但是相信格式字符串中的描述是对参数列表的准确表示(注意,一个好的编译器仍然会添加该检查)。 因此, printf
假定其接收的参数为char *
并相应地对其进行解释。
因为你实际上传递的参数是有一个结构char*
中的领先地位,在这样的说法时隙的数据是相同的, 将一直在争论时隙的数据,如果你已通过了整个结构的刚成员,而不是。
在这种情况下,数据也跟随结构的其余部分这一事实在任何情况下都不会影响任何事情,因为- 仅因为-格式字符串未指示printf
查找更多参数。 确实有更多的数据传递给它,并且如果字符串期望有更多的参数,那么该island
的其余成员将陷入困境并破坏参数列表。
这样做通常是不安全的,在处理指针 (而不是按值传递的结构)时,您实际上仅应依靠struct first-element-layout规则。
*(is.previous)
是结构本身。 该结构按值传输到printf
,即复制到堆栈中。 struct的第一个字段是name
指针,它只是char*
,而printf
只是采用了char*
。 由于printf
是vararg,因此调用方在调用后清除堆栈。
PS尽管*(is.previous)
意外起作用,但是必须将代码更改为is.previous->name
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.