char *pp 和 (char*) p 之间的区别? [英] Difference between char *pp and (char*) p?

查看:85
本文介绍了char *pp 和 (char*) p 之间的区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的练习有问题,我必须解释 C 中指针的运行.

你能解释一下 char *pp(char*) p 和输出给我的区别是什么吗?

#include #include /***/int main(int argc, char** argv) {int n=260,*p=&n;printf("n=%d
", n);char *pp=(char*)p;*pp=0;printf("n=%d
",n);返回 (EXIT_SUCCESS);}

<块引用>

n=260
n=256

我为我所做的错误感到抱歉!希望大家帮帮我.

解决方案

您的问题是一个基本问题,但每个新的 C 程序员都会遇到这个问题,并且是理解 C 的基础.理解指针.虽然一旦您理解它们就很容易理解,但根据许多书籍或教程中的信息呈现方式,到达这一点可能会令人沮丧.

指针基础

指针只是一个普通的变量,它保存了别的东西的地址作为它的值.换句话说,一个指针指向可以找到其他东西的地址.你通常认为一个变量包含一个立即数,例如 int n = 260;,一个指针(例如 int *p = &n;)只会保存260 在内存中存储的地址.

如果您需要访问存储在 p 指向的内存地址处的值,您可以使用一元 dereference p'*' 运算符,(例如 int j = *p; 将初始化 j = 260).

如果要获取内存中的变量地址,请使用 & (address of) 运算符.如果您需要将变量作为指针传递,您只需提供变量的地址作为参数.

由于 p 指向存储 260 的地址,如果您更改该地址处的值(例如 *p = 41;) 41 现在存储在 260 之前所在的地址.由于 p 指向 n 的地址并且您已更改该地址处的值,因此 n 现在等于 41.然而 j 驻留在另一个内存位置,并且它的值是在您更改 n 地址处的值之前设置的,j 的值保持 <代码>260.

指针算术

指针算法的工作方式与所指向对象的类型无关,因为指针的 type 控制指针算法,例如带有char *指针,pointer+1指向下一个字节(next char),对于int *> 指针(普通的 4 字节整数),pointer+1 将指向 pointer 后 4 字节偏移处的下一个 int.(所以一个指针,只是一个指针......其中算术由 type 自动处理)

在你的情况下,你创建了一个不同类型的第二个指针char *pp = (char*)p;.指针 pp 现在也保存了 n 的地址,但它在访问时被解释为 char 类型而不是 int 类型>.

C 标准禁止通过不同类型的指针访问存储在地址中的值.C11 标准 - §6.5 表达式 (p6,7) (称为严格别名规则).规则也有例外.一个例外(最后一点)是可以通过 char 类型的指针访问任何值.

在您的案例中 n 的值会发生什么变化?

分配时:

*pp = 0;

您将单字节0(或二进制的00000000)存储到pp 保存的内存位置.这就是 endianess(小端,大端)发挥作用的地方.回想一下,对于 little-endian 计算机(几乎所有 x86 和 x86_64 IBM-PC 克隆类型框),这些值首先存储在内存中,最低有效字节.(big-endian 先存储最重要字节的值).因此,您的 n 的原始值(二进制中的 10000100)存储在内存中的 little-endian box 为

 n (little endian) : 00000100-00000001-00000000-00000000 (260)^|p(整数类型)

