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.取值操作)的更多相关文章

  1. C语言二级指针(指向指针的指针)

    转载:http://c.biancheng.net/cpp/html/85.html 指针可以指向一份普通类型的数据,例如 int.double.char 等,也可以指向一份指针类型的数据,例如 in ...

  2. C语言指针系列 - 一级指针.一维数组,二级指针,二维数组,指针数组,数组指针,函数指针,指针函数

    1. 数组名 C语言中的数组名是一个特殊的存在, 从本质上来讲, 数组名是一个地址, 我们可以打印一个指针的值,和打印一个数组的值来观察出这个本质: int nArray[10] ={ 0 }; in ...

  3. 对线程等待函数pthread_join二级指针参数分析

    分析之前先搞明白,这个二级指针其实在函数内部是承接了上个线程的返回值. 看man手册,发现返回值是个普通指针.人家用二级指针来承接,可能准备干大事.这个可以自己搜索一下.原因嘛,二级指针是保存了这个地 ...

  4. C#中 this关键字 四种用法

    /// <summary> /// 主程序入口 /// </summary> /// <param name="args"></param ...

  5. [Vuex系列] - 细说state的几种用法

    state 存放的是一个对象,存放了全部的应用层级的状态,主要是存放我们日常使用的组件之间传递的变量. 我们今天重点讲解下state的几种用法,至于如何从头开始创建Vuex项目,请看我写的第一个文章. ...

  6. C++二级指针第二种内存模型(二维数组)

    C++二级指针第二种内存模型(二维数组) 二维数组 二维数组本质上是以数组作为数组元素的数组,即“数组的数组”. 定义 类型说明符 数组名[常量表达式][常量表达式] 例如: float a[3][4 ...

  7. C++二级指针第一种内存模型(指针数组)

    二级指针第一种内存模型(指针数组) 指针的输入特性:在主调函数里面分配内存,在被调用函数里面使用指针的输出特性:在被调用函数里面分配内存,主要是把运算结果甩出来 指针数组 在C语言和C++语言中,数组 ...

  8. C语言提高 (3) 第三天 二级指针的三种模型 栈上指针数组、栈上二维数组、堆上开辟空间

    1 作业讲解 指针间接操作的三个必要条件 两个变量 其中一个是指针 建立关联:用一个指针指向另一个地址 * 简述sizeof和strlen的区别 strlen求字符串长度,字符数组到’\0’就结束 s ...

  9. 深入理解C语言-二级指针三种内存模型

    二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别 第一种内存模型char *arr[] 若有如下定义 char *arr[] = {&quo ...

随机推荐

  1. Bug总结流程

    小明入职已有两年,期间测试能力已不知不觉成长许多,得到了Leader大熊的高度认可.回首这两年间,小明对"Bug总结流程"印象最为深刻,他对这个流程的认识在不断改变着:从最初的好奇 ...

  2. Elasticsearch 检索

    说到查询,那么索引也是一个绕不开的话题,可以说,没有索引就没有检索,先来看一个示意图 左边是索引过程,右边是检索过程.关键的步骤是分词过程,我用等号表示这两个过程一样,而且,必须一样,这个等号并不是模 ...

  3. Codility Tree Height

    public class HeightOfTreeSolution { static int height=-1; public int solution(Tree T) { // write you ...

  4. Python经典资料汇总

    [专题推荐]Python系列英文原版电子书 http://down.51cto.com/zt/104 python简明教程(CHM) http://down.51cto.com/data/49213 ...

  5. 【Delphi7】 解决“程序第一次可以正常编译,但再次编译的时候会报错,必须重新打开Delphi”的问题

    报错如下: Access violation at address 00495044 in module 'coreide70.bpl'. Read of address...Access viola ...

  6. Hibernate与MyBatis

    一. Hibernate与MyBatis Hibernate 是当前最流行的O/R mapping框架,它出身于sf.net,现在已经成为Jboss的一部分. Mybatis 是另外一种优秀的O/R ...

  7. java substring

    str=str.substring(int beginIndex,int endIndex);中最终得到的值: beginIndex =< str的值 < endIndex

  8. how to get soul shields in blade and soul

    These soul shields can either be obtained by E.Fleet Supply Chain or Blackram Supply Chain (4-man or ...

  9. 判断Sql Server2008中ntext不为空

    select * from 表名 where datalength(列名)=0 or datalength(列名) is null

  10. String的方法

    String str = "djsfkskfjs" . str.indexof():括号里面写你查找的字符,从strd的第一个开始找,找到第一个相同的字符,得到该字符的数组下标. ...