为什么不使用解引用操作符与字符串指针一起使用?

huangapple go评论83阅读模式
英文:

Why is the dereferencing operator not used with a string pointer?

问题

为什么在指向除字符串('char')以外的任何数据类型的指针上都要使用间接引用/解引用运算符(*)?

在下面的程序中,字母'A'和字符串"Computer"都是使用字符指针存储的,但只有对指针'a'使用了解引用运算符(*)。为什么会这样?

#include <stdio.h>

int main()
{
  char *a, *b;

  *a = 'A';
  b = "Computer";

  printf("%c %s", *a, b);

  return 0;
}

为什么在将字符串分配给指针时不需要使用*运算符?

英文:

Why the indirection/dereferencing operator (*) is used with a pointer of any data type except a string? 'char'

In the following program the letter 'A' and the string "Computer" are stored using the character pointers but only for the pointer 'a' the dereferencing operator (*) is used. Why is that?

#include &lt;stdio.h&gt;

int main()
{
  char *a, *b;

  *a = &#39;A&#39;;
  b = &quot;Computer&quot;;

  printf(&quot;%c %s&quot;, *a, b);

  return 0;
}

Why is the * operator not needed while assigning a string to a pointer?

答案1

得分: 2

因为 b = &quot;Computer&quot;; 不会复制字符串。&quot;Computer&quot; 被称为 "字符串字面量",它是一个字符数组。

你将指针 b 分配给了指向第一个字符串字面量字符的引用。

