0

伙计们,我对指针的查询很少。请帮助解决它们

char a[]="this is an array of characters"; // declaration type 1 
char *b="this is an array of characters";//  declaration type 2

question.1:这两种声明有什么区别?

    printf("%s",*b); // gives a segmentation fault
    printf("%s",b); // displays the string

question.2:我不明白它是如何工作的

    char *d=malloc(sizeof(char)); // 1)
    scanf("%s",d); // 2)
    printf("%s",d);// 3)

question.3 有多少字节被分配给指针c?当我尝试输入一个字符串时,它只需要一个单词而不是整个字符串。为什么这样 ?

    char c=malloc(sizeof(char)); // 4)
    scanf("%c",c); // 5)
    printf("%c",c);// 6)

question.4 当我尝试输入一个字符时,为什么会引发分段错误?

在此先感谢..等待您的回复。。

4

5 回答 5

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);

question.3 有多少字节被分配给指针c?当我尝试输入一个字符串时,它只需要一个单词而不是整个字符串。为什么这样 ?

在您的代码中,您只分配 1 个字节,因为 sizeof(char) = 1byte = 8bit,您需要分配 sizeof(char)*N,N 是您的“字符串”大小。

于 2012-11-22T21:19:49.683 回答
1

我在您的代码中看到了几个问题。

问题1:区别在于:

  • a被分配到可写内存中,即所谓的data段。在这里,您可以随心所欲地阅读和写作。sizeof a是字符串的长度加1,即所谓的字符串终止符(只是一个空字节)。
  • b然而,它只是一个指向位于rodata. 这意味着,在只读的数据区域中。sizeof b是您系统上的指针大小,在 PC 上可能是 4 或 8,在许多嵌入式系统上可能是 2。

问题2:printf()格式需要一个指向字符串的指针。使用*b,您取消引用您拥有的指针并为其提供第一个数据字节,即 a 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. 伊蒂姆char *...

随着您的继续,您将指针指向scanf(),它接收例如而不是0x80043214仅仅接收0x14,将其解释为指针并再次 BAM。

正确的方法是

char * c=malloc(1024);
scanf("%1024s", c);
printf("%s", c);

为什么?好吧,你想读取一个字符串。1 字节太小,最好多分配。

scanf()你应该注意你不允许读取超过你的缓冲区可以容纳的 - 因此格式说明符的限制。

在打印时,您应该使用%s,因为您希望打印整个字符串而不仅仅是第一个字符。(至少,我想是的。)

于 2012-11-22T21:18:51.433 回答
1
char a[]="this is an array of characters"; // declaration type 1 
char *b="this is an array of characters";//  declaration type 2

在这里,您要声明两个变量,ab,并初始化它们。"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,即: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()允许最大字段宽度,因此:

  • 分配更多内存,至少足以满足您的需求 + 1 终止 ASCII NUL。
  • 告诉scanf()停止,例如:scanf("%19s")最多 19 个字符(您需要 20 个字节来存储它,计算终止的 ASCII NUL)。

最后(如果降价让我):

char c=malloc(sizeof(char)); // 4)
scanf("%c",c); // 5)
printf("%c",c);// 6)

c不是指针,因此您试图将地址存储在不应该的位置。In scanf,"%c"需要一个指向 char 的指针,它应该指向一个对象(=存储区域),该对象具有足够的空间用于指定的字段宽度,默认情况下为 1。由于c不是指针,因此上述内容可能会在某些平台上崩溃(并在其他平台上导致更糟糕的事情)。

于 2012-11-22T22:26:46.170 回答
0

广告 Q1:第一个是一个字符数组,带有一个指向它 的固定指针 a。sizeof(a)将返回类似 20 ( strlen(a)+1) 的内容。尝试将某些东西分配给 a (like a = b) 将失败,因为 a 是固定的。

第二个是指向 char 数组的指针,因此 sizeof(b) 通常在 32 位上为 4 或在 64 位上为 8。将某些东西分配给 b 将起作用,因为指针可以采用新值。

当然,*a 或 *b 都适用。

广告 Q2:printf()使用 %s 参数获取指向char 的指针(这些是 C 中的“字符串”)。因此,printf("%s", *b)将崩溃,因为 printf() 使用的“指针”将包含 *b 的字节值。

可以做的是printf("%c", *b),但这只会打印第一个字符。

广告 Q3:sizeof(char)是 1(根据定义),因此您分配 1 个字节。scanf 很可能会读取超过一个字节(请记住,每个字符串都将由占用一个字符的空字符终止)。因此 scanf 会破坏内存,可能会在以后的某个时候导致内存。

广告 4:也许这就是被丢弃的记忆。

于 2012-11-22T21:29:59.763 回答
-1

两个声明都是一样的。b 指向第一个字节,所以当你说 *b 它是第一个字符。printf("%s", *b) 将失败,因为 %s 接受指向字符串的指针。char 是一个字节。

于 2012-11-22T21:16:31.697 回答