什么是用C转换指针的规则? [英] What are the rules for casting pointers in C?

查看:98
本文介绍了什么是用C转换指针的规则?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

K&安培; R没过,但他们使用它。我想看到它如何会写一个示例程序的工作,但它并没有那么好走:

K&R doesn't go over it, but they use it. I tried seeing how it'd work by writing an example program, but it didn't go so well:

#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; 
}

它编译,但我的print语句吐出垃圾变量(他们每天我所说的节目时间是不同的)。有任何想法吗?

It compiles, but my print statement spits out garbage variables (they're different every time I call the program). Any ideas?

推荐答案

在想着指针,它有助于为画图。指针是指向存储器中的地址,与一个标签指示的值的类型的箭头。地址表示去哪里寻找和类型指的是采取​​什么样的。铸造指针更改标签上的箭头,但不是哪里箭头指向。

When thinking about pointers, it helps to draw diagrams. A pointer is an arrow that points to an address in memory, with a label indicating the type of the value. The address indicates where to look and the type indicates what to take. Casting the pointer changes the label on the arrow but not where the arrow points.

D 是一个指向 C 它的类型是字符的。 A 字符是内存的一个字节,因此当 D 被废弃时,你得到的内存,一个字节的值。在下面的图中,每个小区重presents一个字节。

d in main is a pointer to c which is of type char. A char is one byte of memory, so when d is dereferenced, you get the value in that one byte of memory. In the diagram below, each cell represents one byte.

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

当你施放 D 为int * ,你说 D 确实指向一个 INT 值。在大多数系统今天,一个 INT 占用4字节。

When you cast d to int*, you're saying that d really points to an int value. On most systems today, an int occupies 4 bytes.

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

在取消引用(INT *)D ,你得到的是这四个字节的内存确定的值。你得到的值取决于什么是在这些细胞标记,并就如何在 INT 重新presented在存储器

When you dereference (int*)d, you get a value that is determined from these four bytes of memory. The value you get depends on what is in these cells marked ?, and on how an int is represented in memory.

一个PC是小端,这意味着一个企业的价值 INT 计算这样(假设它跨越4字节):
*((INT *)D)== C +?₁*2⁸+?₂* 2 16 +?₃*2²⁴。所以你会看到,虽然该值是垃圾,如果你在十六进制打印(的printf(%X \\ n,* N)),最后两位数永远是 35 (这是字符'5'的值)。

A PC is little-endian, which means that the value of an int is calculated this way (assuming that it spans 4 bytes): * ((int*)d) == c + ?₁ * 2⁸ + ?₂ * 2¹⁶ + ?₃ * 2²⁴. So you'll see that while the value is garbage, if you print in in hexadecimal (printf("%x\n", *n)), the last two digits will always be 35 (that's the value of the character '5').

其他的一些系统是大端,并安排在其他方向的字节数: *((INT *)D)== C *2²⁴+₁* 2 16 +₂*2⁸+??? ₃。在这些系统中,你会发现,价值总是启动的有 35 十六进制打印时。有些系统的大小 INT 的这4个字节不同。人生难得几系统安排 INT 以不同的方式,但你极不可能遇到他们。

Some other systems are big-endian and arrange the bytes in the other direction: * ((int*)d) == c * 2²⁴ + ?₁ * 2¹⁶ + ?₂ * 2⁸ + ?₃. On these systems, you'd find that the value always starts with 35 when printed in hexadecimal. Some systems have a size of int that's different from 4 bytes. A rare few systems arrange int in different ways but you're extremely unlikely to encounter them.

根据你的编译器和操作系统,您可能会发现该值每次运行程序时是不同的,或者说,它总是相同的,但变化当你哪怕是轻微的调整,以源$ C ​​$ C。

Depending on your compiler and operating system, you may find that the value is different every time you run the program, or that it's always the same but changes when you make even minor tweaks to the source code.

在某些系统中,一个 INT 值必须存储在这4的倍数的地址(或2或8)。这就是所谓的对准的要求。根据的ç的地址是否恰好是正确对齐与否,该程序可能会崩溃。

On some systems, an int value must be stored in an address that's a multiple of 4 (or 2, or 8). This is called an alignment requirement. Depending on whether the address of c happens to be properly aligned or not, the program may crash.

在与您的程序相反,这里是当你有一个 INT 价值,并采取一个指向它时会发生什么。

In contrast with your program, here's what happens when you have an int value and take a pointer to it.

int x = 42;
int *p = &x;

-+----+----+----+----+----+----+-
 |    |         x         |    | 
-+----+----+----+----+----+----+-
       ^~~~~~~~~~~~~~~~~~~
       | int
       p

指针 P 指向一个 INT 值。箭头的标签正确描述什么是在存储单元,所以没有惊喜提领时。

The pointer p points to an int value. The label on the arrow correctly describes what's in the memory cell, so there are no surprises when dereferencing it.

这篇关于什么是用C转换指针的规则?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