博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C/C++学习笔记——C提高:指针的指针(二级指针)
阅读量:4218 次
发布时间:2019-05-26

本文共 2656 字,大约阅读时间需要 8 分钟。

二级指针基本概念

这里让我们花点时间来看一个例子,揭开这个即将开始的序幕。考虑下面这些声明:

int a = 12;int *b = &a;

它们如下图进行内存分配:

在这里插入图片描述
假定我们又有了第3个变量,名叫c,并用下面这条语句对它进行初始化:

c = &b;

它在内存中的大概模样大致如下:

在这里插入图片描述
问题是:c的类型是什么?显然它是一个指针,但它所指向的是什么?变量b是一个“指向整型的指针”,所以任何指向b的类型必须是指向“指向整型的指针”的指针,更通俗地说,是一个指针的指针。

它合法吗?是的!指针变量和其他变量一样,占据内存中某个特定的位置,所以用&操作符取得它的地址是合法的。

那么这个变量的声明是怎样的声明的呢?

int **c = &b;

那么这个**c如何理解呢?操作符具有从右想做的结合性,所以这个表达式相当于(*c),我们从里向外逐层求职。*c访问c所指向的位置,我们知道这是变量b.第二个间接访问操作符访问这个位置所指向的地址,也就是变量a.指针的指针并不难懂,只需要留心所有的箭头,如果表达式中出现了间接访问操作符,你就要随箭头访问它所指向的位置。

二级指针做形参输出特性

二级指针做参数的输出特性是指由被调函数分配内存。

//被调函数,由参数n确定分配多少个元素内存void allocate_space(int **arr,int n){
//堆上分配n个int类型元素内存 int *temp = (int *)malloc(sizeof(int)* n); if (NULL == temp){
return; } //给内存初始化值 int *pTemp = temp; for (int i = 0; i < n;i ++){
//temp[i] = i + 100; *pTemp = i + 100; pTemp++; } //指针间接赋值 *arr = temp;}//打印数组void print_array(int *arr,int n){
for (int i = 0; i < n;i ++){
printf("%d ",arr[i]); } printf("\n");}//二级指针输出特性(由被调函数分配内存)void test(){
int *arr = NULL; int n = 10; //给arr指针间接赋值 allocate_space(&arr,n); //输出arr指向数组的内存 print_array(arr, n); //释放arr所指向内存空间的值 if (arr != NULL){
free(arr); arr = NULL; }}

二级指针做形参输入特性

二级指针做形参输入特性是指由主调函数分配内存。

//打印数组void print_array(int **arr,int n){
for (int i = 0; i < n;i ++){
printf("%d ",*(arr[i])); } printf("\n");}//二级指针输入特性(由主调函数分配内存)void test(){
int a1 = 10; int a2 = 20; int a3 = 30; int a4 = 40; int a5 = 50; int n = 5; int** arr = (int **)malloc(sizeof(int *) * n); arr[0] = &a1; arr[1] = &a2; arr[2] = &a3; arr[3] = &a4; arr[4] = &a5; print_array(arr,n); free(arr); arr = NULL;}

强化训练_画出内存模型图

void mian(){
//栈区指针数组 char *p1[] = {
"aaaaa", "bbbbb", "ccccc" }; //堆区指针数组 char **p3 = (char **)malloc(3 * sizeof(char *)); //char *array[3]; int i = 0; for (i = 0; i < 3; i++) {
p3[i] = (char *)malloc(10 * sizeof(char)); //char buf[10] sprintf(p3[i], "%d%d%d", i, i, i); }}

多级指针

将堆区数组指针案例改为三级指针案例:

//分配内存void allocate_memory(char*** p, int n){
if (n < 0){
return; } char** temp = (char**)malloc(sizeof(char*)* n); if (temp == NULL){
return; } //分别给每一个指针malloc分配内存 for (int i = 0; i < n; i++){
temp[i] = malloc(sizeof(char)* 30); sprintf(temp[i], "%2d_hello world!", i + 1); } *p = temp;}//打印数组void array_print(char** arr, int len){
for (int i = 0; i < len; i++){
printf("%s\n", arr[i]); } printf("----------------------\n");}//释放内存void free_memory(char*** buf, int len){
if (buf == NULL){
return; } char** temp = *buf; for (int i = 0; i < len; i++){
free(temp[i]); temp[i] = NULL; } free(temp);}void test(){
int n = 10; char** p = NULL; allocate_memory(&p, n); //打印数组 array_print(p, n); //释放内存 free_memory(&p, n);}

转载地址:http://bzxmi.baihongyu.com/

你可能感兴趣的文章
Sending the User to Another App
查看>>
kmsg_dump
查看>>
Getting a Result from an Activity
查看>>
Allowing Other Apps to Start Your Activity
查看>>
dev/mem
查看>>
pfn_valid 源码分析
查看>>
dev/kmem 和dev/mem的区别
查看>>
test-definitions/blob/master/auto-test/bigdata/bigdata.sh
查看>>
/test-definitions/blob/master/auto-test/blktrace/blktrace.sh
查看>>
test-definitions/blob/master/auto-test/blogbench/blogbench.sh
查看>>
test-definitions/blob/master/auto-test/boost/boost.sh
查看>>
Java多态性理解
查看>>
Intellij Idea 工具在java文件中怎么避免 import .*包,以及import包顺序的问题
查看>>
IDEA Properties中文unicode转码问题
查看>>
Oracle中Blob转换成Clob
查看>>
Linux如何查看so中函数名
查看>>
自动管理代码的android.mk
查看>>
cocos2dx 2.2.6编译记录(1)
查看>>
makefile学习网站
查看>>
C 编写lua模块(1)
查看>>