【C/C++】 malloc与二级指针详解

目录

一. 用法例题1

1. 问题描述

2. 题解代码

二. 用法例题2

三. 安全动态拓展

四. 动态结构体储存


一. 用法例题1

1. 问题描述

Description

把字符串按照ASCII码序的从小到大排列出来。

串的ASCII码序遵循如下递归定义:

(1)两串的前n-1个字符相同,第n个字符ASCII码序小的排在前面;
(2)只有两串的字符完全相同时,才有两串相等。

字符的ASCII码序比较可以用strcmp()函数完成。

Input

第一行输入为一个整数N(N<=50,000),后接N行,每行一个字符串,串长不超过100,000。

Output

输出为N行,按照字符串的ASCII码序排列,ASCII码序小的排前面。

Sample Input

10
abc
bca
cac
aca
aca
bab
cd
ba

Sample Output

aac
aba
abc
aca
bab
cbc
cc
ada

HINT

用二维数组很难一次性分配出这么大的空间了,要用到根据输入变化的动态分配的内存才行。这里需要动态的数据结构,比如,字符指针的数组“char *s[]”,或者是二维的字符指针“char **s”,等等。

2. 题解代码

        char **s和char *s[]是相类似的,一个二级指针,一个指针数组s,里面元素也是指针,等同于char **s;此题中串长不超十万,行数不超5万,定义一个s[][]肯定不可能,占内存太多,所以要动态分配每一行的内存。但是刚上来的行数也是不确定的,也需要动态分配,因此char *s[n]里面的n是未知的,所以最好用二级指针,然后qsort快排。其参考代码如下:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#include<malloc.h>

#define maxn 100010
char str[maxn];

int cmp(const void *a,const void *b)
{
    return strcmp(*(char**)a,*(char**)b);//二级指针快排。
}

int main()
{
    int N;
    scanf("%d",&N);
    getchar();
    int i,j;
    char**p;
    p=(char **)malloc(sizeof(char*)*(N+1));//分配行数(相应的指针类型malloc(相应的元素类型*数量))
    for(i=0;i<N;i++)
    {
        gets(str);//用一个str来读取输入,赋值给每一行
        p[i]=(char*)malloc(sizeof(char)*strlen(str)+1);//分配每一行内存
        strcpy(p[i],str);
    }
    qsort(p,N,sizeof(char*),cmp);
    for(j=0;j<N;j++)
        printf("%s\n",p[j]);
    free(p);//释放
    return 0;
}
        注意排序易错:用strcpy,因字符数组大小不一,若把长度长的赋给断的,则会越界!所以用指针交换地址或者用qsort快排。指针排序如下:
for(i=1; i<N; i++)
        for(j=N-1; j>=i; j--)
        {
            if(strcmp(p[j],p[j-1])<0)
            {
                char *wx=p[j];//指针交换!防止长度不一
                p[j]=p[j-1];
                p[j-1]=wx;
            }
        }

二. 用法例题2

#include <stdio.h>
#include<malloc.h>
int a,b;
double* allocate(int n)
{
    return (double*)malloc(sizeof(double)*n);//(相应的指针类型)malloc(相应的元素类型*数量)
}
void input(double* p, int n)
{
    int i;
    for(i=0;i<n;i++)
    {
        scanf("%lf",&p[i]);
    }
    scanf("%d%d",&a,&b);
}
void output(double* p, int n)
{
    int i,j;
    if(a>n||b<1)
        printf("no output\n");
    else
    {
        if(b>n)
            b=n;
        if(a<1)
            a=1;
        for(i=a-1;i<b;i++)
            printf("%g\n",p[i]);

    }

}
void release(double* p)
{
    free(p);
}
int main()
{
    int len;
    double *array;
    scanf("%d",&len);
    array=allocate(len);
    input(array,len);
    output(array,len);
    release(array);

}

三. 安全动态拓展

#include <stdio.h>
#include<malloc.h>
#include "headd.h"
//typedef struct Array
//{
//    int capacity;
//    int length;
//    int *elements;
//}ARRAY;
void init(ARRAY *arr)
{
    arr->capacity=100;
    arr->length=0;
    arr->elements=(int*)malloc(sizeof(int)*arr->capacity);
}
void append(ARRAY *arr,int n)
{
    if(arr->length==arr->capacity)
    {
        arr->capacity+=10;
        arr->elements=(int *)realloc(arr->elements,sizeof(int)*arr->capacity);
    }
    arr->elements[arr->length++]=n;

}
int get(ARRAY arr,int n)
{
    if(n<0||n>=arr.length)
    {

        return -1;
    }
    else
        return arr.elements[n];
}
int main()
{
    int N,i,n;
    scanf("%d",&N);
    ARRAY arr;
    init(&arr);
    for(i=0;i<N;i++)
        append(&arr,i+1);
    int k;
    while(scanf("%d",&k)!=EOF)
    {
        if(get(arr,k)==-1)
            printf("NO FOUND!\n");
        else
            printf("%d\n",get(arr,k));
    }
    free(arr.elements);
    return 0;

}

四. 动态结构体储存

#include <stdio.h>
#include<string.h>
typedef struct
{
    int age;
    char sex;
    char *name;
} PERSON;
int main()
{
    char str[1001];
    int N,i,j;
    PERSON *persons,temp;
    scanf("%d",&N);
    persons=(PERSON *)malloc(sizeof(PERSON)*(N+1));
    for(i=0; i<N; i++)
    {
        scanf("%d",&persons[i].age);
        getchar();
        scanf("%c",&persons[i].sex);
        scanf("%s",str);
        persons[i].name=(char *)malloc(sizeof(char)*strlen(str)+1);
        strcpy(persons[i].name,str);

    }
    for(i=1; i<N; i++)
        for(j=N-1; j>=i; j--)
        {
            if(persons[j].age<persons[j-1].age||(persons[j].age==persons[j-1].age&&strcmp(persons[j].name,persons[j-1].name)<0))
            {
                temp=persons[j];
                persons[j]=persons[j-1];
                persons[j-1]=temp;
            }

        }
    for(i=0;i<N;i++)
    {
        printf("%s %d %c\n",persons[i].name,persons[i].age,persons[i].sex);
    }
    for(i=0;i<N;i++)
        free(persons[i].name);//注意释放!
    free(persons);
    return 0;


}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿阿阿安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值