我有一个给定的字符串
char *names = "ABC";
现在作为理解指针及其转换的一部分,我想将字符串转换为ascii代码,但使用指针。
到目前为止我所做的一切。
char *name = "ABC";
int *array;
array = (int *) name;
printf("the array value is %d ",*array);
但遗憾的是,我无法理解为什么会将4407873
打印为值。
注意:我也知道可以使用atoi功能完成,但如果我能理解如何做到这一点,那将会非常有用。
答案 0 :(得分:1)
在您的代码中,使用array
作为指向整数的指针
printf("the array value is %d ",*array);
其中为array
分配了类似
array = (int *) name;
和name
被定义为
char *name = "ABC";
违反了strict aliasing rule。 char
和int
不兼容,因此该程序无效。
引自C11
,章节§6.3.2.3,
指向对象类型的指针可以转换为指向不同对象类型的指针。如果 结果指针未正确对齐引用类型,行为是 未定义。否则,当再次转换回来时,结果应该等于 原始指针。 [...]
因此,如果使用非别名类型来访问内存,则会调用undefined behavior。
答案 1 :(得分:1)
理解指针的一部分是理解不与它们有关的内容。你应该不使用指针做的主要事情之一是尝试访问一种类型的对象,其中指针指向不兼容类型的东西。
例如,使用指针指向char
从char
数组中读取元素是正常的,并且使用指针指向 - const char
也可以,但是指针 - 到 - int
是一个很大的禁忌。
执行此操作的结果是未定义的行为,这意味着它可能导致您的程序完成任何。 (不要被看起来像是一致的行为所迷惑 - 未定义的行为也允许这样做太,然后在你确信自己的某个时候停止工作&#39 ;可以使用未定义的行为,并且不相信它是导致错误的原因)
答案 2 :(得分:0)
在C语言中,大多数类型如int
通常会存储为两个或多个连续字节的序列。写入int*
会将写入的值转换为字节序列并连续存储它们。读取int*
会读取一个字节序列,然后将它们转换为整数。
然而,并非每个连续整数序列都可以被读取为另一种类型。实现可能会施加三种限制:
在某些实现中,某些字节序列可能不代表某些类型的值。例如,可能需要浮点值使其第一个字节在0-126或128-254范围内;尝试加载第一个字节为127或255的值可能会以任意方式陷阱,具体取决于实现方式。
在许多实现中,内存在物理上分为2个,4个或8个字节的组(有时称为"单词"),并且可能需要某些类型和大小的对象才能启动相应大小的组的边界(例如,如果" int"是4个字节,系统可能只能加载" int"适合单个4字节字的数量。尝试加载一个跨越单词边界的int *可能会因任意后果而失败,具体取决于实现。
虽然某些应用领域可能会因使用不同类型读取和写入存储而受益匪浅,但其他领域的许多应用程序都无法获得任何好处。如果编译器可以假设一种类型的对象不会受到另一种类型的指针的影响,则编译器可以生成更有效的代码,并且标准的作者不会尝试要求该实现适合于任何特定字段。因此,标准不要求实现做出关于将存储写入一种类型并将其作为另一种类型读取的效果的任何承诺,即使在满足对齐要求且位模式有意义的情况下也是如此。有用的。
旨在用于这种翻译有用的领域的实现应该指明他们承诺以有意义的方式处理这些行为的情况,并且不这样做的实现可能不适合使用在需要此类能力的目的中,但仅适用于此类能力不提供任何好处的应用程序的实现不需要提供超出标准中给出的最低限度的任何此类能力。
请注意,第三点引发了很多激烈的争论,因为编译器编写者未能认识到当标准的作者没有尝试要求所有实现都适合任何特定目的或应用领域时,因此没有尝试强制要求支持使编译器适合任何特定目的或领域所需的所有行为。