二级指针做函数的输入与输出

本文将介绍二级指针做函数输出以及做函数输入的三种内存模型从内存四区的角度对程序执行的过程进行剖析,通过这中方式来加深对指针的理解。

二级指针做输出(在被调函数中分配内存)模型:

主函数:

int main()
{
    char *p = NULL;
    int len = 0;
    getMem(&p, &len);
    printf("p=%s\n", p);
    FreeMem(&p);
    return 0;
}

getMem函数:

int getMem(char **myp,int *mylen)
{
    char *temp = NULL;
    temp = (char*)malloc(100);
    if (temp == NULL)
    {
        return -1;
    }
    strcpy(temp, "abcdefg");
    *mylen = strlen(temp);
    *myp = temp;
    return 0;
}

犯的错误:

*myp = temp; 最初写成了*myp = *temp; 而该表达式赋值两端根本不是一种数据类型。

*myp = temp1; 这句话与*mylen = 某一数值 本质上是一样的,都是*加上指针变量来改变主调用函数中的内容只不过,myp为二级指针因此赋值的右端应为一级指针。

补充:

"abcdefg"在常量区中,strcpy(temp, "abcdefg"); 这一句使得temp指向"abcdefg",其值为字符‘a‘的地址。

总结:

想要在被调用函数中修改主调用函数中的值,必须使用指针,例如在getMem函数中,修改变量的值使用一级指针,修改一级指针需要用到二级指针。

FreeMem函数:

void FreeMem(char **myp)
{
    if (myp == NULL)
    {
        return;
    }
    char *tmp = NULL;
    tmp = *myp;
    free(tmp);
    tmp = NULL;
}
void FreeMem(char *myp)
{
    if(myp = NULL)
    {
        return ;
    }
    free(myp);
}

这两种FreeMem函数都可以释放p指向的内存,但第一个函数的好处在于使用了二级指针,可在FreeMem函数中将主调用函数中的p的值改为NULL避免 野指针的出现,而第二个函数则要在FreeMem后加上一句p=NULL

调试结果:

二级指针做输入(在主调用函数中分配内存)模型一:

指针数组:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char *myArray[] = { "xcccc","ybbbb","zaaaa" };
    int len = sizeof(myArray) / sizeof(myArray[0]);
    int i = 0;
    for (i = 0; i < len; i++)
    {
        printf("%s\n", myArray[i]);
        //printf("%s\n", *(myArray+i)); 效果相同
    }
    int j, k;
    j = k = 0;
    char *temp = NULL;
    for (j = 0; j < len - 1; j++)
    {
        for (k = 0; k < len - j - 1; k++)
        {
            if (strcmp(myArray[k], myArray[k + 1]) > 0)
            {
                temp = myArray[k];
                myArray[k] = myArray[k + 1];
                myArray[k + 1] = temp;
            }
        }
    }
    for (i = 0; i < len; i++)
    {
        printf("%s\n", myArray[i]);
        //printf("%s\n", *(myArray+i)); 效果相同
    }
    return 0;
}

总结:

1.在32位操作系统下指针变量的长度为4,在64位下为8。

2.指针数组为元素为指针的数组,myArray数组中有三个元素,sizeof(myArray) / sizeof(myArray[0])可以求出数组长度。

3.排序使用的为最简单的冒泡排序。排序过程中交换的是指针而不是内存块。

二级指针做输入模型一封装函数:
主函数:
int main()
{
    char *myArray[] = { "zzz","yyyyyyy","xxxxxxxxx" };
    int len = sizeof(myArray) / sizeof(myArray[0]);

    printArray(myArray, len);

    SortArray(myArray, len);
    printArray(myArray, len);

    return 0;
}

打印函数:

void printArray(char **myArray, int len)
{
    for (int i = 0; i < len; i++)
    {
        printf("%s\n", myArray[i]);
    }
}
排序函数:
void SortArray(char **myArray, int len)
{
    char *temp = NULL;
    for (int i = 0; i < len - 1; i++)
    {
        for (int j = 0; j < len - 1 - i; j++)
        {
            if (strcmp(myArray[j], myArray[j + 1]) > 0)
            {
                temp = myArray[j];
                myArray[j] = myArray[j + 1];
                myArray[j + 1] = temp;
            }
        }
    }
}

总结:

数组在做函数参数是退化为指针,数组名指向数组的第一个元素,即数组名中存放的是数组中第一个元素的地址。指针数组也是如此,char *myArray[];中定义了一个名为myArray的指针数组,根据上面的说明,myArray为第一个元素的地址,而数组元素为指向char类型的指针,即为char *类型,因此myArraychar **类型,所以在函数中第一个参数,均为char **myArray

二级指针做输入(在主调用函数中分配内存)模型二:

二维数组:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char myArray[10][30] = { "ddddd","ccccc","bbbbb","aaaaa" };
    int num = 4;
    for (int i = 0; i < num; i++)
    {
        printf("%s\n", myArray[i]);
    }
    char temp[30];
    for (int i = 0; i < num - 1; i++)
    {
        for (int j = 0; j < num - 1 - i; j++)
        {
            if (strcmp(myArray[j], myArray[j + 1]) > 0)
            {
                strcpy(temp, myArray[j]);
                strcpy(myArray[j], myArray[j + 1]);
                strcpy(myArray[j + 1], temp);
            }
        }
    }
    for (int i = 0; i < num; i++)
    {
        printf("%s\n", myArray[i]);
    }
    return 0;
}

二级指针做输入模型二封装函数:

主函数:

int main()
{
    char myArray[10][30] = { "ddddd","ccccc","bbbbb","aaaaa" };
    int num = 4;
    printArray(myArray, num);
    SortArray(myArray, num);
    printArray(myArray, num);
    return 0;
}

打印函数:

void printArray(char (*myArray)[30], int len)
{
    for (int i = 0; i < len; i++)
    {
        printf("%s\n", myArray[i]);
    }
}

排序函数:

void SortArray(char (*myArray)[30], int len)
{
    char temp[30];
    for (int i = 0; i < len - 1; i++)
    {
        for (int j = 0; j < len - 1 - i; j++)
        {
            if (strcmp(myArray[j], myArray[j + 1]) > 0)
            {
                strcpy(temp, myArray[j]);
                strcpy(myArray[j], myArray[j + 1]);
                strcpy(myArray[j + 1], temp);
            }
        }
    }
}

总结:

二维数组在做函数参数的时候会退化成为一个指针数组。

二维数组中重要的两个点:

1.二维数组名为第一维首元素的地址。

2.一维数组名为首元素的地址。

有了这两点下面将演示如何用数组名打印某一个元素:

                      ==>  表示等价
myArray               ==>  &myArray[0]                     //上面的第一点
myArray + 2           ==>  &myArray[2]
*(myArray + 2)        ==>  myArray[2]  ==>  &myArray[2][0] //上面的第二点
*(myArray + 2) + 1    ==>  &myArray[2][1]
*(myArray + 2) + 4    ==>  &myArray[2][4]
*(*(myArray + 2) + 4) ==>  myArray[2][4]

二级指针做输入(在主调用函数中分配内存)模型三:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
    char **p = NULL;
    int num = 4;
    p = (char**)malloc(sizeof(char*)*num);
    for (int i = 0; i < num; i++)
    {
        p[i] = (char*)malloc(sizeof(char) * 100);
        sprintf(p[i], "%d%d%d", 4 - i, 4 - i, 4 - i);
    }
    for (int i = 0; i < num; i++)
    {
        printf("%s\n", p[i]);
    }
    char *temp = NULL;
    for (int i = 0; i < num - 1; i++)
    {
        for (int j = 0; j < num - i - 1; j++)
        {
            if (strcmp(p[j], p[j + 1]) > 0)
            {
                temp = p[j];
                p[j] = p[j + 1];
                p[j + 1] = temp;
            }
        }
    }
    for (int i = 0; i < num; i++)
    {
        printf("%s\n", p[i]);
    }
    for (int i = 0; i < num; i++)
    {
        if (p[i] != NULL)
        {
            free(p[i]);
            p[i] = NULL;
        }
    }
    if (p != NULL)
    {
        free(p);
        p = NULL;
    }
    return 0;
}

二级指针做输入模型三封装函数:

主函数:

int main()
{
    int num = 4;
    char **p = NULL;
    //p = getMem(num);
    getMem_1(&p, num); //两种方式
    printArray(p, num);
    SortArray(p, num);
    printArray(p, num);
    myArrayFree(p, num);
    return 0;
}

getMem函数:

char **getMem(int num)
{
    char **p = NULL;
    p = (char**)malloc(sizeof(char*)*num);
    for (int i = 0; i < num; i++)
    {
        p[i] = (char*)malloc(sizeof(char) * 100);
        sprintf(p[i], "%d%d%d", 4 - i, 4 - i, 4 - i);
    }
    return p;
}
int getMem_1(char ***p, int num)
{
    if (p == NULL)
    {
        return -1;
    }
    char **temp = NULL;
    temp = (char**)malloc(sizeof(char*)*num);
    for (int i = 0; i < num; i++)
    {
        temp[i] = (char*)malloc(sizeof(char) * 100);
        sprintf(temp[i], "%d%d%d", 4 - i, 4 - i, 4 - i);
    }
    *p = temp;
    return 0;
}
打印函数:
void printArray(char **myArray, int len)
{
    for (int i = 0; i < len; i++)
    {
        printf("%s\n", myArray[i]);
    }
}

排序函数:

void SortArray(char **myArray, int len)
{
    char *temp = NULL;
    for (int i = 0; i < len - 1; i++)
    {
        for (int j = 0; j < len - 1 - i; j++)
        {
            if (strcmp(myArray[j], myArray[j + 1]) > 0)
            {
                temp = myArray[j];
                myArray[j] = myArray[j + 1];
                myArray[j + 1] = temp;
            }
        }
    }
}

Free函数:

void myArrayFree(char **p,int len)
{
    for (int i = 0; i < len; i++)
    {
        if (p[i] != NULL)
        {
            free(p[i]);
            p[i] = NULL;
        }
    }
    if (p != NULL)
    {
        free(p);
        p = NULL;
    }
}

原文地址:https://www.cnblogs.com/optimjie/p/12252698.html

时间: 2024-08-29 03:07:35

二级指针做函数的输入与输出的相关文章

二级指针做函数输入参数

在主调用函数中分配内存: 1 char **myarray = (char **)malloc(10*sizeof(char *)); 2 if (myarray == NULL) 3 { 4 return -1; 5 } 6 for (i=0; i<10; i++) 7 { 8 myarray[i] = (char *)malloc(100); 9 } 释放内存: 1 for(i=0; i<10; i++) 2 { 3 free(myarray[i]); 4 } 5 if (myarray)

C提高_day03_二级指针做输入第2种内存模型

#include <stdlib.h> #include <string.h> #include <stdio.h> //打印 排序 //封装成函数 void main() { int i = 0, j = 0; int num = 4; char tmpBuf[30]; char myArray[10][30] = {"aaaaaa", "ccccc", "bbbbbbb", "1111111111

【通过操作指针,与指针做函数參数&amp;#39;实现字串在主串中出现的次数,然后将出现的部分依照要求进行替换 】

#include<stdio.h> #include<stdlib.h> int strTime(const char *str1, const char *str2, int *time) { int count = 0; char *p1 = str1; char *p2 = str2; //p1是第一次出现的位置 p1 = strstr(p1, p2); //注意这里不要写成*p1!=NULL 由于p1 是null的地址一旦读取*p1 会出错的!!!!不能读取操作系统的数据

通过操作指针,与指针做函数参数&#39;实现字串在主串中出现的次数,然后将出现的部分按照要求进行替换

#include<stdio.h> #include<stdlib.h> int strTime(const char *str1, const char *str2, int *time) { int count = 0; char *p1 = str1; char *p2 = str2; //p1是第一次出现的位置 p1 = strstr(p1, p2); //注意这里不要写成*p1!=NULL 因为p1 是null的地址一旦读取*p1 会出错的!!!!不能读取操作系统的数据

Day8 函数指针做函数参数

课堂笔记 课程回顾 多态 virtual关键字 纯虚函数 virtual func() = 0; 提前布局vptr指针 面向接口编程 延迟绑定 多态的析构函数的虚函数. 多继承的二义性 . 重载 重写 重定义. 实现多态的理论基础:函数指针做函数参数. vptr指针与虚函数表. 构造函数不应为虚函数 多态会降低程序的执行速度.不建议所有的函数都是虚函数. 多态时的指针步进. 多继承在项目开发中使用的比较少. linux从2.4内核升级到2.6的时候,做到了电源可以热插拔,提前将电源驱动的接口规划

二级指针作为函数参数的典型用法

用二级指针作为函数参数,有两种典型情况:1.需要传递一级指针的数组时:例如标准C的main函数:int main(int argc, char*[] argv),数组最高维可以退化,char*[] argv等价于char** argv.这里argv代表命令行参数数组.2.需要对传入的一级指针进行修改时:例如:void alloc_new_char_array(int n, char** t){*t = (char*)malloc(n * sizeof(t));}这里可以通过返回值达到相同的效果,

用指针做函数参数的好处,

用指针做函数参数的好处, 首先要理解函数传参的过程,函数传参是复制型的,例如 void modify(int a) { a++; } void main() { int a=5; modify(a); printf("%d",a); } 程序执行完之后,a的值还是5,为什么呢,因为在执行modify函数的时候,是另外开辟了存储空间,将a的值复制过去,然后modify函数所进行的所有操作都是针对这个新开辟的空间而言的,因此程序执行完之后,a的值并没有发生改变, 如果我们用指针去传递参数,

C++基础8【难】 回顾:数组指针,函数指针,函数指针做函数参数 C语言多态

1,数组指针语法梳理 回顾,如何定义数组数据类型: 回顾,如何定义指针类型数组: 回顾,如何直接定义 一个指向数组类型的指针: 2,函数指针语法梳理 1)如何定义一个函数类型 2)如何定义一个函数指针类型 3)如何定义一个函数指针(指向一个函数的入口地址) [中级程序员 转 高级程序员的 必经之路] 1,函数类型做函数的参数 把函数的入口地址传过来,奇怪的效果:[多态就是这样] 函数指针 做 函数参数 思想剖析 1,数组指针语法梳理 回顾,如何定义数组数据类型: [email protected

二级指针做输入的第三种内存模型:手工打造二维内存

声明局部变量p, p指向一段内存地址,这段内存地址存放这N个指针,每个指针都指向malloc的另一段内存. 内存模型图如下: p应该是二级指针 #define _CRT_SECURE_NO_WARNINGS#include<stdlib.h>#include<stdio.h>#include<string.h>#include<ctype.h> char**getMem(int num){ int i = 0, j = 0; char** p2 = NULL