c指针的理解 (一) * & (int *)

本文通过几个简单的示例,深入浅出地介绍了C语言中的指针概念。包括如何理解&p、*(&p)等表达式的含义,以及不同类型的指针如何影响数据的读取方式。

几行代码了解c指针:

敲击如下代码:

#include <stdio.h>
int main(){
	int p=5;
	printf("%d\n",p);
	printf("%x\n",*(&p));
	printf("%x\n",&p);
	//int *q= 0x62fe44;
	//printf("%d",*q);
	return 1;
}

然后在IDE中打开调试:

我这里选择的IDE是 dev c++


点击添加查看,将p,*p,&p,*(&p) ,q,*q,&q,*(&q)这几个变量添加进去(当然q的也可以之后加)

然后加断点,开始调试


如图所示:

p=5,即p的类型是int型,

但是*p在处理的时候,却把p的类型自动转换为了指针类型,即0x5。

再看下一个&p处理的时候,值是指针类型,也就是0x62fe4c。这个指针地址也就是int p=5存放的地址。

再看下一个变量*(&p)的值是5,等于p,其实也就是p。

由此可以看出

*p    中 p是指针,0x类型。    *p是这个指针所指向的内存地址所存放的值的类型   本题中因为0x5,这个地址不可读。所以,没有数据。

&p   整体是一个指针  0x类型    但p的类型是这个整体所代表的指针的地址所存放的值的类型,比如此例中的int类型

*(&p) 这个变量其实就是p。相当于绕了一圈又转回来了。

0x62fe4c ->  5
0x5 -> not read

也就是上述模型  p=5,*p=not read,&p=0x62fe4c,*(&p)=5。

然后把注释去掉,把地址换成p的地址,添加变量,重新调试。



接着分析:

我们将q这个变量声明为了(int *),也就是说 q的类型是个指针,0x类型。

那么  *q就是取这个内存地址的值,因为编译时有改动,我们将q的值重新设置一下。


这回刚好,指针q正好指向p的地址。,于是内存模型就变成了

0x62fe48 -> 0x62fe44
0x62fe44 ->  5
0x5 -> not read

&q就是个指针的指针,也就是说指针0x62fe48这个指针处存放的数据还是个指针(指向一个int 类型的指针),

因为q就是指针类型,所以*q就取到了存放在q这个指针地址处的值,也即是5这个int。

这个时候如果我把 int *q 改成 char *q,会出现什么情况呢?如下图:


*q 依然是没有问题,但在处理的时候,5就不在是int,而是被当成了字符来处理也就是上图中的‘\005’。

出现解析类型错误。

至此,int *,*,&应该就明白了。





