c语言中的二级指针做函数参数说明

目录
  • 二级指针做函数参数
  • 二级指针作为形参简单实例分析
    • 实例
    • 一级指针二级指针做函数形参
    • 下面看看实例

二级指针做函数参数

1.用指针做函数参数申请动态内存的问题

//如果函数参数是指针,不能用一级指针做函数参数实现申请动态内存
 
void getMemory(char *p, int num)
{
    p = (char *)malloc(sizeof(char)*num);
}
void main()
{
    char *str = NULL;
    getMemory(str, 20);
    strcpy(str, "code");
    cout << str;
    system("pause");
}//出错
然而
//用二级指针为指针申请内存,用二级指针做函数参数可以申请成功
void getMemory1(char **p, int num)
{
    *p = (char *)malloc(sizeof(char)*num);
}
void main()
{
    char *str = NULL;
    getMemory(&str);
    strcpy(str, "code");
    cout << str;
    system("pause");
}

2.二级指针做函数参数简介修改变量的值

#include<iostream>
 
using namespace std;
struct Teacher
{
    char name[20];
    int age;
};
int getTeacher(Teacher **p)
{
    Teacher *tmp = NULL;
    if (p == NULL)
    {
        return -1;
    }
    if (tmp == NULL)
    {
        return -2;
    }
    tmp->age = 23;
    *p = tmp;//p是实参地址,*p间接修改实参的值
    //用二级指针修改一级指针的值,用一级指针修改零级指针的值
}
void FreeTeacher(Teacher *p)
{
    if (p == NULL)
    {
        return;
    }
    free(p);
}
int main()
{
    Teacher *pt = NULL;
    getTeacher(&pt);
    cout << pt->age << endl;
    FreeTeacher(pt);
    system("pause");
    return 0;
}

二级指针作为形参简单实例分析

指针是什么?指针是程序数据在内存中的地址,而指针变量是用来保存这些地址的变量。

举例

int c=2,d=3;
int *pc=&c;

pc是指针变量的存储内容,也就是c的地址

*pc就是对指针的解引用,取出这个c这个地址里面的值

实例

#include <stdio.h>
int c=2,d=3;
int *pc=&c;        //一级指针指向c
int **ppc = &pc;    //二级指针指向一级指针pc    (指向指针的指针)

int main()
{
	//一级指针*p指向c
	printf("一级指针*p指向c\n\n");
	printf("c的地址=%p      c的地址\n",&c);
	printf("pc的值 =%p       pc中指向的就是C的地址\n",pc);
	printf("*pc的值=%d              对c的地址进行取值*pc==2;\n",*pc);

	putchar('\n');
	printf("-------------------------------------------------------------\n");

	//二级指针(指针的指针)**ppc指向*pc
	printf("二级指针(指针的指针)**ppc指向*pc\n\n");
	printf("pc的地址   =%p   一级指针pc的地址\n",&pc);
	printf("ppc的值    =%p   二级指针ppc指向的地址其实就是一级指针pc的地址\n",ppc);
	printf("*ppc的值   =%p   对ppc进行一次解引用,*ppc==pc,*ppc也就是c的地址\n",*ppc);
	printf("*(*ppc)的值=%d          对ppc进行两次解引用,*(*ppc)==*pc==c==2\n",*(*ppc));

	putchar('\n');
	return 0;
}

运行结果为:

一级指针二级指针做函数形参

许多初学者在使用一级指针的时候基本没什么问题

例如

int a=10;
int fun(int *p)
{
          return ( *p+=10);
}

在调用是时需要定义一个变量int b=fun(&a);

当二级指针做形参的时候,调用该函数时实参应该以什么格式填写?

int a=1;
int b=2;

int fun1(int **p1,int *p2)//二级指针做形参   后面举例用
{
	return (**p1+*p2);
} 

int fun2(int x,int y)
{
	return (x+y);
}

函数fun1的第一个形参是**p1 二级指针 , 第二个是*p2 ,  最终的目的是将两个变量相加

我们对比fun2, 这个函数的形参都是普通变量,调用时直接int sum=fun2(a,b),最终的目的是将两个变量相加.

通过对比,我们发现**p1代表一个变量,*p2也代表一个变量。

我们来分析下*p这个东西。

int a=2;
int b=3;
int *p=&a;

我们可以知道 p存放的值就是变量a的地址,*(地址)就相当于把这个地址的值取出来。

假如a的地址等于0x123456, p也==0x123456,   b=(*p)==*(a的地址)==a的值;通过这步b就等于2;

