我们大学有两种远程系统;我们可以远程连接它们并工作。我在其中一个系统上写了一个C程序,其中void指针的大小和size_t变量的大小是8个字节。但是当我连接到其他系统时,我的程序开始以不同的方式工作。由于这两个系统之间的架构差异,我浪费了太多时间进行调试,并最终发现它正在发生。
我的问题是:
原始类型的大小取决于哪些因素?
在开始编程之前如何知道基元类型的大小?
如何用C编写跨平台代码?
答案 0 :(得分:1)
通常,处理器中的整数大小取决于ALU在单个周期中可以运行的位数。 对于例如
i)对于8051架构,由于数据总线大小为8位,所有8051编译器指定整数大小为8位。
ii)对于32位ARM架构,因为数据总线是8位宽,整数大小是32位。
您应该始终参考编译器文档以获取正确的数据类型大小。
几乎所有编译都将其名称/版本声明为预定义宏,您可以在头文件中使用它们,如下所示:
#ifedef COMPILER_1
typedef char S8
typedef int S16
typedef long S32
:
:
#else COPILER_2
typedef int S32
typedef long S64
:
:
#endif
然后在你的代码中你可以声明像
这样的变量S32 Var1;
答案 1 :(得分:1)
问题:
原始类型的大小取决于哪些因素?
CPU和编译器。
问题:
在开始编程之前如何知道基元类型的大小?
你做不到。但是,您可以编写一个小程序来获取基元类型的大小。
#include <stdio.h>
int main()
{
printf("Size of short: %zu\n", sizeof(short));
printf("Size of int: %zu\n", sizeof(int));
printf("Size of long: %zu\n", sizeof(long));
printf("Size of long long: %zu\n", sizeof(long long));
printf("Size of size_t: %zu\n", sizeof(size_t));
printf("Size of void*: %zu\n", sizeof(void*));
printf("Size of float: %zu\n", sizeof(float));
printf("Size of double: %zu\n", sizeof(double));
}
问题:
如何用C编写跨平台代码?
答案 2 :(得分:1)
如何用C编写跨平台代码?
如果您需要以独立于平台的方式(例如在文件系统上或通过网络)封送数据,那么(至少)这些内容应该是一致的:
数据类型 - 依靠<stdint.h>
的类型。例如,如果您需要一个双字节无符号整数,请使用uint16_t
。
数据类型对齐/填充 - 请注意struct
中的成员packed/padded的方式。成员的默认对齐方式可能会从一个系统更改为另一个系统,这意味着成员可能处于不同的字节偏移量,具体取决于编译器。在编组数据时,使用__attribute__((packed))
(在GCC上)或类似的。
字节顺序 - 可以按任意顺序存储多字节整数及其字节:Little-endian系统将最低有效字节存储在最低地址/偏移量处,而Big- endian系统从最重要的开始。幸运的是,每个人都同意字节通过网络作为big-endian发送。为此,我们使用htons
/ ntohs
在通过网络连接发送/接收多字节整数时转换字节顺序。
答案 3 :(得分:1)
问题:
原始类型的大小取决于什么因素&amp;在开始编程之前如何知道原始类型的大小?
CPU和编译器。
要理解原始类型,必须了解原始类型的类型,有两种类型的原始类型:
整数数据类型的大小范围从至少8位到至少32位。 C99标准将此范围扩展到包括至少64位的整数大小。列出的这些类型的尺寸和范围是最小的;根据您的计算机平台,这些尺寸和范围可能会更大。
signed char:范围为-128到127的8位整数值。
unsigned char:8位整数值,取值范围为0~255。
char:根据您的系统,char数据类型被定义为与signed char或unsigned char数据类型具有相同的范围
short int:16位整数值,范围为-32,768到32,767
unsigned short int:16位整数值,范围为0到65,535
int:32位整数值,范围为-2,147,483,648到2,147,483,647
long int:32位整数范围至少为-2,147,483,648到2,147,483,647(根据您的系统,此数据类型可能是64位)
unsigned long int:32位整数范围至少为-2,147,483,648到2,147,483,647(根据您的系统,此数据类型可能是64位)
long long int:64位整数值,范围为-9,223,372,036,854,775,808到9,223,372,036,854,775,807。 (此类型不是C89的一部分,但它是C99和GNU C扩展的一部分。)
unsigned long long int:64位整数值,范围至少为0到18,446,744,073,709,551,615(此类型不是C89的一部分,但它们都是C99和GNU C扩展的一部分。)
float:float数据类型是三种浮点类型中最小的一种,如果它们的大小完全不同的话。其最小值存储在FLT_MIN中,不应大于1e-37。其最大值存储在FLT_MAX中,不应小于1e37。
double:double数据类型至少与float类型一样大。其最小值存储在DBL_MIN中,其最大值存储在DBL_MAX中。
long double:type至少与float类型一样大,并且可能更大。其最小值存储在DBL_MIN中,其最大值存储在DBL_MAX中。 问题:
如何用C编写跨平台代码?
跨平台代码有两件事要做:
答案 4 :(得分:0)
Jonathan Leffler在他的评论中基本涵盖了这一点,但从技术上讲,你无法知道跨系统/架构的原始类型有多大。如果系统遵循C标准,那么您知道每种变量类型都有最小字节数,但是您可能会获得超过该值的数据。
例如,如果我正在编写一个使用signed long
的程序,我可以可靠地知道我将获得至少4个字节,并且我可以存储最多2,147,483,647的数字;但是,有些系统可能会给我超过4个字节。
不幸的是,开发人员无法提前知道(未经测试)系统将返回多少字节,因此良好的代码应足够动态以解决此问题。
此规则的例外情况包括int8_t
,int16_t
,int32_t
,int64_t
及其未签名对应方(uintn_t
)。使用这些变量类型,您可以确保 n 位数 - 不多也不少。
答案 5 :(得分:0)
C有一个标准的sizeof()运算符。
答案 6 :(得分:0)
我问这个雇用的每个开发人员的问题。
我的问题是你在做这件事。
struct A {
int X; // 2 or 4 or 8 bytes
short Y; // 2 bytes
}
在32位计算机上,你得到一个48位的结构,32为int,16为短。
在64位计算机上,你得到的结构是80位长,64位为in,16位是简称。
(是的,我知道,这里可能会发生各种各样的深奥内容,但目标是解决问题,而不是混淆提问者。)
当您尝试使用此结构来读取另一个结构写入的内容时,会出现问题。
您需要一个能够正确编组的结构。
struct A {
long X; // 4 bytes
short Y; // 2 bytes
}
现在,在大多数情况下,双方都会正确地读取和写入数据,除非您使用了标记。
如果要通过线路发送内容,则必须使用char,short,long等。如果不是,那么可以使用int作为int,让编译器弄明白。