【C】二级指针探秘 & 星号的两种用法(1.与基本类型结合形成另一种类型,比如与int结合形成int* 2.取值操作)
1)问题:二级指针到底是什么?怎么用的?怎么存放的?
#include <stdio.h> #define TEST_ADDR 0x12FF40 void main()
{
int a = 0x5555AAAA;
int* pA = &a;
int** ppA = NULL;
unsigned int * pAddr = (unsigned int *)TEST_ADDR;
ppA = &pA;
printf("0x%p\n",a);
printf("0x%p, 0x%p\n",&a, pA);
printf("0x%p, 0x%p\n",&pA, ppA);
printf("0x%p\n",&ppA); printf("[0x%p]:0x%p 0x%p 0x%p 0x%p\n",TEST_ADDR, *(pAddr), *(pAddr+), *(pAddr+), *(pAddr+));
pAddr = (unsigned int *)(TEST_ADDR+0x10);
printf("[0x%p]:0x%p 0x%p 0x%p 0x%p\n",TEST_ADDR+0x10, *(pAddr), *(pAddr+), *(pAddr+), *(pAddr+));
pAddr = (unsigned int *)(TEST_ADDR+0x20);
printf("[0x%p]:0x%p 0x%p 0x%p 0x%p\n",TEST_ADDR+0x20, *(pAddr), *(pAddr+), *(pAddr+), *(pAddr+));
}
结果如下:
0x5555AAAA
0x0012FF60, 0x0012FF60
0x0012FF54, 0x0012FF54
0x0012FF48
[0x0012FF40]:0xCCCCCCCC 0xCCCCCCCC 0x0012FF54 0xCCCCCCCC
[0x0012FF50]:0xCCCCCCCC 0x0012FF60 0xCCCCCCCC 0xCCCCCCCC
[0x0012FF60]:0x5555AAAA 0xCCCCCCCC 0x0012FFB8 0x00411B36
请按任意键继续. . .
结果怎么看:
0x0012FF48存放的值是0x0012FF54 -> ppA = &pA;
0x0012FF54存放的值是0x0012FF60 -> pA = &a;
0x0012FF60存放的值是0x5555AAAA -> int a = 0x5555AAAA;
分析:
a.二级指针的用法:正确用法ppA = &pA; (若用*ppA = pA; 编译无错,运行出错)
记忆:ppA = &pA这是在搞定指向;而*ppA只 用于取值/赋值
(这种用法也是错的int** ppA = &&a;)
(这种用法也是错的int** ppA = pA;)
b.另一种正确用法:
int** ppA = &pA;
这种用法类比于pA = &a,只不过此时pA指向的是一个int,而ppA指向的是一个指针;此时的**可以理解为与int结合跟精密,是一种类型的一部分,因为ppA的类型为int**
c.二级指针是指向指针的指针;(这句只含一层意思:二级指针也是指针,没什么特殊的,要用得先指向,再取值/赋值)
总结:
形成习惯:定义二级指针的时候先赋值NULL;如果要用,先指向,再进行取值赋值操作;
2)实例——高级些的hello word!
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #define STR "Hello!\r\n"
#define STR_MAX 10 extern int mallocStr(char** pStr, unsigned int len);
extern int test(char* pStr);
extern void freeStr(char* pStr); int main()
{
char* pStr = NULL; if( != mallocStr(&pStr, STR_MAX))
{
return -;
}
memset(pStr, , STR_MAX);
test(pStr);
freeStr(pStr);
return ;
} int mallocStr(char** ppStr, unsigned int len)
{
char* pMem = NULL;
pMem = (char*)malloc(len);
if (NULL == pMem)
{
return -;
} *ppStr = pMem;
return ;
} int test(char* pStr)
{
strncpy(pStr, STR, STR_MAX); printf("%s", pStr);
return ;
} void freeStr(char* pStr)
{
free(pStr);
pStr = NULL;
}
点评:
i.在第14行不建议使用二级指针,因为二级指针需要一级指针作媒介来指向实际内存;若此处使用二级指针,此题几乎无解;
ii.二级指针通常是作返回值用,通常用法是:调用函数定义一级指针,接着用&p调用操作函数,而在操作函数中用二级指针进行操作;
【C】二级指针探秘 & 星号的两种用法(1.与基本类型结合形成另一种类型,比如与int结合形成int* 2.取值操作)的更多相关文章
- C语言二级指针(指向指针的指针)
转载:http://c.biancheng.net/cpp/html/85.html 指针可以指向一份普通类型的数据,例如 int.double.char 等,也可以指向一份指针类型的数据,例如 in ...
- C语言指针系列 - 一级指针.一维数组,二级指针,二维数组,指针数组,数组指针,函数指针,指针函数
1. 数组名 C语言中的数组名是一个特殊的存在, 从本质上来讲, 数组名是一个地址, 我们可以打印一个指针的值,和打印一个数组的值来观察出这个本质: int nArray[10] ={ 0 }; in ...
- 对线程等待函数pthread_join二级指针参数分析
分析之前先搞明白,这个二级指针其实在函数内部是承接了上个线程的返回值. 看man手册,发现返回值是个普通指针.人家用二级指针来承接,可能准备干大事.这个可以自己搜索一下.原因嘛,二级指针是保存了这个地 ...
- C#中 this关键字 四种用法
/// <summary> /// 主程序入口 /// </summary> /// <param name="args"></param ...
- [Vuex系列] - 细说state的几种用法
state 存放的是一个对象,存放了全部的应用层级的状态,主要是存放我们日常使用的组件之间传递的变量. 我们今天重点讲解下state的几种用法,至于如何从头开始创建Vuex项目,请看我写的第一个文章. ...
- C++二级指针第二种内存模型(二维数组)
C++二级指针第二种内存模型(二维数组) 二维数组 二维数组本质上是以数组作为数组元素的数组,即“数组的数组”. 定义 类型说明符 数组名[常量表达式][常量表达式] 例如: float a[3][4 ...
- C++二级指针第一种内存模型(指针数组)
二级指针第一种内存模型(指针数组) 指针的输入特性:在主调函数里面分配内存,在被调用函数里面使用指针的输出特性:在被调用函数里面分配内存,主要是把运算结果甩出来 指针数组 在C语言和C++语言中,数组 ...
- C语言提高 (3) 第三天 二级指针的三种模型 栈上指针数组、栈上二维数组、堆上开辟空间
1 作业讲解 指针间接操作的三个必要条件 两个变量 其中一个是指针 建立关联:用一个指针指向另一个地址 * 简述sizeof和strlen的区别 strlen求字符串长度,字符数组到’\0’就结束 s ...
- 深入理解C语言-二级指针三种内存模型
二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别 第一种内存模型char *arr[] 若有如下定义 char *arr[] = {&quo ...
随机推荐
- Hibernate与MyBatis
一. Hibernate与MyBatis Hibernate 是当前最流行的O/R mapping框架,它出身于sf.net,现在已经成为Jboss的一部分. Mybatis 是另外一种优秀的O/R ...
- Jenkins 命令
Jenkins 服务集群环境的启动命令 #必须在root下启动 sh /home/jenkins/tomcat/bin/startup.sh dubbo服务注册中心 zookeeper启动命令 /we ...
- BZOJ AC800纪念
貌似没什么好纪念的...QAQQQ 好不容易水到了800还是记录一下好了....不过感觉水这么多题没有意义啊[思考熊] 然后就没有然后了恩 不过我到底是为什么才努力的呢...前途一阵迷茫,根本没有什么 ...
- maven私服搭建(centOS6.5)
maven的好处和私服的应用本文不赘述,私服搭建如下: MAVEN 私服搭建(centOS 6.5 环境) 1. 准备环境,搭建centOS6.5系统环境,略 2. 准备对应的软件包如下: A. ...
- 14073102(CCDIKRecoil)
[目标] CCDIKRecoil [思路] 1 CCDIK和Recoil的结合 2 Recoil的回弹机制,逐渐回到原来位置 3 添加一个Recoil基类 [步骤] 1 将\Src\GameFrame ...
- CentOS 6中MATLAB print函数“所见非所得”bug的解决方案
0 系统配置+软件版本 主机:Dell optiplex 390 MT (i5) 系统+软件:CentOS 6.5 x64, Matlab R2012, R2013 系统+软件:CentOS 6.7 ...
- P53 T3
为方便旅客,某航空公司拟开发一个机票预定系统.旅行社把预定机票的旅客信息(姓名.性别.工作单位.身份证号码.旅行时间.旅行目的地等)输入进入该系统,系统为旅客安排航班,印出取票通知和账单,旅客在飞机起 ...
- .net 附加W3wp进程
步骤:1.鼠标右键点击application项目中的web,找到属性 2.修改web服务器地址(如果使用localhost报错,则http://电脑IP/): 3.在本地iis中找到你部署的网站,点击 ...
- JAVA动手动脑
1.运行 TestInherits.java 示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是 ...
- Visro 应用的前端模板工具介绍 -JsRender
1.什么是JsRender: JsRender是一款JavaScript模版引擎,是具有简单直观,功能强大,可扩展的,早期版本是基于JQUERY 写的,后来作者重构了,就不再依赖JQUERY了. 它的 ...