我们回到fun1函数,**p怎么才能转换 为一个变量呢,看下图

一级指针只有一层解引用——*(地址)则得到一个变量,

二级指针内层解引用得到一个地址add2,对add2解引用得到一个变量

*(add1)=add2,*(add2)=变量 ——> *(*(add1))=变量

所以fun1的第一个实参应该填一个地址ADD1  对ADD1解引用得到ADD2,对ADD2解引用得到一个变量

下面看看实例

#include <stdio.h>
int c=2,d=3;
int *pc=&c;
int **ppc = &pc;
int fun1(int **p1,int *p2)//二级指针做形参   后面举例用
{
	return (**p1+*p2);
}
int main()
{

	int sum=fun1(&pc,&d);//在二级指针形参填写一个指针的地址,这个指针指向一个变量

	printf("sum=%d\n",sum);

	putchar('\n');
	printf("------------------------------------------\n");

	printf("      c的地址=%p\n",&c);
	printf(" pc指向的地址=%p\n",pc);
	printf("          *pc=%d\n",*pc);

	putchar('\n');
	printf("------------------------------------------\n");

	printf("         c的地址=%p\n",&c);
	printf("    pc指向的地址=%p\n",pc);
	printf("        pc的地址=%p\n",&pc);

	putchar('\n');
	printf("------------------------------------------\n");

	printf("   ppc指向的地址=%p\n",ppc);
	printf("    *(ppc)的地址=%p\n",*(ppc));
	printf("   **(ppc)的值=%d\n",**(ppc));
	putchar('\n');
	return 0;
}

解析一下程序二级指针的流程

