$dataframe1
a b
1 1
2 1
3 1
4 1
5 1
$dataframe2
a b
5 1
5 1
5 1
这是一个运行良好的代码,我只是一个小问题。
在结构部分中,在#include <stdio.h>
typedef struct {
char * name;
int age;
} person;
int main() {
person john;
/* testing code */
john.name = "John";
john.age = 27;
printf("%s is %d years old.", john.name, john.age);
}
之前删除*
之后,此代码不再有效,但无论name
的类型是,int还是指针,它都是总是很好。那么有谁可以告诉我为什么age
必须是指针而不仅仅是一种char?
答案 0 :(得分:2)
char
类型是字符的缩写,可以容纳一个字符。 C没有string
类型,而C中的字符串是以char
结尾的'\0'
数组 - 空字符(空终止字符串)。
因此,要使用字符串,您需要一个指向包含大量字符的内存的指针。那么,为什么它适用于int
有{@ 1}}的情况。好吧,我们可以将年龄定为*
,或者我们可以指向存储年龄的内存。要么效果很好。但我们不能将字符串存储在一个字符中。
答案 1 :(得分:1)
这与printf
函数中的格式说明符有关。 %s
尝试输出字符串(读取内存的一部分),%d
将整个内容中的所有内容解释为整数,因此即使是指针类也可以,但是,您不应该这样做,它是未定义的行为。
我建议你阅读一些关于C的好书,以便很好地掌握这些事情,这里有一个很好的清单The Definitive C Book Guide and List
答案 2 :(得分:1)
但无论年龄的类型是int还是指针,它总能正常工作。
这是未定义的行为。
详细说明,双引号分隔的字符串(如上所示)是字符串文字,当用作初始化程序时,它基本上为您提供指向文字起点的指针,从而它需要一个指针变量来存储。因此,name
必须是指针。
OTOH,初始值设定项27
是整数文字(整数常量),需要将其存储到int
变量中,而不是int *
。如果您使用27
来初始化int *
并使用它,则可以(相反,似乎有效),因为这样,它稍后会调用undefined behavior试图使用无效的内存位置。
FWIW,如果您尝试类似
的话typedef struct {
char * name;
int *age;
} person;
然后
john.age = 27; //incompatible assigment
编译器会警告您从整数到指针的错误转换。
答案 3 :(得分:0)
char *name
:name
是指向char
类型的指针。现在,当你指向"John"
时,编译器将John\0
即5个字符存储到某个内存中,并返回该内存的起始地址。因此,当您尝试使用%s
(字符串格式说明符)进行阅读时,name
变量会将整个字符串读取返回到\0
。
char name
:这里name
只是一个有1个字节内存的字符。因此,您不能存储多于一个char的内容。此外,当您尝试阅读时,您应该始终只读取一个字符(%c
),因为尝试阅读更多字符会将您带到未分配给您的内存区域,因此会调用{{ 3}}
int age
:age
分配了4个字节,因此您可以将整数存储到此内存中并读取,printf("%d", age);
int *age
:age
是一个指向int类型的指针,它存储一些内存的地址。与字符串不同,您不会使用地址读取整数(松散地说,只是为了避免复杂性)。你必须取消引用它。首先,您需要分配一些内存,将任何整数存储到其中,并将此内存的地址返回到age
。或者,如果您不想分配内存,可以使用编译器的帮助,为age
分配一个值,*age = 27
。在这种情况下,编译器会将27
存储到某个随机内存中,并将地址返回到age
,可以使用*age
取消引用,例如printf("%d", *age);