【问题标题】:What is the data type of pointer variables?指针变量的数据类型是什么?
【发布时间】:2015-01-14 14:08:57
【问题描述】:

我参考了以下链接,

Link1 Link 2

在上面的链接 1 中,答案中提到了“Pointers are of pointer type”。

我只需要知道指针是不是数据类型。

没有人用一个词回答过这个问题。是不是数据类型?

这是我提到的第二个链接

指针只是一个保存地址的变量,因此人们可能会认为指针是一种数据类型,但它没有被定义为一种数据类型(根据“C 编程语言”。Kernighan & Ritchie)。

【问题讨论】:

  • “我只需要知道指针是不是一种数据类型。” - 是的,指针是一种数据类型。
  • 这取决于您所说的“数据类型”。它肯定是一个 type,实际上是一个 object type,而不是 functionreference type,但两者都不是语言正式定义了术语“数据类型”。 (通俗地说,它是一种可以保存一些数据(地址)的类型,所以是的,它是一种数据类型。)
  • 我不确定“数据类型”这个短语与“类型”有什么不同
  • @BillLynch:函数类型是“数据类型”吗?我会说不。
  • “指针是指针类型”意味着它们不必存储为整数(有符号或无符号);它们甚至不必是标量。在某些架构上,它们可能表示为一对值(页面 #:offset)。

标签: c++ c pointers


【解决方案1】:

是的,指针是一种数据类型。其中最纯粹的形式(这里主要讲C)是void *void * 可用于传递内存地址(这就是指针),但不能取消引用。取消引用指针是为了获取指针指向的内存位置中包含的数据,这意味着您知道从内存中读取的数据类型。类型决定了将读取多少内存,因为void“nothing”void * 可以设置为指向可以包含任何类型的任何内存块,因此您可以将void * 强制转换为任何其他指针类型(例如int *),然后取消引用它。

我们拥有的每种类型都用于存储特定的数据(值),我们使用char 存储单个字符,int 存储整数,double 存储双精度小数和很快。除了指针之外,这些类型都不用于在内存中存储位置。因此,就像其他类型一样,指针用于存储特定的数据。所有指针之母是void *

遗憾的是,这个void * 相当受限制:你不能取消引用它,你不能将它用于指针算术(无论如何都不是根据标准)。因此,C 为您提供了一系列派生指针类型,让生活更轻松:char *int *double * 等等。
它们实际上是简写形式:(char *) void * my_ptr;

更多尝试尽可能清楚地说明我的观点:

指针有自己的大小,与它们所指向的类型无关:

char a_character = 'a';  //type: a char
char *a_char_ptr = &a_character; //memory address, in this case, the one holding a_charachter

通过查看这两个变量的大小可能最能看出区别:

printf("%zu <> %zu\n", sizeof a_character, sizeof a_char_ptr);

上面的代码会给你类似 "1 8""1 4" 的东西,这取决于你使用的系统。数字表示大小,以字节为单位。

指针也有自己的printf 格式说明符:%p

printf("%c is the value stored at %p\n", *a_char_ptr, (void *) a_char_ptr);

要打印实际内存地址(指针的实际值),您需要将指针转换为通用void * 类型。 void 指针是一种通用指针。它是指针,它对它指向的数据不做任何假设。这就是malloccallocrealloc 返回的通用指针,可以设置为指向任何其他类型。那么char * 是什么?它是一种通用指针类型,设置为指向 1 字节大小的内存块 (sizeof(char))。从某种意义上说,类型化指针是派生类型,但可以这样想:char *(char *) void *my_ptr; 的缩写

但实际上,什么是类型?它的要点是,类型是确定如何解释内存中数据的方法。 char 类型的变量代表一个字符。 int 类型的变量代表一个整数。同样适用于指针:char *x 不是char 类型,而是char * 类型(指向字符的指针)。这意味着char *x 本身就是内存中的一个位置,我们可以使用它来读取一个或多个char 值。

我可以咆哮一会儿,但是 TL;TR:

是的,指针是一种数据类型(void * 的最纯粹形式)。纯形式是完全不可用的(因为你不能取消引用它)。不必每次决定使用指针时都强制转换,C 提供了派生指针类型的便利(如char *int * 等)。但实际上,它们是指针,因此本身就是一种数据类型。

【讨论】:

  • Nit - 您不能取消引用 void *,因为结果表达式的类型为 void,它没有任何值;这就是为什么你必须在取消引用之前将指针转换为不同的指针类型。
  • @JohnBode:我没提过吗? Nips...我以为我一直在抱怨无法取消引用 void 指针。进行了编辑
  • @EliasVanOotegem 回答得非常漂亮!它不仅可以解决被问到的疑问,还可以解决更多类似char *存储整数地址时发生的情况。
  • >"上面的代码会给你类似 "1 8" 或 "1 4" 的东西,这取决于你使用的系统。 - 您可以在 32 位模式下在 x64 位“系统”上编译。那么它将不依赖于“系统”。您也可以很好地将整数值分配给指针类型void* ptr = (void* )32,当然只要您不取消引用它就可以了。必须考虑范围。
【解决方案2】:

你问了两个不同的问题。

你的标题问“指针变量的数据类型是什么?”。答案很简单:指针变量属于某种指针类型。例如,给定:

int *ptr;

ptr为指针对象,其类型为int*,为指针类型。

您的问题主体询问“指针是否是数据类型”。根据“数据类型”这一短语的任何合理定义,指针类型就是数据类型。

C 标准从未定义短语“数据类型”,但它确实使用它(非正式地)在几个地方。碰巧在标准中“数据类型”这个短语的使用都没有指代指针类型,但这并不能告诉我们任何事情。

标准规定所有类型要么是函数类型,要么是对象类型。对象类型进一步分为若干类别:整数类型、数组类型、结构类型、联合类型、指针类型等。指针类型可以是指向对象类型的指针,也可以是指向函数类型的指针。 (它可以是指向 incomplete 对象类型的指针;在 2011 标准中,不完整类型被归类为对象类型。)

您问题中的另一个歧义是您使用了“指针”一词。 “指针”一词本身通常指的是指针类型的对象,但它也可以指代指针类型的(例如,标准说@ 987654325@ 返回一个指针)。最好将“指针”用作形容词而不是用作名词,这样您就可以:

  • 指针类型;
  • 指针对象(指针类型的对象);
  • 指针表达式(产生指针类型结果的表达式);或
  • 指针值(指针类型的值,由指针表达式产生)。

指针类型是对象类型。指针对象是一个对象;标准将对象定义为“执行环境中的数据存储区域,其内容可以表示值”。所以指针对象是一个数据存储区域。

在您的Link 2 之后,互联网上的某个随机人写道:“指针只是一个保存地址的变量,因此有人可能会说指针是一种数据类型,但它没有被定义为数据类型(根据“C 编程语言”。Kernighan & Ritchie)”。我不知道 K&R 是否定义了术语“数据类型”;由于此人没有提供具体的引文,因此如果不搜索这本书就很难判断。但定义语言的是标准,而不是 K&R。

我很好奇:为什么您会认为指针类型不会被视为数据类型?

【讨论】:

  • K&R (second edition) Section A8.8: Type names "specifier-qualifier-list abstract-declarator(opt)" 后面是一系列例子,包括@987654326 @、int *int*[3],将它们列为不同的类型。数据类型在本书的任何地方定义,AFAIK,但类型和类型名称是
  • @iOSdeveloper:什么是“原始数据类型”? C 标准没有定义或使用该短语。
【解决方案3】:

例如,在 C 标准中没有术语数据类型的正式定义。有对象类型和函数类型。同时,指针是由对象和函数类型构造的派生类型。

因此,一般情况下,指针是数据类型,即它们是从对象和函数类型构造的数据类型。

C 标准中也有术语对象的定义

3.15
1 object
region of data storage in the execution environment, the contents of which can represent
values

因此标准中存在一些矛盾。一方面,指针是对象,因为它们占用内存并且内存代表它们的值。所以我们可以说指针是对象类型。另一方面,指针被认为是对象类型的派生类型。

在我看来,如果在标准中明确写出指针是派生对象类型或派生函数类型会更好。

无论如何你都可以勇敢地说指针是数据类型!:)

【讨论】:

  • 我明白你所说的标准中明显的矛盾,但数据类型 "pointer" 将是 void *,其中包含数据(内存地址),派生类型是您实际可以使用的指针:char *int *,...所以指针是一种数据类型,但您主要使用派生类型
  • 指针类型可能派生自函数类型,但所有指针类型都是对象类型。
  • @Keith Thompson 我同意,但最好在标准中写得更清楚。
  • 它说“类型被划分为 object types ...和 ​​function types ....”指针类型显然不是函数类型,因此它们是对象类型。为什么需要比这更清楚?
  • @Keith Thompson 没有写到指针是对象类型。上面写着指针是对象和函数类型的派生类型。
【解决方案4】:

是的,指针是一种数据类型,并且是一个指针变量存储指针数据类型

【讨论】:

  • “指针变量存储指针数据类型”——听起来很循环。
  • @KeithThompson;现在它是线性的。
  • 当然,但现在您只是断言指针(您的意思是指针 type?)是一种数据类型。并且变量不存储类型;它存储一种类型的数据。
【解决方案5】:

指针是一种数据类型。所以我们可以创建指针变量来保存内存位置的地址。

【讨论】:

  • -1,只有void *%p打印有效,指向的数据类型是类型的一部分。 double *int * 的数据类型不同。
  • @unwind 但基本上 %p 是用于打印指针地址,对吗?让指针指向任意内存位置
  • @Gopi:参考我的回答,要打印指针的实际值,您必须将其转换为void *。这是因为printf & 是可变参数函数,因此不可能进行隐式转换。
  • @Gopi:短语“指针地址”是多余的。 %p 用于打印指针的 value。 (地址是一个指针值。)
