伙计我在指针中几乎没有查询。请帮助解决它们
char a[]="this is an array of characters"; // declaration type 1
char *b="this is an array of characters";// declaration type 2
问题1:这两种声明有什么区别?
printf("%s",*b); // gives a segmentation fault
printf("%s",b); // displays the string
问题2:我没知道它是如何运作的
char *d=malloc(sizeof(char)); // 1)
scanf("%s",d); // 2)
printf("%s",d);// 3)
问题3为指针c分配了多少字节?
当我尝试输入一个字符串时,它只需要一个单词而不是整个字符串。为什么呢?
char c=malloc(sizeof(char)); // 4)
scanf("%c",c); // 5)
printf("%c",c);// 6)
问题4当我尝试输入字符时为什么会抛出分段错误?
提前致谢..等待你的回复...
答案 0 :(得分:2)
printf("%s",*b); // gives a segmentation fault
printf("%s",b); // displays the string
%s需要一个指向字符数组的指针。
char *c=malloc(sizeof(char)); // you are allocating only 1 byte aka char, not array of char!
scanf("%s",c); // you need pass a pointer to array, not a pointer to char
printf("%s",c);// you are printing a array of chars, but you are sending a char
你需要这样做:
int sizeofstring = 200; // max size of buffer
char *c = malloc(sizeof(char))*sizeofstring; //almost equals to declare char c[200]
scanf("%s",c);
printf("%s",c);
问题3为指针c分配了多少字节?当我 尝试输入一个字符串,它只需要一个单词而不是整个字符串。 为什么呢?
在你的代码中,你只分配1个字节,因为sizeof(char)= 1byte = 8bit,你需要分配sizeof(char)* N,N是你的"字符串"大小
答案 1 :(得分:1)
我在你的代码中看到了几个问题。
问题1:区别在于:
a
被分配在可写内存中,即所谓的data
段。在这里,您可以根据需要进行读写。 sizeof a
是字符串的长度加1,即所谓的字符串终止符(只是一个空字节)。b
只是指向rodata
中字符串的指针。这意味着,在一个只读的数据区域。 sizeof b
是系统上的指针大小,PC上可能是4或8,许多嵌入式系统上可能是2。问题2:printf()
格式需要指向字符串的指针。使用*b
,您可以取消引用指针,并为其提供数据的第一个字节,即t
(ASCII 84或类似的东西)。然而,被调用者将其视为指针,取消引用它和BAM。
然而,使用b
,一切都很顺利,因为这是正确的呼叫。
问题3:malloc(sizeof(char))
只分配一个字节。根据定义,sizeof(char)
为1
,因此有效调用malloc(1)
。输入只是一个字,因为%s
就是这样定义的。
问题4:
char c=malloc(sizeof(char)); // 4)
shound给你一个警告:malloc()
返回一个你试图放入char
的指针。 ITYM char *
...
当你继续时,你将指针指向scanf()
,它接收例如0x80043214
。而不是0x14
仅仅char * c=malloc(1024);
scanf("%1024s", c);
printf("%s", c);
,将其解释为指针和BAM。
正确的方法是
scanf()
为什么呢?好吧,你想读一个字符串。 1个字节太小,更好地分配更多。
在%s
中,您应该注意不要允许读取比缓冲区更多的读取 - 因此格式说明符的限制。
在打印时,您应该使用{{1}},因为您希望打印整个字符串而不仅仅是第一个字符。 (至少,我想是这样。)
答案 2 :(得分:1)
char a[]="this is an array of characters"; // declaration type 1
char *b="this is an array of characters";// declaration type 2
在这里,您要声明两个变量a
和b
,然后对其进行初始化。 "this is an array of characters"
是一个字符串文字,在C中有char类型数组。 a
具有char类型数组。在这种特定情况下,数组不会转换为指针,a
会使用数组"this is an array of characters"
进行初始化。 b
具有指向char的类型指针,数组将转换为指针,并使用指向数组b
的指针初始化"this is an array of characters"
。
printf("%s",*b); // gives a segmentation fault
printf("%s",b); // displays the string
在表达式中,*b
取消引用指针b
,因此它计算为b
指向的char,即:T
。这不是一个地址(这是“%s”所期望的),所以你得到了未定义的行为,很可能是崩溃(但是不要试图在嵌入式系统上这样做,你可能会得到神秘的行为和损坏的数据,比崩溃还糟糕。在第二种情况下,%s
需要一个指向char的指针,获取它,并且可以继续执行它的操作。
char *d=malloc(sizeof(char)); // 1)
scanf("%s",d); // 2)
printf("%s",d);// 3)
在C中,sizeof
返回对象(=存储区域)的字节大小。在C中,char被定义为与字节相同,其具有至少8位,但可以具有更多(但是一些标准存在额外的限制,例如:POSIX需要8位字节,即:八位字节)。所以,你要分配1个字节。当你调用scanf()
时,它会无限制地写入d
指向的内存中,覆盖所有内容。 scanf()
允许最大字段宽度,因此:
scanf()
停止,例如:scanf("%19s")
最多19个字符(你需要20个字节来存储它,计算终止的ASCII NUL)。最后(如果降价让我):
char c=malloc(sizeof(char)); // 4)
scanf("%c",c); // 5)
printf("%c",c);// 6)
c
不是指针,所以你试图存储一个你不应该存在的地址。在scanf
中,"%c"
需要一个指向char的指针,该指针应指向一个对象(=存储区域),该对象具有足够的空间用于指定的字段宽度,默认为1。由于c
不是指针,因此在某些平台上可能会崩溃(并导致其他平台出现更糟糕的情况)。
答案 3 :(得分:0)
Ad Q1:第一个是一个字符数组,其中一个固定指针指向它。 sizeof(a)
将返回类似20(strlen(a)+1
)的内容。尝试将某些内容分配给a(如a = b
)将失败,因为a是固定的。
第二个是指向char数组的指针,因此sizeof(b)通常是32位上的4或64位上的8。将某些内容分配给b将起作用,因为指针可以采用新值。
当然,* a或* b同时适用于这两种情况。
广告Q2:带有%s参数的printf()
将指针带到char(这些是C中的“字符串”)。因此,printf("%s", *b)
将崩溃,因为printf()使用的“指针”将包含* b的字节值。
Ad Q3:printf("%c", *b)
为1(根据定义),因此您分配1个字节。 scanf很可能会读取多个字节(请记住,每个字符串将由占用一个字符的空字符终止)。因此,scanf会丢弃内存,可能会在以后的某个时间内导致内存。
广告4:也许那是被遗忘的记忆。
答案 4 :(得分:-1)
两种声明都是一样的。 b指向第一个字节,所以当你说* b时它是第一个字符。 printf(“%s”,* b) 将失败,因为%s接受指向字符串的指针。 char是一个字节。