【C】二级指针探秘 & 星号的两种用法(1.与基本类型结合形成另一种类型,比如与int结合形成int* 2.取值操作)
2013-11-30 21:38
351 查看
1)问题:二级指针到底是什么?怎么用的?怎么存放的?
结果如下:
结果怎么看:
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!
点评:
i.在第14行不建议使用二级指针,因为二级指针需要一级指针作媒介来指向实际内存;若此处使用二级指针,此题几乎无解;
ii.二级指针通常是作返回值用,通常用法是:调用函数定义一级指针,接着用&p调用操作函数,而在操作函数中用二级指针进行操作;
#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+1), *(pAddr+2), *(pAddr+3)); pAddr = (unsigned int *)(TEST_ADDR+0x10); printf("[0x%p]:0x%p 0x%p 0x%p 0x%p\n",TEST_ADDR+0x10, *(pAddr), *(pAddr+1), *(pAddr+2), *(pAddr+3)); pAddr = (unsigned int *)(TEST_ADDR+0x20); printf("[0x%p]:0x%p 0x%p 0x%p 0x%p\n",TEST_ADDR+0x20, *(pAddr), *(pAddr+1), *(pAddr+2), *(pAddr+3)); }
结果如下:
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(0 != mallocStr(&pStr, STR_MAX)) { return -1; } memset(pStr, 0 , STR_MAX); test(pStr); freeStr(pStr); return 0; } int mallocStr(char** ppStr, unsigned int len) { char* pMem = NULL; pMem = (char*)malloc(len); if (NULL == pMem) { return -1; } *ppStr = pMem; return 0; } int test(char* pStr) { strncpy(pStr, STR, STR_MAX); printf("%s", pStr); return 0; } void freeStr(char* pStr) { free(pStr); pStr = NULL; }
点评:
i.在第14行不建议使用二级指针,因为二级指针需要一级指针作媒介来指向实际内存;若此处使用二级指针,此题几乎无解;
ii.二级指针通常是作返回值用,通常用法是:调用函数定义一级指针,接着用&p调用操作函数,而在操作函数中用二级指针进行操作;
相关文章推荐
- C语言学习7 :二级指针定义,强制转换,多级指针初步,6级指针构造,错误应用*p=&a,错误应用 二级p2,void型指针的兼容性,malloc函数基本用法,malloc分配空间和堆栈空间的区别,验证malloc函数内存的分配,验证malloc函数的越界,内存泄漏,指针不能返回局部变量地址,内存分配
- C++ 指针的两种操作,通过指针赋值 & 对指针赋值
- 2006-07-28 Java的常用包,"=="和"equals"的用法,基本数据类型与引用类型,对象的克隆
- C语言中基本类型char、short、int、long等类型的取值范围
- 定义一个不受计算机字长限制的整数类INT,要求INT与INT以及INT与C++基本数据类型int之间能进行+、-、×、÷和=运算,并且能通过cout输出INT类型的值。(持续添加)
- Hive 文件格式 & Hive操作(外部表、内部表、区、桶、视图、索引、join用法、内置操作符与函数、复合类型、用户自定义函数UDF、查询优化和权限控制)
- osg源码中的ref_ptr operator unspecified_bool_type() 指向类数据成员的指针&类转化为另一类型(如自定义的C类转化为int)
- 练习2-1 编写一个程序一确定分别由signed及unsigned限定的char,short,int及long类型变量的取值范围。采用打印标准头文件中的相应值以及直接计算两种方式实现。通过直接计算来确定浮点类型的取值范围是一项难度很大的任务。
- C语言中基本类型char、short、int、long等类型的取值范围
- java基本数据类型&&int与Integer区别
- 关于int取值范围及其他基本类型范围等(2015年10月21日)
- 二级指针的两种用法
- java中传递参数的两种方式(int(基本类型),int[](对象类型))
- C语言难点解析之void *类型指针转换成二级指针的操作
- (JAVA & C)数据类型取值范围——short int long float double等
- Java基本类型转换(Primitive Data Type Casting) int/byte & char
- c++ operator操作符的两种用法:重载和隐式类型转换,string转其他基本数据类型的简洁实现string_cast
- C语言基本数据类型:整型(int)用法详解
- 编写一个程序以确定分别由signed及unsigned限定的char、short、int及long类型变量的取值范围。采用打印标准头文件中的相应值以及直接计算两种方式实现
- golang基础-反射获取(基础数据、结构体)、操作(基本类型、结构体、指针)、反射获取Tag