为什么一般不用一个整数给一个指针变量赋初值?[c/c++]

本文详细解析了C语言中指针常量的概念、如何将整数转换为指针及安全注意事项,包括如何通过地址访问内存特定位置,以及指针与整数之间的转换过程。重点强调了指针赋值的限制条件,以及不推荐直接用整数赋值给指针的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

-----------摘自《c和指针》6.9指针常量----------------------------------------------------------------------------------------------------------------------------------

假定变量a存储于位置100,下面这条语句的作用是什么?

*100 =25;

它看上去像是把25赋值给a,因为a是位置100所存储的变量。但是,这是错误的,因为字面值100的类型是整型,而间接访问操作只能作用于指针类型表达式。

如果你确实想把25存储于位置100,你必须使用强制类型转换。

*(int*)100 = 25;

强制类型转换把值100从“整型”转换为“指向整型的指针”,这样对它进行间接访问就是合法的。如果a存储于位置100,那么这条语句就把值25存储于a。


但是你需要这种技巧的机会是绝无仅有的。

你通常无法预测编译器会把某个特定的变量放在内存中的什么位置,所以你无法预先知道它的地址。用&操作符得到变量的地址是很容易的,但表达式在程序执行时才会进行求值,此时已经来不及把它的结果作为字面值常量复制到源代码。


这个技巧唯一有用之处是你偶尔需要通过地址访问内存中某个特定的位置,它并不是用于访问某个变量,而是访问硬件本身。例如,操作系统需要与输入输出设备控制器通信,启动I/O操作并从前面的操作中获得结果。在有些机器上,与设备控制器的通信是通过在某个特定内存地址读取和写入值来实现的。但是,与其说这些操作访问的是内存,还不如说它们访问的是设备控制器接口。这样,这些位置必须通过它们的地址访问,此时这些地址是预先已知的。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


可以把指针的值当做一个整数取出来,也可以把一个整数值当作地址赋给一个指针。

int a=123,b;
int *ptr=&a;
char *str;
b=(int)ptr;  //把指针ptr的值当作一个整数取出来。
str=(char*)b;  //把这个整数的值当作一个地址赋给指针str。

注意:

例如:

unsigned int a;

a=N;  //N必须代表一个合法的地址

ptr=a;

上面强调了a的值必须代表一个合法的地址,否则的话,你在使用ptr的时候,就会出现非法操作错误。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ps:一般不用一个整数给一个指针变量赋初值,但是可以用。(绝无仅有)

当向指针变量赋值时,赋的值必须是地址常量或变量,不能是普通整数。


运行如下代码:

int *pi = (int*)0xbfc5aaac;

一般情况下,会报“段错误”,因为这个地址可能没有映射到物理内存;

因此使用指针要特别小心,很容易将指针指向错误的地址,访问这样的地址可能导致段错误,可能读到无意义的值




为什么一般不用一个整数给一个指针变量赋初值?



应该是为了安全和兼容的问题。您将整数赋值给指针变量,就是赋给这个变量一个绝对地址。

您能确保您使用这个绝对地址时:

(1)您是否保证没有访问系统禁止您访问的空间;

(2)假设(1)满足,您能保证在任何计算机上访问这个空间的效果都一样?

如果这两点都能保证,您确实可以直接赋值(其中包含了一个强者转换的过程)。

不过,可能大多数情况下谁都没这个把握哦,也许X86系统的系统中断函数地址还20多年来始终维持不变?



tips:
  1. 任何一个指针变量本身数据值的类型都是unsigned long int
  2. 指针赋值运算常见的有以下几种形式:
把一个变量的地址赋予一个指向相同数据类型的指针;
把一个指针的值赋予相同数据类型的另外一个指针;

把数组的地址赋予指向相同数据类型的指针。


部分内容摘自互联网:

http://learn.akae.cn/media/ch23s01.html

http://zhidao.baidu.com/question/210714496.html?fr=qrl&cid=869&index=1

让你不再害怕指针.pdf





