C语言学习9: malloc动态内存存储,动态内存分配去空格字符增长版,动态内存分配去符号incr增长版,型参和返回值都是int型的函数的指针,main函数的地址也可以用指针指向,typedef定义函数指针,函数定义与嵌套的作用,返回函数指针类型,const作用

1,malloc动态内存存储

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
//动态存储 
int main(void) 
{ 
        int *p=NULL; 
    int *tmp=NULL; 

    int n; 
    int ret; 

    int count=0; 

    while(1) 
    { 
retry: 
        printf("input num:"); 
        ret=scanf("%d",&n); 
        while(getchar()!='\n');//清空输入输出缓存区里面的东西 
        if(ret==0) 
            goto retry; 
        if(n==-1) 
            break; 
        tmp=malloc(sizeof(int) * (count+1)); 
        //多一个是因为有一个结束符 
        if(NULL==tmp) 
            goto err0; 
        memcpy(tmp,p,sizeof(int) * count); 
        //从p所指的内存地址的起始位置开始拷贝sizeof(int)*count 
        //个字节到tmp所指向的内存地址的起始位置中 
        tmp[count]=n; 
        //tmp得到每个输入的值, 

        free(p);//释放旧空间 
        p=tmp;//将p指向新的空间 

        count++;//输入一个数字,count加1 
    } 

    int i; 
    for(i=0;i<count;i++) 
    { 
        printf("%d ",p[i]); 
    } 
    putchar('\n'); 

    free(p); 

    return 0; 

err0: 
    free(p); 
    return 1;//释放空间 

} 

//只能接收数字,空格默认结束

结果:

will@will-laptop:~/ex/8$ ./a.out 
input num:5 
input num:6 
input num:7 
input num:8 
input num:8 
input num:2 
input num:-1 
5 6 7 8 8 2 

2,动态内存分配版的去空格,其中内存增长的方式是一个一个的加起来

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
//对一段语句进行单词的动态存储 
char *my_gets(void) 
{ 
    char *p=NULL,*tmp=NULL; 

    int ch,count=0; 
    while((ch=getchar())!='\n')//输入字符并清空输入区 
    { 
        tmp=malloc(count+1); 
        //因为是字符,所以char是1,所以输入的count长字符,用count 
        //长的空间存放 
        if(NULL==tmp) 
            goto err0; 
        memcpy(tmp,p,count); 
        tmp[count]=ch; 
        //这个就是来作用的玩意temp[1],temp[2],temp[3]都是相当于一个 
        //个数组赋值,count的每次增加都是给分配空间加大的 

        free(p);//释放老空间 
        p=tmp;//将tmp开辟的空间起始内存地址给p,使p的空间容纳存储的 
        //字符 

        count++;//每输入一次加一次 
    } 
/*    if(NULL==p)//最开始 
    { 
        p=malloc(1); 
        if(NULL==p) 
            goto err0; 
    }*/ 
    p[count]='\0';//给这个加一个结束符,占用一个字节即char长度 
    return p; 
err0: 
    free(p);          //释放空间 
    return NULL; 
} 

char **cut_word(char *s,int *cnt) 
{ 
    //这个就是去掉空格和逗号 
    char **p=NULL; 
    char **tmp=NULL; 

    int word_start,word_len; 
    int i=0,count=0; 
    while(1) 
    { 
        if(s[i]!=' '&&s[i]!=',') 
        { 
            word_start=i; 
             
            while(s[i]!=' '&&s[i]!=','&&s[i]!='\0') 
                i++; 
            word_len=i-word_start; 

            printf("count=%d\n",count); 
            printf("start:%c,end:%c\n",*(s+word_start),*(s+i-1)); 

            tmp=malloc(sizeof(char*)*(count+1)); 
            if(NULL==tmp) 
                goto err0; 
            memcpy(tmp,p,sizeof(char*)*count); 

            free(p); 
            p=tmp; 
                         //开辟一个空间个数组p 
                        
            p[count]=malloc(word_len+1); 
            //这个就是p[1]里面拥有一个单词的的字符串 
            if(NULL==p[count]) 
                goto err0; 
            memcpy(p[count],s+word_start,word_len); 
            p[count][word_len]='\0'; 

            count++; 

        } 
        if(s[i]=='\0')//整个字符串处理完成后跳出 
            break; 
        i++; 

    } 
    *cnt=count;//记录单词个数 
    return p; 
err0: 
    for(i=0;i<count;i++) 
        free(p[i]); 
    free(p);//原则谁开辟谁回收,这个开辟了p和p[]所以两者要释放 
    return NULL; 
} 

