C码是多少?
我对C中的C码是多少?,c,int,size-t,C,Int,Size T,我对C中的size\u t感到困惑。我知道它是由sizeof操作符返回的。但到底是什么呢?它是数据类型吗 假设我有一个for循环: for(i = 0; i < some_size; i++) for(i=0;i
size\u t
感到困惑。我知道它是由sizeof
操作符返回的。但到底是什么呢?它是数据类型吗
假设我有一个for
循环:
for(i = 0; i < some_size; i++)
for(i=0;i
我应该使用inti代码>或<代码>大小\u t i代码>?的手册页上写着:
大小\u t应为无符号整数类型
:
根据1999年ISO C标准
(C99),size\u t
是一个无符号整数
至少16位的类型(参见章节
7.17和7.18.3)
size\t
是一种无符号数据类型
由多个C/C++标准定义,
e、 g.C99 ISO/IEC 9899标准,
在stddef.h
中定义的。它可以
通过加入
stdlib.h
作为此文件的子文件
包括stddef.h
此类型用于表示
物体的大小。图书馆职能
接受或返回他们期望的大小
属于类型或具有返回类型
尺寸为的尺寸
。此外,最
常用的基于编译器的
运算符sizeof的计算结果应为
与之兼容的常量值
大小\u t
作为暗示,size\u t
是一种保证保存任何数组索引的类型。size\u t
是一种无符号类型。因此,它不能表示任何负值(,根据我的理解,size\u t
是一个无符号
整数,其位大小足以容纳本机架构的指针
因此:
size\u t
和int
不可互换。例如,在64位Linux上size\u t
的大小为64位(即sizeof(void*)
),但int
的大小为32位
还要注意,size\u t
是无符号的。如果您需要有符号的版本,那么在某些平台上会有ssize\u t
,这与您的示例更相关
作为一般规则,我建议在大多数一般情况下使用int
,只有在有特殊需要时才使用size\u t
/ssize\u t
(例如使用mmap()
).通常,如果从0开始向上,请始终使用无符号类型,以避免溢出将您带入负值情况。这一点至关重要,因为如果数组边界恰好小于循环的最大值,但循环的最大值恰好大于类型的最大值,则您将返回负数,您可能会遇到(SIGSEGV)。因此,一般来说,对于从0开始并向上的循环,不要使用int。请使用无符号。size\u t
是一种可以保存任何数组索引的类型
根据实施情况,它可以是以下任何一种:
无符号字符
unsigned short
unsigned int
unsigned long
unsigned long-long
以下是如何在我的机器的stddef.h
中定义size\t
:
typedef unsigned long size_t;
如果你是经验型的
echo | gcc -E -xc -include 'stddef.h' - | grep size_t
Ubuntu 14.04 64位GCC 4.8的输出:
typedef long unsigned int size_t;
请注意,stddef.h
由GCC提供,而不是GCC 4.2中src/GCC/ginclude/stddef.h
下的glibc
有趣的C99外观
malloc
将size\u t
作为参数,因此它确定可以分配的最大大小
由于它也是由sizeof
返回的,因此我认为它限制了任何数组的最大大小
另见:
由于还没有人提到它,
size\u t
的主要语言意义在于sizeof
运算符返回该类型的值。同样地,ptrdiff\u t
的主要意义在于从一个指针减去另一个指针将产生该类型的值。接受它的库函数因此,因为它将允许这些函数在可能存在此类对象的系统上处理大小超过UINT_MAX的对象,而不会迫使调用方浪费传递大于“unsigned int”的值的代码在系统上,较大的类型可以满足所有可能的对象。大小\u t是无符号整数数据类型。在使用GNU C库的系统上,这将是无符号整数或无符号长整数。大小\u t通常用于数组索引和循环计数。大小\u t或任何无符号类型都可能被视为循环作为循环变量的变量通常大于或等于0
当我们使用大小\u t对象时,我们必须确保在使用它的所有上下文中,包括算术,我们只需要非负值。例如,以下程序肯定会给出意外的结果:
// C program to demonstrate that size_t or
// any unsigned int type should be used
// carefully when used in a loop
#include<stdio.h>
int main()
{
const size_t N = 10;
int a[N];
// This is fine
for (size_t n = 0; n < N; ++n)
a[n] = n;
// But reverse cycles are tricky for unsigned
// types as can lead to infinite loop
for (size_t n = N-1; n >= 0; --n)
printf("%d ", a[n]);
}
Output
Infinite loop and then segmentation fault
//C程序来演示该大小\u t或
//应使用任何无符号int类型
//在循环中使用时要小心
#包括
int main()
{
常数大小N=10;
int a[N];
//这很好
对于(大小n=0;n=0;--n)
printf(“%d”,a[n]);
}
输出
无限循环和分段故障
要了解为什么需要存在大小\u t
以及我们是如何来到这里的:
从实用角度讲,size\u t
和ptrdiff\u t
在64位实现上保证为64位宽,在32位实现上保证为32位宽,依此类推。它们不能强制任何现有类型在每个编译器上都意味着,在不破坏遗留代码的情况下
size\u t
或ptrdiff\u t
不一定与intptr\u t
或uintpr\u t
相同。它们在某些体系结构上有所不同,当size\u t
和ptrdiff\u t
在20世纪80年代末被添加到标准中时,它们仍然在使用,并且在添加了许多代码后变得过时
echo | gcc -E -xc -include 'stddef.h' - | grep size_t
typedef long unsigned int size_t;
// C program to demonstrate that size_t or
// any unsigned int type should be used
// carefully when used in a loop
#include<stdio.h>
int main()
{
const size_t N = 10;
int a[N];
// This is fine
for (size_t n = 0; n < N; ++n)
a[n] = n;
// But reverse cycles are tricky for unsigned
// types as can lead to infinite loop
for (size_t n = N-1; n >= 0; --n)
printf("%d ", a[n]);
}
Output
Infinite loop and then segmentation fault
const size_t number;
#include <stdio.h>
int main()
{
const size_t value = 200;
size_t i;
int arr[value];
for (i = 0 ; i < value ; ++i)
{
arr[i] = i;
}
size_t size = sizeof(arr);
printf("size = %zu\n", size);
}
#include <stdio.h>
int main()
{
size_t value = 200;
size_t i;
int arr[value];
for (i = 0; i < value; ++i)
{
arr[i] = i;
}
size_t size = sizeof(arr);
printf("size = %zu\n", size);
}