字符指针pp被赋值为p持有的地址,所以ppp,都持有相同的地址(区别在于一个是指向 int 的指针,另一个是指向 char 的指针:

 n (little endian) : 00000100-00000001-00000000-00000000 (260)^|p(整数类型)pp(字符类型)

当您取消引用 pp(例如 *pp)并分配零值(例如 *pp = 0;)时,您会覆盖内存中 n 的第一个字节为零.完成任务后,您现在拥有:

 n (little endian) : 00000000-00000001-00000000-00000000 (256)^|p(整数类型)pp(字符类型)

哪个是二进制值 100000000、(256 或十六进制 0x0100)以及您的代码为 n 的值输出什么.问问自己,如果您使用的计算机是大端的,那么结果值会是多少?

如果您有任何其他问题,请告诉我.

I am having a problem with my exercise in which I have to explain the running of pointers in C.

Can you explain what is the differences between char *pp and (char*) p and the outputs to me?

#include <stdio.h>
#include <stdlib.h>

/*
 * 
 */
int main(int argc, char** argv) {

    int n=260, *p=&n;
    printf("n=%d
", n);
    char *pp=(char*)p;
    *pp=0;
    printf("n=%d
",n);
    return (EXIT_SUCCESS);
}

n=260
n=256

I'm so sorry for the mistake I've done! Hope you guys can help me.

解决方案

Your question is a basic question, but one that every new C-programmer wrestles with and is fundamental to understanding C. Understanding pointers. While they are easy to understand once you understand them, getting to that point can be frustrating based on the way the information is presented in many books or tutorials.

Pointer Basics

A pointer is simply a normal variable that holds the address of something else as its value. In other words, a pointer points to the address where something else can be found. Where you normally think of a variable holding an immediate values, such as int n = 260;, a pointer (e.g. int *p = &n;) would simply hold the address where 260 is stored in memory.

If you need to access the value stored at the memory address pointed to by p, you dereference p using the unary '*' operator, (e.g. int j = *p; will initialize j = 260).

If you want to obtain a variables address in memory, you use the & (address of) operator. If you need to pass a variable as a pointer, you simply provide the address of the variable as a parameter.

Since p points to the address where 260 is stored, if you change that value at that address (e.g. *p = 41;) 41 is now stored at the address where 260 was before. Since p points to the address of n and you have changed the value at that address, n now equals 41. However j resides in another memory location and its value was set before you changed the value at the address for n, the value for j remains 260.

Pointer Arithmetic

Pointer arithmetic works the same way regardless of the type of object pointed to because the type of the pointer controls the pointer arithmetic, e.g. with a char * pointer, pointer+1 points to the next byte (next char), for an int * pointer (normal 4-byte integer), pointer+1 will point to the next int at an offset 4-bytes after pointer. (so a pointer, is just a pointer.... where arithmetic is automatically handled by the type)

In your case you create a second pointer of a different type char *pp = (char*)p;. The pointer pp now also holds the address of n but it is interpreted at type char on access instead of type int.

The C standard prohibits access of a value stored at an address though a pointer of a different type. C11 Standard - §6.5 Expressions (p6,7) (known as the strict-aliasing rule). There are exceptions to the rule. One exception (the last point) is that any value may be accessed through a pointer of char type.

What Happens to the Value of n In Your Case?

When you assign:

*pp = 0;

you storing the single-byte 0 (or 00000000 in binary) to the memory location held by pp. Here is where endianess (little-endian, big-endian) come into play. Recall, for little-endian computers (just about all x86 and x86_64 IBM-PC clone type boxes), the values are stored in memory with the Least-Significant Byte first. (big-endian stores values with the Most-Significan Byte first). So your original value of n (10000100in binary) is stored in memory on a little-endian box as

    n (little endian) : 00000100-00000001-00000000-00000000  (260)
                        ^
                        |
                        p   (type int)

The character pointer pp is assigned the address held by p, so both p and pp, hold the same address (the difference being one is a pointer to int the other a pointer to char:

    n (little endian) : 00000100-00000001-00000000-00000000  (260)
                        ^
                        |
                        p   (type int)
                        pp  (type char)

When you dereference pp (e.g. *pp) and assign the value zero (e.g. *pp = 0;), you overwrite the first byte of n in memory with zero. After the assignment, you now have:

    n (little endian) : 00000000-00000001-00000000-00000000  (256)
                        ^
                        |
                        p   (type int)
                        pp  (type char)

Which is the binary value 100000000, (256 or hex 0x0100) and what your code outputs for the value of n. Ask yourself this, if the computer you were using was big-endian, what would be resulting value have been?

Let me know if you have any further questions.

这篇关于char *pp 和 (char*) p 之间的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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