void free_word(char **p,int row) 
{ 
    int i; 
    for(i=0;i<row;i++) 
        free(p[i]); 
    free(p); 
}//同理释放 

 
int main(void) 
{ 
    char **pwords=NULL;//为了得到像二维数组的地址,必须二级指针 
    char *s=NULL;//为了得到输入一连串字符的地址 
    int cnt; 

    printf("input str:"); 
    s=my_gets(); 
    puts(s); 
        printf("_______________________________\n"); 

    pwords=cut_word(s,&cnt); 
    //为了改变cnt的值,只能使指针进去,所以变成&cnt 

    int i; 
    for(i=0;i<cnt;i++) 
        puts(pwords[i]);//给人的感觉就是一个指针的效果 
    free_word(pwords,cnt);//释放在cut_word函数中的malloc 
    free(s);//释放在get_word函数中的malloc 
    return 0; 
}

结果:

will@will-laptop:~/ex/8$ ./a.out 
input str:what your naem xxxx 
what your naem xxxx 
_______________________________ 
count=0 
start:w,end:t 
count=1 
start:y,end:r 
count=2 
start:n,end:m 
count=3 
start:x,end:x 
what 
your 
naem 
xxxx

3,动态内存分配版的去空格,去符号。不过这个不是来一个字符增加一个,而是只增加一次incr大小的空间。避免多次操作浪费时间。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

char *my_gets(int max,int incr) 
{ 
    char *p=NULL; 
    char *tmp=NULL; 

    p=malloc(max+1); 
    if(NULL==p) 
        goto err0; 
    int ch,count=0; 
    while((ch=getchar())!='\n') 
    { 
        if(count>=max) 
        { 
            tmp=malloc(max+incr+1);//比较大小重新分配指定大小 
            if(NULL==tmp) 
                goto err1; 
            memcpy(tmp,p,max); 
            free(p); 
            p=tmp; 

            max+=incr; 

        } 
        p[count]=ch; 
        count++; 
    } 
    p[count]='\0'; 
    printf("111111111111111]\n"); 
    return p; 
err1: 
    free(p); 
err0: 
    return NULL; 

} 

char **cut_word(char *s,char *delim,int *cnt) 
{ 
    char **p=NULL; 
    char **tmp=NULL; 

    int word_start,word_len; 
    int i=0,count=0; 

    while(1) 
    { 
        if(!strchr(delim,s[i])) 
        { 
            word_start=i; 
            while(!strchr(delim,s[i])&&s[i]!='\0') 
                i++; 
            word_len=i-word_start; 

            printf("count=%d\n",count); 
            printf("start:%c,end:%c\n",*(s+word_start),*(s+i-1)); 
            tmp=malloc(sizeof(char *)*(count+1)); 
            if(NULL==tmp) 
                goto err0; 
            memcpy(tmp,p,sizeof(char *)*count); 

            free(p); 
            p=tmp; 

            p[count]=malloc(word_len+1); 
            if(NULL==p[count]) 
                goto err0; 
            memcpy(p[count],s+word_start,word_len); 
            p[count][word_len]='\0'; 

            count++; 

        } 
        if(s[i]=='\0') 
            break; 
        i++; 

                 
    } 
    *cnt=count; 
    return p; 
     
err0: 
    for(i=0;i<count;i++) 
        free(p[i]); 
    free(p); 
    return NULL; 

} 
void free_word(char **p,int row) 
{ 
     int i; 
     for(i=0;i<row;i++) 
         free(p[i]); 
     free(p); 
} 
int main(void) 
{ 
    char *s=NULL; 
    char **pwords=NULL; 
    int cnt; 

    printf("input s:"); 
    s=my_gets(5,10); 
    puts(s); 

    pwords=cut_word(s," ,?!:\"\'",&cnt); 

    int i; 
    for(i=0;i<cnt;i++) 
        puts(pwords[i]); 
    free_word(pwords,cnt); 
    free(s); 
    return 0; 
}

结果:

will@will-laptop:~/ex/8$ ./a.out 
input s:what your naem : 
111111111111111] 
what your naem : 
count=0 
start:w,end:t 
count=1 
start:y,end:r 
count=2 
start:n,end:m 
what 
your 
naem 

4,型参和返回值都是int型的函数的指针。函数指针的用法

#include <stdio.h> 

int add(int l,int r) 
{ 
    return l+r; 

} 

int sub(int l,int r) 
{ 
    return l-r; 
} 

int main(void) 
{ 
    //pfunc是int(*)(int,int)类型 
    //pfunc指向int()(int,int)函数类型 
    int (*pfunc)(int,int)=NULL; 
        //pfunc1是double(*)(double,double)类型 
    double(*pfunc1)(double,double)=NULL; 

    int a=9,b=6; 
    int ret; 

    pfunc=add; 
    ret=pfunc(a,b); 
    printf("ret=%d\n",ret); 

    pfunc=&sub; 
    ret=(*pfunc)(a,b); 
    printf("ret=%d\n",ret); 

    printf("----------------------\n"); 
        //强制类型转换 
    //程序员要自己保证,所指向的函数,其返回值和参数类型 
    //都相同(类型兼容,占用空间一致,形式不会变化) 
    pfunc1=(double(*)(double,double))add; //强制转化为双精度
    ret=pfunc1(a,b); 
    printf("ret=%d\n",ret); 

    return 0; 

}

