C 中指针转换的规则是什么?

2024-01-28

K&R 并没有忽略它,但他们使用了它。我尝试通过编写示例程序来了解它是如何工作的,但进展不太顺利:

#include <stdio.h> 
int bleh (int *); 

int main(){
    char c = '5'; 
    char *d = &c;

    bleh((int *)d); 
    return 0;  
}

int bleh(int *n){
    printf("%d bleh\n", *n); 
    return *n; 
}

它可以编译,但我的打印语句吐出垃圾变量(每次调用程序时它们都是不同的)。有任何想法吗?


当考虑指针时,它会有所帮助画图。指针是指向内存中地址的箭头,带有指示值类型的标签。地址表示要查找的位置,类型表示要获取的内容。投射指针会更改箭头上的标签,但不会更改箭头所指的位置。

d in main是一个指向c这是类型char. A char是一个字节的内存,所以当d取消引用后,您将获得该内存字节中的值。在下图中,每个单元代表一个字节。

-+----+----+----+----+----+----+-
 |    | c  |    |    |    |    | 
-+----+----+----+----+----+----+-
       ^~~~
       | char
       d

当你施放时d to int*,你是说d确实指向一个int价值。在当今的大多数系统上,int占用4个字节。

-+----+----+----+----+----+----+-
 |    | c  | ?₁ | ?₂ | ?₃ |    | 
-+----+----+----+----+----+----+-
       ^~~~~~~~~~~~~~~~~~~
       | int
       (int*)d

当您取消引用时(int*)d,您将获得由这四个字节的内存确定的值。您获得的值取决于这些标记的单元格中的内容?,以及如何int被表示在内存中。

A PC is 小尾数法 http://en.wikipedia.org/wiki/Endianness,这意味着 a 的值int是这样计算的(假设它跨越4个字节):* ((int*)d) == c + ?₁ * 2⁸ + ?₂ * 2¹⁶ + ?₃ * 2²⁴。所以你会看到,虽然该值是垃圾,但如果你以十六进制打印(printf("%x\n", *n)),最后两位数字始终是35(这就是角色的价值'5').

其他一些系统是大尾数并以另一个方向排列字节:* ((int*)d) == c * 2²⁴ + ?₁ * 2¹⁶ + ?₂ * 2⁸ + ?₃。在这些系统上,您会发现该值始终starts with 35以十六进制打印时。有些系统的大小为int这与 4 字节不同。很少有系统安排int以不同的方式,但你极不可能遇到它们。

根据您的编译器和操作系统,您可能会发现每次运行程序时该值都不同,或者它始终相同,但当您对源代码进行细微调整时会发生变化。

在某些系统上,int值必须存储在 4(或 2、或 8)的倍数的地址中。这被称为结盟 http://en.wikipedia.org/wiki/Data_structure_alignment要求。取决于地址是否c无论是否正确对齐,程序都可能崩溃。

与您的程序相反,当您有一个int值并获取指向它的指针。

int x = 42;
int *p = &x;
-+----+----+----+----+----+----+-
 |    |         x         |    | 
-+----+----+----+----+----+----+-
       ^~~~~~~~~~~~~~~~~~~
       | int
       p

指针p指向一个int价值。箭头上的标签正确描述了内存单元中的内容,因此取消引用它时不会出现任何意外。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 中指针转换的规则是什么? 的相关文章

