警告:“int *”的初始化从'整数'将数组分配给 int 指针时,无需强制转换即可从整数生成指针

发布于 2025-01-13 21:01:57 字数 1354 浏览 3 评论 0原文

我正在研究指针,这就是我学到的:-

int a = 23;
int *ptr = &a;

char b = 'b';
char *pnt = &b;

char *str = "string";

分配给指针的值是一个地址。所以我不能做 int *ptr = 7;char *k = 'c';。但我可以这样做 char *str = "string"; 因为“string”不是一个字符,而是一些字符值的数组,因为字符和指针彼此非常相似,所以在上面的代码中如果我打印 printf("%p", str); 应该打印保存在 str 中的地址,该地址应该是字符串 的起始地址的地址(这是我想知道的第一部分我是对还是错)

所以在另一种方法是执行 char *str = "string"; 我只是创建一个字符数组,例如 {'s','t','r','i','n ','g'}(也许这听起来很愚蠢,但事实就是如此) 所以我想为什么不尝试 char *str = {'s','t','r','i ','n','g'};,我认为 printf("%p\n", str) 将再次给出字符串的起始地址,但在获得一些奇怪的值之后并运行 printf("%c", str) 返回's'我发现它给出了数组的第一个元素而不是地址。我尝试了与 int 数组相同的操作,并注意到一条警告说

int *array = {1,2,3};

警告:从“int”初始化“int *”会使指针来自整数而无需强制转换

根据我对此的理解,编译器将 {1,2,3} 视为 int 而不是数组,我不确定为什么,但如果我显式地转换它运行良好,如int *array = (int[]){1,2,3}。我不确定为什么我需要明确告知,但我认为这就是编译器

  • 在执行 int *array = {1,2,3}; 后看到的方式编译器正在获取 {1,2 的地址,3}。
  • 但是当编译器看到该地址有一个 int 时,它只读取该 int
  • 并且编译器将其视为 int *array = 1 而不是 int *array = {1,2,3}< /code>

我不知道我的理论是否正确。如果没有,我想知道为什么会发生这种情况以及为什么执行 char *str = "string" 不需要任何转换。

I was studying pointers and this is what i learned:-

int a = 23;
int *ptr = &a;

char b = 'b';
char *pnt = &b;

char *str = "string";

Value assigned to a pointer is an address. So i can't do int *ptr = 7; or char *k = 'c';. But i can do char *str = "string"; because "string" is not a char but an array of some char values, as chars and pointers are quite similar to each other, So in above code if i print printf("%p", str); should print address saved in str which should be the address of starting address of string (This is the 1st part where i want to know i am right or wrong)

So in another way by doing char *str = "string"; i am just creating an array of chars like {'s','t','r','i','n','g'}. (maybe this is going to sound very stupid but that's what it is) So i thought why not try char *str = {'s','t','r','i','n','g'};, i thought that printf("%p\n", str) will again give starting address of string but after getting some weired value and running printf("%c", str) returned 's' i found it is giving the very 1st element of array instead of address. and i tried same with int array and noticed a warning saying

int *array = {1,2,3};

warning: initialization of 'int *' from ' int' makes pointer from integer without a cast

As per my understanding of this, compiler treating {1,2,3} as an int not as an array, i am not sure why but if i cast explicitly it is running fine like int *array = (int[]){1,2,3}. I am not sure why i need to tell explicitly but i think this is how compiler sees it

  • after doing int *array = {1,2,3}; compiler is getting an address of {1,2,3}.
  • but when compiler sees there is an int at that address it is reading that int only
  • and compiler sees it like int *array = 1 not int *array = {1,2,3}

i don't know if my theory is right or not. If not please i want to know why this is happening and why doing char *str = "string" doesn't need any cast.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花开半夏魅人心 2025-01-20 21:01:57

在 C 中,字符串文字具有字符数组类型。例如,字符串文字 "string" 作为 char[7] 类型的以下数组存储在内存中:

{ 's', 't', 'r', 'i', 'n', 'g', '\0' }

您可以使用以下调用来检查这一点

printf( "sizeof( \"string\" ) = %zu\n", sizeof( "string" ) );

:很少有例外的表达式会隐式转换为指向其第一个元素的指针。

来自 C 标准(6.3.2.1 左值、数组和函数指示符)

3 除非它是 sizeof 运算符或一元 & 的操作数。
运算符,或者是用于初始化数组的字符串文字,
具有“类型数组”类型的表达式被转换为
类型为“指向类型的指针”的表达式,指向初始值
数组对象的元素并且不是左值。如果数组对象
有寄存器存储类,行为未定义

因此在此声明中,

char *str = "string";

与编译器存储的字符串文字对应的数组(通常在字符串文字池中)将转换为指向其第一个元素的指针,并将指针的值分配给标量对象str

str 不是数组。 str 是一个指针。

上述声明也可以按以下方式重写

char *str = &"string"[0];

。此声明

char *str = {'s','t','r','i','n','g'};

是不正确的。标量对象可以通过仅包含一个赋值表达式的花括号列表来初始化。

来自 C 标准(6.7.9 初始化)

11 标量的初始值设定项应为单个表达式,
可选择用大括号括起来。该对象的初始值为
表达式的(转换后);相同的类型约束和
与简单赋值一样的转换适用,采用的类型
标量是其声明类型的非限定版本。

例如,您可以这样写:

char *str = { ( 's','t','r','i','n','g' )};

在这种情况下,大括号内有一个带有逗号运算符的主表达式。事实上,这个声明相当于

char *str = { 'g' };

,编译器将发出一条消息,表明您正在尝试用整数初始化指针。

在这个声明中

int *array = (int[]){1,2,3};

没有强制转换。构造 (int[]){1,2,3} 表示 int[3] 类型的复合文字,并且再次表示该数组的第一个元素的地址被分配给指针数组

您可以通过以下方式想象上述声明

int compound_literal[] = { 1, 2, 3 };
int *array = compound_literal;

In C string literals have character array types. For example the string literal "string" is stored in memory as the following array of the type char[7]:

{ 's', 't', 'r', 'i', 'n', 'g', '\0' }

You can check this by using the following call

printf( "sizeof( \"string\" ) = %zu\n", sizeof( "string" ) );

Arrays used in expressions with rare exceptions are implicitly converted to pointers to their first elements.

From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)

3 Except when it is the operand of the sizeof operator or the unary &
operator, or is a string literal used to initialize an array, an
expression that has type ‘‘array of type’’ is converted to an
expression with type ‘‘pointer to type’’ that points to the initial
element of the array object and is not an lvalue. If the array object
has register storage class, the behavior is undefined

So in this declaration

char *str = "string";

the array that corresponds to the stored string literal by the compiler (usually in a string literal pool) is converted to pointer to its first element and the value of the pointer is assigned to the scalar object str.

str is not an array. str is a pointer.

The above declaration may be rewritten also the following way

char *str = &"string"[0];

This declaration

char *str = {'s','t','r','i','n','g'};

is incorrect. A scalar object may be initialized by a braced list that contains only one assignment expression.

From the C Standard (6.7.9 Initialization)

11 The initializer for a scalar shall be a single expression,
optionally enclosed in braces. The initial value of the object is that
of the expression (after conversion); the same type constraints and
conversions as for simple assignment apply, taking the type of the
scalar to be the unqualified version of its declared type.

You could write for example

char *str = { ( 's','t','r','i','n','g' )};

In this case within the braces there is a primary expression with the comma operator. In fact this declaration is equivalent to

char *str = { 'g' };

and the compiler will issue a message that you are trying to initialize a pointer with an integer.

In this declaration

int *array = (int[]){1,2,3};

there is no casting. The construction (int[]){1,2,3} denotes a compound literal of the type int[3] and again the address of the first element of this array is assigned to the pointer array.

You may imagine the above declaration the following way

int compound_literal[] = { 1, 2, 3 };
int *array = compound_literal;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文