结果:

will@will-laptop:~/ex/8$ ./a.out 
ret=15 
ret=3 
---------------------- 
ret=9 

5,main函数地址可以用指针指向

#include <stdio.h> 

int main(void) 
{ 
    void *p=main; 

    printf("addr of main=%p\n",main); 
    printf("addr of main=%p\n",p); 

    return 0; 
}

结果:

will@will-laptop:~/ex/8$ ./a.out 
addr of main=0x83fd 
addr of main=0x83fd 

7,typedef定义

#include <stdio.h> 

typedef int int32; 
#define INIT32 int 
//fun_t代表 int()(int,int)函数类型 
typedef  int (func_t)(int,int); 

//pfun_t代表int(*)(int,int)函数指针类型 
typedef int (*pfunc_t)(int,int); 

int add(int l,int r) 
{ 
    return l+r; 
} 

int sub(int l, int r) 
{ 

    return l-r; 
} 

int main(void) 
{ 
    INIT32 a=12; 
    int32 b=8; 

    int ret; 

    func_t *pf1 = add; 
    ret= pf1(a,b); 
    printf("ret=%d\n",ret); 

    pfunc_t pf2 = sub; 
    ret=pf2(a,b); 
    printf("ret = %d\n",ret); 
    return 0; 
}

结果:

will@will-laptop:~/ex/8$ ./a.out 
ret=20 
ret = 4 

8,函数定义后与嵌套的作用

#include <stdio.h> 

typedef int int32; 
#define INT32 int 

//fun_t代表 int()(int,int)函数类型 
typedef int (fun_t)(int , int); 

//pfunc_t代表 int(*)(int,int)函数指针类型 
typedef int (*pfunc_t)(int, int); 

int add(int l, int r) 
{ 
    return l+r; 
} 

int sub(int l, int r) 
{ 
    return l-r; 
} 
//int operation(pfunc_t pf,int a ,int b) 
//两者定义完全相同 
int operation(int (*pf)(int,int),int a,int b) 
{ 
    return pf(a,b); 
} 

int main(void) 
{ 

    INT32 a=12; 
    int32 b=8; 
    int ret; 

    ret=operation(add,a,b); 
    printf("ret=%d\n",ret); 

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

    ret=operation(sub,a,b); 
    printf("ret=%d\n",ret); 
    return 0; 
}

结果:

will@will-laptop:~/ex/8$ gcc 8.8.c 
will@will-laptop:~/ex/8$ ./a.out 
ret=20 
---------------------------- 
ret=4 

9,返回函数指针类型

#include <stdio.h> 

typedef int (func_t)(int,int); 
//同样这两个也是代表不同的函数类型,不过意思都是一样 
typedef int (*pfunc_t)(int,int); 

int add(int l,int r) 
{ 
    return l+r; 
} 
int sub(int l,int r) 
{ 
    return l-r; 
} 

//pfunc_t choice_func(int choice) 
//这个就是使用上面定义的两个不同的方式进行函数的使用 
int (*choice_func(int choice))(int,int) 
{ 
    if(choice == 0) 
        return add; 
    else 
        return sub; 
} 

int main(void) 
{ 
    int a=2,b=8; 
    int ret; 

    ret=choice_func(0)(a,b); 
    printf("ret=%d\n",ret); 

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

    ret=choice_func(1)(a,b); 
    printf("ret=%d\n",ret); 

    return 0; 

}

结果:

will@will-laptop:~/ex/8$ ./a.out 
ret=10 
------------------------ 
ret=-6 

10,singnal函数见杂项吧

11,const作用

#include <stdio.h> 

int main(void) 
{ 
    int a=8; 
        //不能通过p修改 *p 
           const int *p=NULL; 
       // int const *p=NULL; 
    p=&a; 
    printf("a=%d,*p=%d\n",a,*p); 
        
    //不能通过p修改 *p 
    // *p=32;这个是直接赋值 
    a=16; 
    printf("a=%d,*p=%d\n",a,*p); 

    printf("---------------------------\n"); 
           
    //变量p1是const,p1本身不能被修改 
    //意味着该指针变量只能在初始化时“赋值” 
    int *const p1=&a; //这个被初始化赋值不能修改了 
    *p1=32; 
    printf("a=%d,*p=%d\n",a,*p); 
        
    //p本身是const的 
    //并且不能通过p2修改 *p2 
    const int *const p2 = &a; 
    printf("a=%d,*p2=%d\n",a,*p2); 
         //不能通过p3修改 *p3,也不能通过 *p3 修改 **p3 
    const int * const *p3; 

    return 0; 
}

结果:

will@will-laptop:~/ex/8$ ./a.out 
a=8,*p=8 
a=16,*p=16 
--------------------------- 
a=32,*p=32 
a=32,*p2=32 

 

 

 

posted @ 2013-10-06 09:46  泛起的鱼  阅读(547)  评论(0编辑  收藏  举报