三级指针或者多级指针以此类推,凡是涉及到指针解引用的*(x),x都是一个地址。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • C语言 一级指针与二级指针详细介绍

    指针的概念 指针就是地址, 利用这个地址可以找到指定的数据 指针就是地址, 那么在使用的时候, 常常会简单的说 指针变量为指针 指针变量就是存储地址的变量 int *p1;// 申请了一个变量, 即在内存中开辟了一块内存, 存储数据 // 开辟了 8 个字节, 在 Mac 下 指针都占 8 个字节 使用指针, 实际上应该说成使用指针变量      1> 算术运算 +1 移动几个字节? 看类型: int *,  long *,  char *     2> 获得地址表示的数据 指针里面存储的是地

  • C语言中二维数组作为函数参数来传递的三种方法

    c语言中经常需要通过函数传递二维数组,有三种方法可以实现,如下: 方法一, 形参给出第二维的长度. 例如: #include <stdio.h> void func(int n, char str[ ][5] ) { int i; for(i = 0; i < n; i++) printf("/nstr[%d] = %s/n", i, str[i]); } void main() { char* p[3]; char str[][5] = {"abc&quo

  • C语言指针基础详解

    目录 1.1:概述 1.1.1:内存 1.1.2:内存 1.1.3:指针和指针变量 1.2:指针基础知识 1.2.1:指针变量的定义和使用 1.2.2:通过指针间接修改变量的值 1.2.3:指针的大小 1.2.4:空指针与野指针 1.2.4:万能指针 1.3:指针与数组 1.3.1:数组名 1.3.2:指针操作数组 1.3.3:指针的加减运算 1.4:指针基础小结 1.5:总结 1.1:概述 1.1.1:内存 内存含义: 储存器:用来存储程序和数据,辅助CPU进行运算处理的重要组成部分. 内存:

  • C语言 二级指针详解及示例代码

    指针可以指向一份普通类型的数据,例如 int.double.char 等,也可以指向一份指针类型的数据,例如 int *.double *.char * 等. 如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针. 假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示: 将这种关系转换为C语言代码: int a =100; int *p1 = &a; int **p2 = &p1; 指针变量也是一种变量

  • c语言中的二级指针做函数参数说明

    目录 二级指针做函数参数 二级指针作为形参简单实例分析 实例 一级指针二级指针做函数形参 下面看看实例 二级指针做函数参数 1.用指针做函数参数申请动态内存的问题 //如果函数参数是指针,不能用一级指针做函数参数实现申请动态内存   void getMemory(char *p, int num) {     p = (char *)malloc(sizeof(char)*num); } void main() {     char *str = NULL;     getMemory(str,

  • 一文带你了解C语言中的动态内存管理函数

    目录 1.什么是动态内存管理 2.为什么要有动态内存管理 3.如何进行动态内存管理 3.1 malloc 3.2 free 3.3 calloc 3.4 realloc 总结 1.什么是动态内存管理 平时我们写代码,一种非常常见的写法是: int a = 0; // 创建一个变量 int arr[10] = {0}; // 创建一个数组 当你创建变量a的时候,其实是向内存中申请了4个字节的空间来存放一个整数.而当你创建数组arr的时候,是向内存中申请了40个字节的空间来存放10个整数.当你这么写

  • C语言中枚举与指针的实例详解

     C语言中枚举与指针的实例详解 总结一下, 定义枚举,用typedef enum关键字, 比如 typedef enum{Red,Green,Blue} Color3; 枚举到数值的转换,如果没有指定代表数值就是从0开始算, 比如 Color3 c=Red; printf("%d",c);会显示0, 除非指定 如typedef enum{Red=3,Green=5,Blue=10} Color3; 关于类型指针的定义, 定义的时候在变量名左边加*代表此变量只是一个空指针而已, 若需要赋

  • C语言中求字符串长度的函数的几种实现方法

    1.最常用的方法是创建一个计数器,判断是否遇到'\0',不是'\0'指针就往后加一. int my_strlen(const char *str) { assert(str != NULL); int count = 0; while (*str != '\0') { count++; str++; } return count; } 2.不创建计数器,从前向后遍历一遍,没有遇到'\0'就让指针向后加一,找到最后一个字符,记下来地址,然后用最后一个字符的地址减去起始地址,就得到了字符串的长度.

  • C语言中的文件读写fseek 函数

    目录 一.fseek 函数简介 二.fseek 函数实战 一.fseek 函数简介 fseek 函数用来移动文件流的读写位置:就好比播放器,可以直接拖拽到精彩的时间点一样,fseek 函数声明如下 #include <stdio.h> #include <stdlib.h> /* *描述:文件读写偏移 * *参数: * [in] stream:文件指针句柄 * [in] offset:偏移量,正数表示正向偏移(向后偏移),负数表示负向偏移(向前偏移) * [in] fromwher

  • Go语言中的流程控制结构和函数详解

    这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和无条件跳转. if if也许是各种编程语言中最常见的了,它的语法概括起来就是:如果满足条件就做某事,否则做另一件事. Go里面if条件判断语句中不需要括号,如下代码所示: 复制代码 代码如下: if x > 10 {     fmt.Println("x is greater than 10&

  • 详解C语言中的常量指针和指针常量

    概述 对于新手来说,指针在c语言里总是一个非常难以理解的概念.在这篇文章中,我们将解释常量指针,指针常量,const pointer to const(ps:楼主以为这可以翻译成指向常量的常量指针)的区别 常量指针 让我们先来理解什么是常量指针.常量指针是指指针指向的地址是常量.换句话说,一旦常量指针指向了一个变量,你不能让该常量指针指向其他变量了 常量指针的声明方法如下: <type of pointer> * const <name of pointer> 常量指针声明示例:

  • C语言中利用封装好的函数实现英文字母的大小写转换

    在C语言中,利用tolower和toupper两个函数实现英文字母的大小写之间的转换 范例1:将s字符串内的小写字母转换成大写字母 #include <ctype.h> int main() { char s[] = "aBcDeFgH"; int i; printf("before toupper() : %s\n", s); for(i = 0; i < sizeof(s); i++) s[i] = toupper(s[i]); printf(

  • 关于c语言中输出字符指针的相关问题

    目录 c语言输出字符指针问题 例如定义一个 char * p = "hello";的字符指针 c语言指针求字符串长度 c语言输出字符指针问题 例如定义一个 char * p = "hello";的字符指针 首先搞清楚在c语言中没有字符串的类型,所以对字符串操作,有两种形式:可以用字符指针(为什么不叫字符串指针,我个人觉得,字符指针针对的是单个字符的操作,即指针操作,所以就叫它字符指针吧...) 或者字符串数组(这里不在讨论字符串相关问题,前面博客有讨论过)这里的指针

  • C语言中用于产生随机数的函数使用方法总结

    在UNIX操作系统和window的操作系统上,我们知道有一个函数rand,它就是用来产生随机数的函数API接口,那么它的原理如何实现? 如果约定a1=f(seed),an+1=f(an),那么可以得到一个序列a1,a2,a3..an,那么要制作一个伪随机函数rand,只需要让它每调用一次就返回序列的下一个元素就行.其实就是相当于第1次调用rand返回a1,第2次返回a2,-,第n次返回an,这样每次返回的数值都不一样,也就是相当于随机数了.但是其实不是真正的随机数,真正的随机数是使用物理现象产生

随机推荐