Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中查找短int变量的最大值_C_Size_Short_Typecase - Fatal编程技术网

在C中查找短int变量的最大值

在C中查找短int变量的最大值,c,size,short,typecase,C,Size,Short,Typecase,我在做K&R的练习2-1,目标是计算不同变量类型的范围,下面是我计算ashort int可以包含的最大值的函数: short int max_short(void) { short int i = 1, j = 0, k = 0; while (i > k) { k = i; if (((short int)2 * i) > (short int)0) i *= 2; else {

我在做K&R的练习2-1,目标是计算不同变量类型的范围,下面是我计算a
short int
可以包含的最大值的函数:

short int max_short(void) {
    short int i = 1, j = 0, k = 0;
    while (i > k) {
        k = i;
        if (((short int)2 * i) > (short int)0)
            i *= 2;
        else {
            j = i;
            while (i + j <= (short int)0)
                j /= 2;
            i += j;
        }
    }
    return i;
}
short int max_short(无效){
短整数i=1,j=0,k=0;
while(i>k){
k=i;
如果(((短整数)2*i)>(短整数)0)
i*=2;
否则{
j=i;

虽然(i+j您不能使用这样的计算来推断有符号整数的范围,因为有符号整数溢出具有未定义的行为,而缩小转换范围最多只能导致实现定义的值,或引发信号。正确的解决方案是只使用
SHRT\u MAX
INT\u MAX
…即可。在标准化的C语言中,通过算术推导有符号整数的最大值是一个棘手的问题,自1989年第一个标准发布以来一直如此

请注意,K&R的原始版本比C的标准化早了11年,甚至是第二个版本,即“ANSI-C”版本早于最终确定的标准,与之有些不同,它们是为一种与当今的C语言不完全不同的语言编写的

对于无符号整数,您可以轻松地执行此操作:

unsigned int i = -1;
// i now holds the maximum value of `unsigned int`.

在比较过程中,您忘记强制转换为短int

好的,这里我假设计算机会处理整数溢出行为,将其转换为负整数,正如我相信您在编写这个程序时所假设的那样

输出32767的代码:

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
short int max_short(void)
{
    short int i = 1, j = 0, k = 0;
    while (i>k)
    {
        k = i;
        if (((short int)(2 * i))>(short int)0)
            i *= 2;
        else
        {
            j = i;
            while ((short int)(i + j) <= (short int)0)
                j /= 2;
            i += j;
        }
    }

    return i;
}

int main() {
    printf("%d", max_short());
    while (1);
}
#包括
#包括
#包括
短整数最大_短(空)
{
短整数i=1,j=0,k=0;
while(i>k)
{
k=i;
如果(((短整型)(2*i))>(短整型)0)
i*=2;
其他的
{
j=i;

虽然((short int)(i+j)根据定义,您无法通过使用同一类型的变量来计算C中类型的最大值。这根本没有任何意义。当类型“超过顶部”时,它将溢出。在有符号整数溢出的情况下,行为是未定义的,这意味着您如果尝试它,将得到一个重大错误

正确的方法是从limits.h中简单地检查
SHRT\u MAX

另一种有点可疑的方法是,创建一个
无符号短码的最大值,然后将其除以2。我们可以通过对值0进行位反转来创建最大值

#include <stdio.h>
#include <limits.h>

int main()
{ 
  printf("%hd\n", SHRT_MAX); // best way

  unsigned short ushort_max = ~0u;
  short short_max = ushort_max / 2;
  printf("%hd\n", short_max);

  return 0;
}
#包括
#包括
int main()
{ 
printf(“%hd\n”,SHRT_MAX);//最佳方式
无符号短U最大值=~0u;
short-short\u max=ushort\u max/2;
printf(“%hd\n”,短\u max);
返回0;
}

关于代码的一个注意事项:


((short int)2*i)>(short int)0这样的强制转换是完全多余的。C语言中的大多数二进制运算符,如
*
实现了一种称为“常用算术转换”的功能,这是一种隐式转换和平衡表达式类型的方法。这些隐式转换规则将使两个操作数的类型均为
int
,而不考虑您的强制转换。

Short int int是有符号类型,如果值超过其正容量,它将溢出到负范围。最好的方法是查看语句中的“limits.h”很遗憾,“如果值超过,则溢出到负范围”不正确。正确的语句是“行为未定义”“AnttiHaapala,我道歉。你是对的!而且,演员是纯粹的废话。在演员阵容之后,通常的算术转换仍然在关系操作符的两个操作数上执行。这意味着它最终被作为<代码> int <代码>。这也不是标记C++。我知道,但是这正是海报试图做的,而且实际上可以超额完成。ut正确的值,尽管它实际上无效“3否则,新类型是有符号的,并且不能在其中表示该值;结果是实现定义的,或者引发了实现定义的信号。”强制转换
(short int int)(2*i)
有一定的意义,因为
int
产品
2*i
如果没有溢出,将在“已定义实现或发出已定义实现的信号”中转换为
short
。结果随后提升为
int
,但产品的缩小意味着
((short int int int)(2*i))>(短int)0)
在功能上不一定与
(2*i>0)相同
噢,我的理解是,如果你一直将一个“1”乘以2,“1”最终会一直移动到符号位位置,使整个变量为负数……因此没有办法计算最大值?我认为这项练习的重点是找到一个要做的计算so@Ryuuzaki_kun否,将1移到符号位位置n有未定义的行为,无论是通过
@ryuuuzaki_kun,这种未定义的行为允许许多优化,例如-这是C编程语言中最大的警告之一。我不太确定这是一个诡计问题。检查我的答案,寻找一种方法。我想不出会失败的场景-它应该涵盖模糊的补充还有符号和大小系统。您可能想补充一点,这种方法已经过时,因为自1990年以来,不可移植且C标准将算术溢出指定为未定义的行为。K&R比这早了15年,并且它曾经是一种可接受的测试环绕的方法。使用这种方法失败的角落案例:最大值有符号整数的最大值可能等于相应无符号整数的最大值。这种实现非常罕见,但C允许。我只遇到过最宽的无符号类型,而不是
short
。Minor:
unsigned short ushort\u max=~0u;
可以使用
unsigned short
,但在使用des时不太好tination类型比
u更宽