简体   繁体   English

C 语言,在赋值中做隐式转换

[英]The C language, does implicit conversion in assignments

The C language, does implicit conversion in assignments, both from smaller types to larger types and from larger types to smaller ones, is that it? C 语言在赋值中进行隐式转换,从较小的类型到较大的类型以及从较大的类型到较小的类型,是吗?

#include <stdio.h>

int main(void) {
   int x = 5;
   long y = x; // conversion implicit ?

   long a = 12;
   int b = a; // conversion implicit ?
   return 0;
}

Another thing, have you written in the language standard about conversions when using the assignment operator?另一件事,您是否在使用赋值运算符时用语言标准编写了有关转换的内容?

I'll try to explain what the C standard says formally.我将尝试正式解释 C 标准的内容。 We can start by reading 6.5.16.1/2:我们可以从阅读 6.5.16.1/2 开始:

In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.简单赋值(=)中,将右操作数的值转换为赋值表达式的类型,并替换存储在左操作数指定的 object 中的值。

Simple assignment meaning = , as opposed to the various compound assignments like for example += .简单的赋值意味着= ,而不是像+=这样的各种复合赋值

The above mentioned conversion only happens if the assignment is a valid form.上述转换仅在赋值是有效形式时才会发生。 There's a list of all forms of valid assignments (you don't need to read it, I'm including it here for the sake of completeness):有一个包含所有 forms 个有效作业的列表(您不需要阅读它,为了完整起见,我将其包含在此处):

6.5.16.1 Simple assignment 6.5.16.1 简单赋值

Constraints约束条件

One of the following shall hold:满足以下条件之一:

  • the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;左操作数具有原子、限定或非限定算术类型,右操作数具有算术类型;
  • the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;左操作数具有与右操作数兼容的结构或联合类型的原子、限定或非限定版本;
  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;左操作数具有原子、限定或非限定指针类型,并且(考虑左操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针,并且 left 指向的类型具有所有右边指向的类型的限定符;
  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of void, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;左操作数具有原子、限定或非限定指针类型,并且(考虑左操作数在左值转换后将具有的类型)一个操作数是指向 object 类型的指针,另一个是指向限定或非限定版本的指针void,左边指向的类型具有右边指向的类型的所有限定符;
  • the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant;左边的操作数是一个原子的、限定的或非限定的指针,右边的是一个 null 指针常量; or或者
  • the left operand has type atomic, qualified, or unqualified _Bool, and the right is a pointer.左侧操作数的类型为原子、限定或非限定 _Bool,右侧是指针。

If a type of assignment is not on that list, it is a "constraint violation", meaning invalid C, and the compiler must issue a message about it.如果某类赋值不在该列表中,则为“约束违规”,表示无效 C,编译器必须发出有关它的消息。

If an assignment is on that list, the right operand is implicitly converted to the type of the left operand.如果该列表中有赋值,则右操作数将隐式转换为左操作数的类型。 In your case long y = x;在你的情况下long y = x; , it fits the first bullet in the list: the left operand is an arithmetic type (integer or float) and the right operand is also arithmetic type. , 它符合列表中的第一个项目符号:左操作数是算术类型(整数或浮点数),右操作数也是算术类型。 So the int operand x gets converted to long upon assignment.所以int操作数x在赋值时被转换为long


Regarding qualifiers:关于预选赛:

All the stuff about "qualified type" refers to const etc type qualifiers.所有关于“限定类型”的东西都是指const等类型限定符。 During assignment, something called lvalue conversion occurs.在赋值过程中,会发生称为左值转换的事情。 6.5.16/3: 6.5.16/3:

The type of an assignment expression is the type the left operand would have after lvalue conversion.赋值表达式的类型是左操作数在左值转换后的类型。

Not very helpful if you don't know what an "lvalue conversion" is.如果您不知道什么是“左值转换”,则帮助不大。 The formal definition is found in 6.3.2.1/2, but it's equally unhelpful for beginners.正式定义在 6.3.2.1/2 中找到,但它对初学者同样没有帮助。 To summarize it in simple terms, lvalue conversion means that it doesn't matter what qualifiers ( const , volatile etc) the right operand has, it gets converted to have the same qualifiers as the left operand.简而言之,左值转换意味着无论右操作数具有什么限定符( constvolatile等),它都会被转换为与左操作数具有相同的限定符。 The term "lvalue" actually originates from "left value of the assignment operator". “左值”一词实际上来源于“赋值运算符的左值”。

From my knowledge it does, you can use print statements and see the warning about the types.据我所知,您可以使用打印语句并查看有关类型的警告。

#include <stdio.h>

int main(void) {
   int x = 5;
   printf("%d ",x);
   long y = x; // conversion implicit ?
   printf("%d ",y);


   long a = 12;
   printf("%ld ",a);
   int b = a; // conversion implicit ?
   printf("%ld ",b);
   return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM