指针可以作为变量吗?

问题描述:

我对这个程序有一个困惑。指针可以作为变量吗?

#include <stdio.h> 

int main(void) 
{ 
     int value = 10; 
     char ch = 'A'; 

     int* ptrValue = &value; 
     char* ptrCh = &ch; 

     int* ptrValue1 = value; 
     char* ptrCh1 = ch; 

     printf("Value of ptrValue = %d and value of ptrValue1 = %d\n", *ptrValue, ptrValue1); 

     printf("Value of ptrCh = %c and value of ptrCh1 = %c\n", *ptrCh, *ptrCh1); 
} 

我得到两次警告,同时编制这个方案

的UniPro @ ubuguest:/ SoftDev/ADSD /模块 1 /单位1 /路/ C /系统$ CC charPointers.c -o charPointers
charPointers.c:在功能 '主':
charPointers.c:11: 警告:初始化使指针 从整数,未作铸造
charPointers.c:12:警告: 初始化使指针从 整数没有铸造

我知道他们的意思。

运行程序时出现以下错误。

UniPro中@ ubuguest:/ SoftDev/ADSD /模块 1 /单元1/RD/C /系统ptrValue = 10的$ ./charPointers
价值和ptrValue1 = 10
分段故障

的值

我知道我得到第二个printf方法的错误。

所以我的问题是如果我在指针中存储一个值,为什么我们不能去引用它呢?它的行为像一个变量?

谢谢。

+1

指针是存储地址的变量。 – Nyan 2010-09-01 08:40:34

+0

感谢您的回复 – Searock 2010-09-01 09:45:52

+1

如果您使用gcc和-Wall进行编译,它会告诉您第一个printf调用的一个参数对于所使用的格式说明符而言类型错误,这意味着您基本上将一个指针转换为int取消引用指针,这使得它看起来像你似乎认为第二个printf行失败了。 – nategoose 2010-09-01 19:47:21

随着分配

char* ptrCh1 = ch; 

您将设置地址的0x41,而不是价值。该程序稍后将尝试解除引用0x41(即,在地址0x41处获取数据),这是非法地址。因此,分段错误

这是因为*ptrCh1在最后一行,您试图对其进行解引用。删除*使其工作(但它不是很有意义,但)。

您可以对其进行解除引用,但获得有效内存块的机会非常渺茫。此处有效意味着您的流程拥有该位置的访问权限。

操作系统将阻止您修改不属于您的进程的内存。它通过分段错误“异常”来响应那种无效的内存访问。

指针指向一个内存位置(然后您可以在其中存储一些值)。这里

int* ptrValue1 = value; 
    char* ptrCh1 = ch; 

您指定一个指针变量的值(不是其地址),使指针很有可能指向一个无效的内存位置,因此段错误。请注意,在许多体系结构中,有效内存位置始于高偏移量,因此像10或('ASCII'值)'A'这样的小整数值永远不会指向有效的内存位置。这种低内存位置通常由操作系统本身保留/使用(因此它们不受修改 - 如果您尝试,会出现段错误)。如果您尝试直接访问另一个进程使用的内存,通常会发生同样的情况。

当然,它必须segfault。你正在存储指针中的任何值(并且正如你所说的编译器警告过你的那样),然后你将它解除引用,无论这指向何处。 你还期望什么?

一个指针存储的东西(或NULL)的地址。因此int *可以存储int的地址。您可以使用一元运算符&获得某个地址。

那么,将10存储在int指针中意味着什么?那么,10不是int的地址,所以你得到了“初始化使得整型指针没有抛出”警告,并且由于你在int *中存储了除int以外的其他地址,并尝试对其进行解引用,你会得到未定义的行为。

在你的情况中可能发生的事情是10个被解释为内存地址,并且当你取消引用一个指针时,它将出去获取该地址处的任何内容(在你的情况下为内存地址10)。这里可能什么也没有,那个内存区域没有被映射,并且你是segfault。