这相当于:

    char *b;
    const char literal[] = {&#39;C&#39;, &#39;o&#39;, &#39;m&#39;, &#39;p&#39;, &#39;u&#39;, &#39;t&#39;, &#39;e&#39;, &#39;r&#39;, 0};
    b = &amp;literal[0];
英文:

Because b = &quot;Computer&quot;; does not copy the string. &quot;Computer&quot; is called "string literal" and it is a char array.

You assign pointer b with reference to the first string literal character.

It is an equivalent of:

    char *b;
    const char literal[] = {&#39;C&#39;, &#39;o&#39;, &#39;m&#39;, &#39;p&#39;, &#39;u&#39;, &#39;t&#39;, &#39;e&#39;, &#39;r&#39;, 0};
    b = &amp;literal[0];

答案2

得分: 2

为什么在除字符串以外的任何数据类型的指针上都使用间接引用/解引用运算符(*)?

这个问题不成立,因为其前提是不正确的。当想要引用指针指向的对象时,会对指针应用解引用运算符。如果要引用指针本身,则会省略它。这两种方式都可以用于各种类型的指针。

此外,在C中,“string”不是一种数据类型。它是对char数组可以保存的值的描述:一个或多个char的序列,最后一个值为零,而其他所有值都不为零。

在以下程序中,字母'A'和字符串"Computer"都使用字符指针存储,但只有指针'a'使用了解引用运算符(*)。为什么?

同样,这是不成立的前提。下面的代码尝试将值'A'(在C中是一个int;在C++中是一个char)存储在指针'a'指向的char对象中。如果'a'实际上指向char,那么结果将是设置指向的char的值,但是'a'没有指向任何东西,从未被赋予有效的指针值,因此行为是未定义的。

另一方面,下面的代码将一个(指针)值分配给了'b'本身:

b = "Computer";

在这种情况下,该值指向一个不可修改的静态char数组的第一个字符,该数组包含字符串文字表示的char,包括字符串终止符。这是语言定义字符串文字(表示数组)的结果,以及标准规则在表达式中出现数组时的行为。

为什么在将字符串分配给指针时不需要*运算符?

因为你永远不需要或希望使用*来分配给(或从中读取)指向指针的lvalue。它的用途是访问指针值指向的对象。永远记住这些是不同的东西,有独立的标识和存储(当它们有标识和存储时)。

英文:

> Why the indirection/dereferencing operator (*) is used with a pointer of any data type except a string?

The question is moot, because its premise is incorrect. The dereferencing operator is applied to a pointer when one wants to refer to the object to which the pointer points. It is omitted to refer to the pointer itself. Both alternatives are used with pointers of every type.

Additionally, in C, "string" is not a data type. It is a description of a (part of a) value that arrays of char can hold: a sequence of one or more chars, the last having value zero, and all others being nonzero.

> In the following program the letter 'A' and the string "Computer" are stored using the character pointers but only for the pointer 'a' the dereferencing operator (*) is used. Why is that?

Again, moot because the premise is incorrect. This ...
>
&gt; *a = &#39;A&#39;;
&gt;

... attempts to store the value &#39;A&#39; (an int in C; a char in C++) in the char object to which pointer a points. If a actually pointed to a char then the result would be to set the value of that pointed-to char, but a does not point to anything, having never been assigned a valid pointer value, so the behavior is undefined.

On the other hand, this ...
>
&gt; b = &quot;Computer&quot;;
&gt;

... assigns a (pointer) value to b itself. In this case, that value points to the first char of an unmodifiable static array of char containing the chars expressed by the string literal, including a string terminator. This is a consequence of the language's definition of string literals (as representing arrays) and of the standard rules for the behavior of arrays where they appear in expressions.

> Why is the * operator not needed while assigning a string to a pointer?

Because you never need or want * to assign to (or read from) an lvalue designating a pointer. Its use is rather to access the object to which the value of a pointer points. Remember always that these are different things, with separate identity and storage (when they have identity and storage at all).

答案3

得分: 0

为了回答你的问题,我们首先需要消除一些语法糖,并确切了解b是什么:

char *b;
b = "Computer";

(几乎)等同于

const char *b;
const char str[] = {'C', 'o', 'm', 'p', 'u', 't', 'e', 'r', '
const char *b;
const char str[] = {'C', 'o', 'm', 'p', 'u', 't', 'e', 'r', '\0'};
b = &str[0];
'
};
b = &str[0];

这意味着b是指向char元素数组的第一个元素的指针。或者更简单地说,b只是指向一个char

printf("%c", *b)期望一个char%c),通过使用*b,我们向printf提供了字符串(或char数组)"Computer"的第一个char

printf("%s", b)期望一个指针(%s)。因此,我们提供了指向"Computer"b。为什么?因为在底层,printf从一个位置开始,读取一个字符,然后转到下一个位置(即b + 1)。它一直这样做,直到printf在其路径上读取到值0

因此,核心思想是,你确实在处理一个指针,但printf需要一个指针,以便遍历char数组

请注意,字符'0'不是数字0,但数字0等于字符'\0',这是你有时在char数组中看到的内容,就像我的示例中一样。

至于为什么上面的片段不完全相同的额外说明:代码中的字符串存储在只读位置,而字符数组的赋值存储在可修改的内存中。const关键字确保不可变性,但这两个字符串仍然存储在完全不同的位置,因此行为可能不同。

英文:

To answer your question, we need to get rid of some syntactic sugar first and know exactly what b is:

  char *b;
  b = &quot;Computer&quot;;

is (almost) equivalent to

  const char *b;
  const char str[] = {&#39;C&#39;, &#39;o&#39;, &#39;m&#39;, &#39;p&#39;, &#39;u&#39;, &#39;t&#39;, &#39;e&#39;, &#39;r&#39;, &#39;
  const char *b;
const char str[] = {&#39;C&#39;, &#39;o&#39;, &#39;m&#39;, &#39;p&#39;, &#39;u&#39;, &#39;t&#39;, &#39;e&#39;, &#39;r&#39;, &#39;\0&#39;};
b = &amp;str[0];
&#39;}; b = &amp;str[0];

Meaning b is a pointer to the first element in an array of char elements. Or simpler, b just points to a char

printf(&quot;%c&quot;, *b) expects a char (%c), and by using *b we are giving printf the first char from the string (or char array) &quot;Computer&quot;

printf(&quot;%s&quot;, b) expects a pointer (%s). We are thus providing b which points to &quot;Computer&quot;. Why? Because under the hood, printf starts at a location, reads a character and goes to the next location (which is b + 1). It does that until printf reads the value 0 somewhere along its path.

So the core idea is that you're indeed dealing with a pointer, but printf needs itself a pointer to go through an array of char

Note that the charatcer &#39;0&#39; is not the number 0, but the number 0 is equal to the character &#39;\0&#39; which is what you sometimes see in char arrays like in my example.

As an extra on why the above snippets are not exactly the same: A string in code is stored in a read-only location, whereas the assignment as an array of characters is stored in modifiable memory. The const keyword ensures immutability, but both of these strings are still stored in entirely different locations and thus behaviour might not be the same.

答案4

得分: 0

使用char*数据类型并将字符串分配给它时,实际上是在创建一个指向字符数组的指针,但是当你将单个字符分配给它时,你实际上是在创建一个指向单个字符的指针,例如:

char Var1 = 'A';
char Var2[9] = {'C','o','m','p','u','t','e','r','\n'};

char* a = &Var1;
char* b = Var2;
printf("%c %s\n", *a, b);

与以下代码(大致相同):

char *a = malloc(1);
char *b = malloc(8);

*a = 'A';
b = "Computer";

printf("%c %s\n", *a, b);
free(a);
free(b);

(请注意,您最初提供的代码本身无法正常运行,我稍作更改)希望这有助于您更好地理解char指针数据类型。

英文:

Whenever you use the char* data type and assign a string to it, you are actually making a pointer to an array of characters, but whenever you assign a single character to it, you are making a pointer to a single character for example:

    char Var1 = &#39;A&#39;;
    char Var2[9] = {&#39;C&#39;,&#39;o&#39;,&#39;m&#39;,&#39;p&#39;,&#39;u&#39;,&#39;t&#39;,&#39;e&#39;,&#39;r&#39;,&#39;\n&#39;};
    
    char* a = &amp;Var1;
    char* b = Var2;
    printf(&quot;%c %s\n&quot;,*a,c);

does (about) the same thing as

char *a = malloc(1);
  char *b = malloc(8);

  *a = &#39;A&#39;;
  b = &quot;Computer&quot;;

  printf(&quot;%c %s\n&quot;, *a, b);
  free(a);
  free(b);


(please take note that the code you originally provided does not function on its own and I had to change it a bit) I hope this helps you understand the char pointers data type a better

huangapple
  • 本文由 发表于 2023年7月24日 18:51:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76753750.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定