随机推荐

  • pandas:如何绘制 pandas 中 IMDB 电影的电影数量与类型的饼图?

    我有以下数据集 import pandas as pd import numpy as np matplotlib inline df pd DataFrame movie A B C D genres Science Fiction Ro
  • 存在同名数据库,或无法打开指定文件,或位于 UNC 共享上

    当我在新电脑上运行我的项目时出现此错误 为了避免这种情况 我每次都必须复制粘贴新的连接字符串 有什么办法可以避免这种情况 我有3个不同的数据库 它非常烦人的O O SqlConnection con new SqlConnection Da
  • 复合键作为外键(sql)

    这是我关心的两个表 CREATE TABLE IF NOT EXISTS tutorial beggingTime time NOT NULL day varchar 8 NOT NULL tutorId int 3 NOT NULL ma
  • gulp:gulp任务回调函数在哪里定义的?

    gulp 中的任务可以这样定义 gulp task foobar function callback 我想了解回调函数是什么 它在哪里定义的 我可以在运行时传入其他函数作为参数吗 它有什么作用 这些文档 https github com g
  • 如何在 WPF 弹出窗口中放置关闭 [x]

    我已经在 c 和 wpf 中使用此代码成功创建了一个弹出窗口
  • 为什么我的 Twitter Bootstrap 表单字段使用流体容器会溢出?

    更新 问题演示在这里 http jsfiddle net fdB5Q embedded result http jsfiddle net fdB5Q embedded result 从大约 767 像素到 998 像素 表单字段比包含井更宽
  • 如何隐藏 TieredCompilation 警告?

    我正在使用 Linux Mint 和 OpenJDK java version显示这个 java version 1 7 0 79 OpenJDK Runtime Environment IcedTea 2 5 6 7u79 2 5 6 0
  • 为什么 bash 按字典顺序而不是数字来评估数字比较?

    有人可以解释一下 if 重击块 我使用下面的简单代码检查是否第一个值小于第二个值 first value 67 second value 2 if first value lt second value then echo Yes else
  • WiX .NET Bootstrapper - 功能选择

    我们正在尝试获取自定义 NET Bootstrapper 以便通过我们的 WiX 安装程序有选择地安装 MSI 包中的功能 注册了 PlanMsiFeature 事件后 我们认为我们将能够访问 MSI 中的功能并根据预设条件排除某些功能 然
  • d3.js 受形状约束的力定向布局

    我想知道是否有一种方法可以使用 d3 js 创建强制导向布局并通过任意形状限制它 这样 所有节点均等分布within形状和 边界和节点之间的距离等于节点之间的距离 我希望已经有这样的解决方案 否则 我的想法是从力导向布局开始 并在每次迭代中
  • 在 Sequelize 中按日期范围查询列字段

    我正在尝试使用 Sequelize 查询数据库以获取在特定日期范围内创建的项目 我用的是 between运营商 但我似乎没有得到任何东西 where createdAt between 2018 03 31T21 00 00 000Z 20
  • Gitcherry-pick 会发生合并冲突

    目前我有两个分支 master beta 001 beta 001 之前有时会从 master 处检出 为了使 beta 001 更新到 master 在 master 中推送的提交也将被挑选到 beta 001 一切都运行良好 直到 be
  • 从一个视图切换到下一个视图

    我有一个带有两个视图和视图控制器的应用程序 如何让用户从一个视图切换到下一个视图 例如在主屏幕或天气应用程序中 我知道界面生成器中有一个页面控件 但它只是用户所在页面的指示器 感谢并抱歉我的英语不好 查看 Apple 的 iPhone 示例
  • wxPython 中带有自动关闭计时器的 wxMessageBox

    平台 Windows OS X Python版本 活动状态Python 2 7 wxPython版本 2 9版 如果您通过子类化创建自己的自定义对话框wx Dialog http www wxpython org docs api wx D
  • 在 React js 中将数组作为 props 传递

    我是新来的反应 我一直在尝试 React 但我陷入了如何使用 props 传递数组的困境 case 1 var c program var Navigation React createClass getInitialState funct
  • AES 加密 Java 密钥长度无效

    我正在尝试创建 AES 加密方法 但由于某种原因我不断收到 java security InvalidKeyException Key length not 128 192 256 bits 这是代码 public static Secre
  • Zend_Auth:允许用户登录到多个表/身份

    我在用Zend Auth用于门户网站中的身份验证 一个普通的 mySQL 用户 表 带有login and password列被查询 并且用户登录 但是 我想要对另外两组用户进行身份验证 这三个用户组都有自己的其他表中的登录数据 他们的数据
  • 在 ASP.NET MVC 网站上集成 PayPal 的简单解决方案

    PayPal 为网站提供了许多与 PayPal 支付集成的解决方案 产品 我想知道将 PayPal 集成到 ASP NET MVC Web 应用程序中最简单或最简单的解决方案是什么 我应该使用哪种解决方案 如果以前做过此操作的人可以分享他或
  • 如何在 Rust 中执行高效的向量初始化?

    在 Rust 中填充结构体向量的好方法是什么 大小是动态的 但在初始化时已知 不首先将内存初始化为虚拟值 当内存已满时不会重新分配内存 在此示例中 向量的所有成员都是always已初始化 与 Rust 保持一致 保证没有未定义的行为 理想情
  • C 中指针转换的规则是什么?

    K R 并没有忽略它 但他们使用了它 我尝试通过编写示例程序来了解它是如何工作的 但进展不太顺利 include