char*pp和(char*)p之间的区别?

char*pp和(char*)p之间的区别?,c,C,我在练习中遇到了一个问题,我必须解释C语言中指针的运行 你能解释一下char*pp和(char*)p之间的区别以及给我的输出吗 #include <stdio.h> #include <stdlib.h> /* * */ int main(int argc, char** argv) { int n=260, *p=&n; printf("n=%d\n", n); char *pp=(char*)p; *pp=0;

我在练习中遇到了一个问题,我必须解释C语言中指针的运行

你能解释一下
char*pp
(char*)p
之间的区别以及给我的输出吗

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

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

    int n=260, *p=&n;
    printf("n=%d\n", n);
    char *pp=(char*)p;
    *pp=0;
    printf("n=%d\n",n);
    return (EXIT_SUCCESS);
}
#包括
#包括
/*
* 
*/
int main(int argc,字符**argv){
int n=260,*p=&n;
printf(“n=%d\n”,n);
char*pp=(char*)p;
*pp=0;
printf(“n=%d\n”,n);
返回(退出成功);
}
n=260
n=256


我为我所犯的错误感到非常抱歉!希望你们能帮助我。

你们的问题是一个基本的问题,但每个新的C程序员都要解决这个问题,这是理解C的基础。理解指针。虽然一旦你理解了它们,它们就很容易理解,但从许多书籍或教程中呈现信息的方式来看,达到这一点可能会令人沮丧

指针基础知识

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

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

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

由于
p
指向存储
260
的地址,如果在该地址更改该值(例如
*p=41;
),则
41
现在存储在
260
之前的地址。由于
p
指向
n
的地址,并且您已经更改了该地址的值,
n
现在等于
41
。但是
j
驻留在另一个内存位置,其值是在更改
n
地址处的值之前设置的,
j
的值仍然是
260

指针算法

无论指向的对象类型如何,指针算法的工作方式都是相同的,因为指针的
类型
控制指针算法,例如,对于
int*
指针,
Pointer+1
指向下一个字节(下一个
char
),对于
int*
指针(正常的4字节整数),
指针+1
将指向
指针后偏移4字节处的下一个
int
。(因此,指针只是一个指针……其中算术运算由
类型自动处理)

在本例中,您创建了另一个不同类型的指针
char*pp=(char*)p。指针
pp
现在也保存
n
的地址,但它在访问时被解释为type
char
,而不是type
int

C标准禁止通过不同类型的指针访问存储在地址中的值。(称为严格别名规则)。这条规则也有例外。一个例外(最后一点)是,任何值都可以通过
char
类型的指针访问

在您的情况下,n的值会发生什么变化?

分配时:

*pp = 0;
将单字节
0
(或二进制
00000000
)存储到
pp
持有的内存位置。这里是endian(小endian,大endian)发挥作用的地方。回想一下,对于little-endian计算机(几乎所有x86和x86_64 IBM-PC克隆类型框),值存储在内存中,以最低有效字节开头。(big-endian首先存储具有最高有效字节的值)。因此,您的原始值
n
10000100
二进制)存储在内存中的一个小端点框中,如下所示:

    n (little endian) : 00000100-00000001-00000000-00000000  (260)
                        ^
                        |
                        p   (type int)
字符指针
pp
被分配了
p
持有的地址,因此
p
pp
都持有相同的地址(区别在于一个是指向
int
的指针,另一个是指向
char
的指针:

    n (little endian) : 00000100-00000001-00000000-00000000  (260)
                        ^
                        |
                        p   (type int)
                        pp  (type char)
当您取消引用
pp
(例如
*pp
)并将值赋值为零(例如
*pp=0;
)时,您将用零覆盖内存中
n
的第一个字节。赋值后,您现在有:

    n (little endian) : 00000000-00000001-00000000-00000000  (256)
                        ^
                        |
                        p   (type int)
                        pp  (type char)
哪一个是二进制值
100000000
,(
256
或十六进制
0x0100
)以及您的代码为
n
的值输出的值。问问自己,如果您使用的计算机是big-endian,结果会是什么


如果您还有任何问题,请告诉我。

char*pp
声明变量
pp
,作为指向
char
-
pp
的指针将存储
char
对象的地址

(char*)p
是一个强制转换表达式-它的意思是“将
p
的值视为
char*

p
被声明为
int*
-它存储
int
对象的地址(在本例中,是
n
的地址)。问题是
char*
int*
类型不兼容-不能直接将一个类型分配给另一个类型1。必须使用强制转换将值转换为正确的类型


  • 指向不同类型的指针本身就是不同的类型,不必具有相同的大小或表示形式。唯一的例外是
    void*
    类型-它是专门为“通用”指针类型引入的,在指定下注时不需要显式强制转换