C语言int 取最小值为啥是-32768而不能是-32769

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言int 取最小值为啥是-32768而不能是-32769相关的知识,希望对你有一定的参考价值。

哪位可以说一下.

正数最大值是32767,负数最小值是-32768
从 0到 32767,用二进制是从:00000000到01111111 ①
从-1到-32768,用二进制是从:11111111到10000000 ②
注意到:①和②里对应的数相加是:11111111.
参考技术A 因为int为两个字节,除去一个符号位,最大只能表示32768,所以最小为-32768 参考技术B 两个字节是16位(一个字节8位),除去一个符号位,也就是15位,2的15次方也就是32768了。

为啥 C 函数不能返回数组类型? [复制]

【中文标题】为啥 C 函数不能返回数组类型? [复制]【英文标题】:Why can't C functions return an array type? [duplicate]为什么 C 函数不能返回数组类型? [复制] 【发布时间】:2015-12-13 18:28:39 【问题描述】:

我是 C 语言的新手,我想知道:

为什么 C 函数不能返回数组类型?

我知道数组名是数组第一个值的地址,而数组是 C 中的二等公民。

【问题讨论】:

相关帖子:***.com/questions/5157439/…。它是关于 C++ 的,但 C++ 这样做是因为 C。 如果你使用 C++11,你可以传递一个数组容器:std::array<int, 3> a2 = 1, 2, 3;,它具有像普通数组一样的运算符。 没有真正的数组是从 1970 年代的语言继承而来的。您可以通过将数组包装在 struct 中来解决此限制。 APL 可以追溯到 1960 年代,适用于“真实”数组,包括多维数组。回到问题,这是设计 C 语言以通过引用而不是通过值传递数组的人们做出的选择。 不同意将 C 问题链接到 C++ 副本 【参考方案1】:

因为在 C 中实际上没有任何类似于 Java 等语言的数组类型的数组类型。如果源代码提供了该信息,现代 C 编译器将执行一致性检查,但是有多年的 C 源代码是在现代编译器之前编写的,并且源代码需要与现代 C 编译器一起使用。

如果你愿意,你可以返回一个指向数组的指针,并且你可以使用与使用数组相同的指针语法,只要使用下标(例如,*aa[0] 相同,用于某些指针 @987654324 @)。

或者您可以返回 struct,然后您可以使用它来提供在 Java 等语言中看到的数组类型的一些功能。

因此您可以执行以下操作。

typedef  struct 
    things *array;
    int    iCount;
 MyArrayType;

然后你可以做一些事情,比如分配一个数组,然后返回它。

MyArrayType myFuncIntArray (int iCount)

    MyArrayType ret = 0;

    ret.array = malloc (iCount * sizeof(things));
    ret.iCount = iCount;

    return ret;

当然,您可以更改函数以创建您想要创建的任何类型的数组。不幸的是,您还需要负责在完成后释放内存,因为垃圾收集不是 C 的核心产品,尽管有 Boehm-Demers-Weiser garbage collector for C and C++。

C 之所以这样做,是因为设计它的聪明人是这样做的,而 C 标准委员会在大约 40 年里没有改变它。

C 的最初设计目标是代码的简单性和简洁性,以及通过函数库实现核心语言的可扩展性,以保持 C 编译器的简单和小巧,同时为程序员提供灵活性。生成的机器代码的高性能也是设计目标。然而,这些设计目标也将程序正确性和性能的重大责任放在了程序员身上。

【讨论】:

但是有数组类型。而你没有回答这个问题。 @juanchopanza,Java 具有数组类型,就像 C# 等大多数托管类型的语言一样。 C 有什么相当于数组的语义糖。因此,您可以像使用数组一样使用带索引的指针。 不会改变 C 具有数组类型的事实。它们的语义可能与其他语言中的数组不同,但这是另一回事。 @juanchopanza,“只是语义问题”?语义,意义,是所有交流的组成部分。不同的语义,不同的意义,不同的交流方式,不同的语言。类型数组和数组类型是有区别的。 @RichardChambers:鉴于int *ptr;int arr[1];,你认为ptrarr 具有相同的类型吗?仅仅因为数组很容易衰减为指针并不意味着它们是同一回事。【参考方案2】:

你自己已经回答了这个问题:数组是二等公民。

C 按值返回。数组不能传值,所以不能返回。

至于为什么数组不能按值传递:这是 K&R 在最初设计语言时做出的设计决定,现在更改它为时已晚,因为所有现有的 C 代码都会损坏。

【讨论】:

这个答案虽然正确,但并不能解释 K&R 设计决策的动机。有关 K&R 设计决策的简明理解,请参阅 John Bode 的回答,或参阅 Barmar 进行更长时间的讨论。【参考方案3】:

基于The Development of the C Language,看起来真正的原因主要与C从B和BCPL的演变有关。 B 没有数组变量,它只有指针。它也没有结构。当结构被添加到 C 中,并且它们被允许包含数组成员时,他需要一种方法来处理这些封闭的数组,类似于处理 B 样式数组的方式,解决方案是让数组在任何时候都转换为指针re 用在表达式中。这是论文中解释这一点的部分。

当我尝试扩展类型符号时,问题变得很明显,尤其是 添加结构化(记录)类型。结构似乎应该以直观的方式映射到内存 在机器中,但是在包含数组的结构中,没有好地方来存放指针 包含数组的基数,也没有任何方便的方式来安排它被初始化。为了 例如,早期 Unix 系统的目录条目在 C 中可能被描述为

struct 
     int inumber;
     char name[14];
  ;

我希望这个结构不仅可以描述一个抽象对象,还可以描述一个集合 可能从目录中读取的位。编译器可以在哪里隐藏指向的指针 语义要求的名称?即使结构被认为更抽象,并且 指针的空间可能会以某种方式隐藏,我该如何正确处理技术问题 在分配一个复杂的对象时初始化这些指针,也许是一个指定的对象 包含包含任意深度结构的数组的结构?

该解决方案构成了无类型 BCPL 之间进化链中的关键跳跃 并键入 C。它消除了指针在存储中的具体化,而是导致 在表达式中提到数组名称时创建指针。规则,生存下来 在今天的 C 语言中,数组类型的值在出现在表达式中时会被转换, 指向组成数组的第一个对象的指针。

这并不特定于将数组传入和传出函数,它适用于任何时候在表达式中使用数组(除非它是 & 运算符的参数)。

另请注意,此设计允许使用 malloc() 动态分配的数组变量和内存在传递给函数时被同等对待。

【讨论】:

Ritchie 写了一篇关于 C 语言发展的论文(包括它的数组语义)——PDF 是可用的here。 相关事实:在 K&R C 中,结构也不能按值传递或返回。这是在 ANSI C 中添加的。 @M.M 我对此有一个模糊的回忆,但我不确定。【参考方案4】:

不能从函数返回数组的原因是数组类型可能不是赋值的目标。你不能写类似的东西

int arr[N];
arr = foo();

当它们出现在大多数上下文中时,数组表达式失去了它们的“数组特性”。这是 Ritchie 在 C 开发早期做出的设计决定的结果。 C 源自一种称为 B 的早期编程语言(如图),而 B 又源自 BCPL。在 B 中,数组对象指向数组第一个元素的指针,并且数组访问是根据指针算法定义的。 a[i] 被定义为*(a + i); - 从a 中存储的地址偏移i 元素 并取消引用结果。

Ritchie 保留了 B 的数组语义,但不想搁置这些语义所需的指针存储。因此,他提出了在大多数情况下将数组表达式转换(“衰减”)为指针表达式的规则。

这意味着如果arr 是数组类型,arr = foo(); 将无法工作,因为没有为名为@9​​87654328@ 的对象预留存储空间,与数组元素本身分开;没有什么可以分配给

【讨论】:

以上是关于C语言int 取最小值为啥是-32768而不能是-32769的主要内容,如果未能解决你的问题,请参考以下文章

C语言的int 为啥最小值是-32768

c语言 int的范围不是-32768~32767吗?为啥我输入了大于的数还是成立.

在C语言中为啥int型的取值范围是-32768~32767

为啥C语言中max函数不能取到最大值

c语言中long型的65530转化为int型是多少啊?为啥啊?

为啥C语言中有符号整型变量的取值范围是-32768~32767,麻烦详细解释一下?