<think>我们在C/C++中讨论指针操作。用户的问题是:如何将一个指针变量的地址值给另一个指针变量? 首先,我们需要明确:指针变量本身存储的是一个地址。如果我们想要获取指针变量自己的地址,我们可以使用取地址运算符`&`。 然后,如果我们想要将指针变量A的地址值给另一个指针变量B,那么B必须是一个指向指针指针(即二级指针)。 例如: 假设有一个指针变量 `int* p;`,它指向一个整数。现在,我们想要将指针变量p的地址存储到另一个指针变量q中。 那么,q应该被声明为指向指针指针,即 `int** q;`。 值操作就是:`q = &p;` 这样,q就存储了p的地址,也就是说,q指向了p。 步骤: 1. 声明一个指针变量(例如:`int* p;`) 2. 声明一个二级指针变量(例如:`int** q;`) 3. 将指针变量的地址值给二级指针变量:`q = &p;` 注意:这里我们并没有涉及指针所指向的内容,而是指针变量本身的地址。 下面是一个简单的示例代码: ```c #include <stdio.h> int main() { int a = 10; int* p = &a; // p是指向整型变量a的指针 int** q; // q是指向整型指针指针(二级指针) q = &p; // 将p的地址值给q // 验证 printf("a的地址: %p\n", &a); printf("p存储的地址(即a的地址): %p\n", p); printf("p自身的地址: %p\n", &p); printf("q存储的地址(即p的地址): %p\n", q); printf("通过q访问a的值: %d\n", **q); // 两次解引用得到a的值 return 0; } ``` 在这个例子中: - `p` 是一个指向 `int` 的指针存储变量 `a` 的地址。 - `q` 是一个指向 `int*`(即指向整型的指针)的指针存储指针变量 `p` 的地址。 因此,通过 `q` 我们可以间接访问 `p`,进而访问 `a`。 总结: 要将一个指针变量的地址给另一个指针变量,接收方必须是一个二级指针(或更高级的指针,视情况而定),然后使用取地址运算符`&`获取源指针变量的地址,再进行值。 注意:在C++中,语法相同。 相关问题: 1. 什么情况下需要用到二级指针? 2. 如何通过二级指针修改原始指针的指向? 3. 二级指针指针数组有什么关系? 4. 如何避免使用多级指针时出现野指针或内存泄漏?</think>### 如何将一个指针变量的地址值给另一个指针变量 在 C/C++ 中,要将指针变量 A 的地址值给另一个指针变量 B,需要遵循以下步骤: #### 1. **理解指针层级** - 指针变量本身存储在内存中,有独立地址 - 获取指针变量的地址需用取地址运算符 `&` - 接收指针地址的变量必须是**二级指针**(指向指针指针) #### 2. **操作步骤** ```c int main() { int data = 10; int* ptrA = &data; // 一级指针:指向普通变量 // 关键步骤:声明二级指针值 int** ptrB = &ptrA; // ptrB存储ptrA的地址 // 验证 printf("ptrA指向的值: %d\n", *ptrA); // 输出 10 printf("ptrB指向的地址: %p\n", *ptrB); // 输出 ptrA的地址 printf("通过ptrB访问data: %d\n", **ptrB); // 输出 10(双重解引用) return 0; } ``` #### 3. **关键语法说明** | 操作 | 语法 | 说明 | |------|------|------| | 获取指针地址 | `&ptrA` | 取指针变量本身的地址 | | 二级指针声明 | `int** ptrB` | 声明指向指针指针 | | 值操作 | `ptrB = &ptrA` | 将 ptrA 的地址存入 ptrB | #### 4. **内存示意图** ``` data [10] 地址: 0x1000 ptrA [0x1000] 地址: 0x2000 ←─┐ ptrB [0x2000] 地址: 0x3000 │ │ │ └────────────────────┘ ``` - `ptrB` 存储 `ptrA` 的地址(0x2000) - `*ptrB` 解引用得到 `ptrA` 的值(0x1000) - `**ptrB` 双重解引用得到 `data` 的值(10) #### 5. **注意事项** 1. **类型必须匹配**:一级指针 `int*` 的地址必须用 `int**` 接收 2. **避免空指针**:确保源指针已初始化 3. **指针大小**:32位系统指针占4字节,64位占8字节[^4] 4. **应用场景**:常用于函数内修改外部指针、动态二维数组等[^3] > 示例中通过二级指针 `ptrB` 成功获取了 `ptrA` 的地址,并通过双重解引用访问了原始数据[^1][^3]。 --- ### 相关问题 1. 二级指针在函数参数传递中有什么特殊作用? 2. 如何通过二级指针实现动态二维数组的内存分配? 3. 指针指针(`int**`)和指针数组(`int* arr[]`)有什么区别? 4. 在 C++ 中如何用引用替代二级指针实现类似功能?[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值