【解决方案6】:

指针类型是数据类型;它们存储指针值。

没有一种单一的指针类型;指向int 的指针与指向char 的指针的类型不同,后者与指向double 的指针不同,后者与指向int 的10 元素数组的指针不同,这与指向 int 等 11 元素数组的指针是不同的类型。

不同的指针类型可能有不同的大小和表示;唯一保证具有相同大小和表示的指针类型是void *char *

【讨论】:

  • 是真的吗?不同的指针变量有不同的大小。我研究了所有指针的大小都相同
  • @VinothKumar 指向成员函数的指针不一定与其他指针类型的大小相同。
  • @VinothKumar:C 语言定义允许不同的指针类型有不同的大小和表示。参见online C2011 draft standard, 6.2.5/28。在商品 x86 系统上,它们可能都相同,但在某些古怪的架构上它们可能不一样。
  • @CaptainObvlious 它显示的整数指针和函数指针的大小与我的系统中的相同。这个架构是否依赖
  • @VinothKumar:它绝对依赖于架构。哈佛架构将代码和数据存储在物理上不同的内存段中,这些内存段可能具有不同的总线大小,因此数据指针可能比函数指针更宽或更窄。字寻址架构可以为char * 使用比其他类型更广泛的类型,以允许对字进行索引。
【解决方案7】:

您的问题可能是指“指针的数据类型”,而不是指向数据的数据类型,这是人们首先会理解的。

基于此假设,那么请查看类型uintptr_tvoid*

引用Drew Dorman 的回答:“uintptr_t 是一种无符号整数类型,能够存储指针。这通常意味着它与指针大小相同”

当然,它的大小取决于平台:32 位或 64 位。所以不要跨不同大小的平台传输这个变量。

请注意,要分配它,您必须从“特定”指针类型转换为“通用”类型:

int var = 1;
int* addrOfVar = &var; // pointer to variable
uintptr_t pVar = (uintptr_t)&var;
uintptr_t pVar2 = reinterpret_cast<uintptr_t>(&var); // alternative cast

【讨论】:

  • 这个解释如何回答我的问题?
猜你喜欢
  • 1970-01-01
  • 2021-04-08
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多