&lt;think&gt;首先,用户的问题是基于提供的站内引用,总结C语言中指针*&amp;的含义及用法。用户说:&ldquo;我想获取C语言中指针*&amp;的含义及用法的相关知识&rdquo;,所以我需要从引用[1]、[2]、[3]中提取相关信息。 回顾引用内容: - 引用[1]:强调C语言中没有&ldquo;引用&rdquo;概念,这是C++的;建议使用GCC编译器;指针的基本介绍。 - 引用[2]:详细解释&amp;的作用是取地址符;*有两种用法:定义指针和解引用指针;给出示例代码。 - 引用[3]:解释&amp;和*的关系,&amp;取地址,*取内容;提供简单示例。 用户指令:[系统级指令]要求所有行内数学表达式用$...$,独立公式用$$...$$,但这里是指针主题,不涉及数学表达式,所以可能不需要LaTeX数学语法。但指令说&ldquo;包括变量、不等式、方程等&rdquo;,但这里是编程,不是数学,所以或许可以忽略数学格式。指令还说&ldquo;LaTeX语法正确&rdquo;,但在回答中,代码应该用代码块,如示例中的Python代码。 用户指令的示例显示,回答结构清晰,包括相关内容,末尾生成相关问题。系统指令要求&ldquo;生成相关问题&rdquo;,所以我需要在回答后添加相关问题。 回答结构: 1. 解释*&amp;的含义及用法。 2. 使用中文回答。 3. 引用站内引用时,在段落末尾添加引用标识,如[^1]。 4. 代码部分用代码块展示,如示例中的Python代码。 5. 末尾添加相关问题。 从引用中提取关键点: - &amp;:取地址运算符。用于获取变量的地址,存储在指针中。例如:int a; int *p = &amp;a;。 - *:有两种用法: - 在声明中:定义指针变量。例如:int *p; 意思是p是个指向int指针。 - 在表达式中:解引用运算符,用于获取指针指向的值。例如:int value = *p;。 引用[2]有typedef的例子,引用[3]有简单示例。 我需要组织回答: - 先介绍&amp;的含义和用法。 - 然后介绍*的含义和用法。 - 提供代码示例。 - 确保引用标识正确:引用[1]讨论C语言没有引用,引用[2]和[3]提供具体解释。 在回答中,引用段落末尾添加引用标识。例如,如果我引用[2]的内容,就在那段末尾加[^2]。 最后,生成相关问题,如指令示例所示。 相关问题应该基于主题:C语言指针*&amp;的用法。 可能的类似问题: 1. &amp;和*在C语言中的区别是什么? 2. 如何在C语言中正确使用指针? 3. 指针操作常见错误有哪些? 根据用户指令:&ldquo;生成相关问题&rdquo;,在末尾添加。 现在,构建回答: 标题或开头:C语言中指针 *&amp; 的含义及用法 内容: 1. &amp; 运算符:取地址运算符。用于获取变量的内存地址。例如,如果你有个变量 int a;,那么 &amp;a 返回 a 的地址,可以赋给指针变量。 引用[2]说:&quot;&amp;的作用比较好理解,取地址符,即通过&ldquo;&amp;变量名&rdquo;可以获取该变量的地址&quot;[^2]。 2. * 运算符:有两种主要用法。 - 在声明中:用于定义指针变量。例如,int *p; 声明 p 是个指向 int指针。 - 在表达式中:解引用运算符,用于获取指针指向的值。例如,如果 p 指向某个地址,*p 返回该地址存储的值。 引用[2]:&quot;*可以用在两个地方,&ldquo;数据类型关键字 *变量名&rdquo;的形式,可以定义个指向该数据类型的指针;二是&ldquo;*指针变量&rdquo;的形式,可以根据该指针变量取出其指向的数据&quot;[^2]。 引用[3]:&quot;*作用是通过变量的地址,获取存储的内容&quot;[^3]。 3. 代码示例:展示基本用法。 参考引用[2]和[3]的代码。 例如: ```c int i = 1; // 定义整型变量 i,值为1 int *x; // 定义整型指针 x x = &amp;i; // &amp;i 取 i 的地址,赋给 x printf(&quot;data = %d&quot;, *x); // *x 取 x 指向的值,输出1 ``` 注意:使用代码块。 4. 澄清:C语言中没有&ldquo;引用&rdquo;概念,这是C++的,避免混淆。引用[1]强调这点[^1]。 结尾:总结重要性或常见用途。 然后添加相关问题。 相关问题建议: 1. C语言中指针和数组的关系是什么? 2. 如何避免指针引起的常见错误,如野指针? 3. *&amp;在指针算术中的使用? 确保引用标识:在引用的段落末尾加[^n],例如:&quot;取地址运算符,即通过&ldquo;&amp;变量名&rdquo;可以获取该变量的地址&quot;[^2]。 现在,写出回答。 &lt;/think&gt;### C语言中指针 *&amp; 的含义及用法 在C语言中,指针种强大的特性,用于直接操作内存地址。运算符 `*`(星号)和 `&amp;`(取地址符)是处理指针的核心工具。以下基于站内引用内容,详细解释它们的含义和用法。 #### 1. **&amp; 运算符:取地址符** - **含义**:`&amp;` 用于获取变量的内存地址。它将变量名转换为指向该变量的指针。 - **用法**: - 语法:`&amp;变量名`,返回变量的地址。 - 结果可以赋给同类型的指针变量。例如,`int a; int *p = &amp;a;` 表示 `p` 存储 `a` 的地址。 - 在输入函数(如 `scanf`)中常用,例如 `scanf(&quot;%d&quot;, &amp;a);` 将用户输入写入 `a` 的地址。 - 关键点:`&amp;` 是单向操作,仅用于获取地址,不涉及数据内容。引用[2]指出:&quot;&amp;的作用比较好理解,取地址符,即通过&ldquo;&amp;变量名&rdquo;可以获取该变量的地址,也就是指针&quot;[^2]。 #### 2. **\* 运算符:指针声明和解引用** `*` 有两种主要用法,取决于上下文: - **在声明中:定义指针变量** - **含义**:在变量声明时,`*` 表示该变量是指针类型,指向特定数据类型的内存地址。 - **用法**: - 语法:`数据类型 *变量名;`,例如 `int *p;` 定义 `p` 为指向整型的指针。 - 可以使用 `typedef` 简化定义(如引用[2]所示): ```c typedef int *pInt; // 定义 pInt 为指向 int指针类型 int a = 1; pInt p1 = &amp;a; // p1 指向 a 的地址 int *p2 = &amp;a; // 直接定义指针 p2 ``` - 关键点:声明中的 `*` 强调变量的指针性质[^2]。 - **在表达式中:解引用(dereference)** - **含义**:`*` 用于访问指针指向的值,即 &quot;取内容&quot;。它与 `&amp;` 互为逆运算:如果 `&amp;` 取地址,`*` 则取地址中的值。 - **用法**: - 语法:`*指针变量`,返回指针指向的数据。 - 例如(引用[3]的示例): ```c int i = 1; // 定义整型变量 i,值为 1 int *x; // 定义整型指针 x x = &amp;i; // x 存储 i 的地址 printf(&quot;data = %d&quot;, *x); // 输出 *x 的值(结果为 1) ``` - 在输出函数中,如 `printf(&quot;%d&quot;, *p);` 输出指针 `p` 指向的值。 - 关键点:解引用时,`*` 操作必须确保指针已初始化并指向有效内存;否则可能导致未定义行为。引用[3]强调:&quot;*作用是通过变量的地址,获取存储的内容&quot;[^3]。 #### 3. **核心关系与注意事项** - **&amp; 和 * 的互逆性**:`&amp;` 和 `*` 是互补运算符。例如: - `int a = 10;` - `int *p = &amp;a;` // p 存储 a 的地址 - `*p` 等同于 `a`,因为 `*p` 访问 a 的值。 - 表达式 `*&amp;a` 等价于 `a`,操作顺序是先取地址再解引用。 - **避免混淆**:C语言中**没有引用(reference)概念**(这是C++的特性),学习时应专注于指针操作。引用[1]提醒:&quot;C语言中是没有引用这个概念的。如果大家在刚开始学习C语言时,尽量用GCC编译器,以免混淆些概念&quot;[^1]。 - **常见用法场景**: - 动态内存分配:如 `int *arr = malloc(10 * sizeof(int));` 后,使用 `*arr` 访问元素。 - 函数参数传递:通过指针修改实参(如 `void swap(int *a, int *b)`)。 - 数组操作:指针与数组紧密相关(如 `int arr[5]; int *p = arr;`)。 #### 4. **代码示例** 以下示例展示了 `&amp;` 和 `*` 的基本用法: ```c #include &lt;stdio.h&gt; int main() { int num = 42; // 定义整型变量 int *ptr; // 定义整型指针 ptr = &amp;num; // &amp; 取 num 的地址,赋给 ptr printf(&quot;地址: %p\n&quot;, (void*)ptr); // 输出指针值(地址) printf(&quot;值: %d\n&quot;, *ptr); // * 解引用,输出存储的值(42) *ptr = 100; // 通过指针修改值 printf(&quot;新值: %d\n&quot;, num); // 输出 100 return 0; } ``` 在此代码中: - `&amp;num` 获取 `num` 的地址。 - `*ptr` 访问并修改 `ptr` 指向的值。 输出结果应为地址和值的变化。 总结:`&amp;` 用于地址操作,`*` 用于指针声明和值访问。掌握它们对理解C语言内存管理至关重要,能提升代码效率和灵活性[^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值