• C语言学习8:malloc返回的void*类型指针不可以做更改,free双重释放,二维数组的初始化和打印,a和a[0]和a[0][0]的区别,数组指针(*p)[3],指针数组*a[10],动态内存分配版约瑟夫环,动态分配版去空格和逗号处理,二级指针与二维数组互用


    1,malloc返回的void *类型指针不可做更改

    #include <stdio.h> 
    #include <stdlib.h> 
    
    int main(void) 
    { 
            int *p=malloc(20); 
    
            p++; 
    
            //p已经变化过,因此是 无效的释放 
            free(p); 
    
            return 0; 
    }

    结果:报错

    *** Error in `./a.out': free(): invalid pointer: 0x0156000c *** 
    Aborted (core dumped) 

    2,free双重释放

    #include <stdio.h> 
    #include <stdlib.h> 
    //双重释放,p的值不变,但是系统报警告: 
    int main(void) 
    { 
            int *p=malloc(32); 
    
            printf("p=%p
    ",p); 
        
            free(p); 
    
            printf("====================
    "); 
            printf("p=%p
    ",p); 
            //double free 
            free(p); 
    
            return 0; 
    }

    结果:

    p=0x1238008 
    ==================== 
    p=0x1238008 
    *** Error in `./a.out': double free or corruption (fasttop): 0x01238008 *** 
    Aborted (core dumped)

    3,二维数组的初始化和打印

    #include <stdio.h> 
    //数组的初始化和输出打印形式 
    
    int main(void) 
    { 
            int a[2][3] = {3,4,5,6,7,8}; 
            int b[2][3] = {{6,7,8},{9,10,11}}; 
    
            int c[][3]={[0][2]=16,[1][1]=32}; 
    
            int i,j; 
            for(i=0;i<2;i++) 
            {   
                    for(j=0;j<3;j++) 
                    {   
                            printf("a[%d][%d] = % 2d ",i,j, *(*(a+i)+j)); 
                    }   
                    putchar('
    '); 
            }   
    
            printf("========================
    "); 
            for(i=0;i<6;i++) 
                    printf("b[0][%d] = %d
    ",i,b[0][i]); 
            printf("=======================
    "); 
            for(i=0;i<2;i++) 
                    for(j=0;j<3;j++) 
                    { 
                            printf("c[%d][%d]=%2d
    ",i,j,c[i][j]); 
                    } 
            return 0; 
    } 

    结果:

    a[0][0] =  3 a[0][1] =  4 a[0][2] =  5 
    a[1][0] =  6 a[1][1] =  7 a[1][2] =  8 
    ======================== 
    b[0][0] = 6 
    b[0][1] = 7 
    b[0][2] = 8 
    b[0][3] = 9 
    b[0][4] = 10 
    b[0][5] = 11 
    ======================= 
    c[0][0]= 0 
    c[0][1]= 0 
    c[0][2]=16 
    c[1][0]= 0 
    c[1][1]=32 
    c[1][2]= 0 

    4,a和a[0],a[0][0]的区别

    #include <stdio.h> 
    //a和a[0]和a[0][0]是同一个地址和值,都表示首地址,但是代表的含义不同 
    
    int main(void) 
    { 
            int a[2][3]={23,34,67,25,55,99}; 
    
            printf("sizeof a =%u
    ",sizeof a );//代表不同的范围,整个 
            printf("sizeof a[0]=%u
    ",sizeof a[0]);//1行 
            printf("sizeof a[0][0]=%u
    ",sizeof a [0][0]);//二维数组一个元素 
    
            printf("-------------------------------
    "); 
    
            printf("&a=%p
    ",&a);//初始地址都是一样的 
            printf("a=%p
    ",a); 
            printf("&a[0]=%p
    ",&a[0]); 
            printf("&a[0][0]=%p
    ",&a[0][0]); 
    
            printf("------------------------------
    "); 
    
            printf("&a+1 =%p
    ",&a+1);//整个二维数组+1,就是加上24个字节 
            printf("-----------------------------
    "); 
            printf("a+1=%p
    ",a+1);//这个加12个字节,加一行
            printf("&a[0]+1=%p
    ",&a[0]+1);//加12个字节 
            printf("=----------------------------
    "); 
            printf("a[0]+1=%p
    ",a[0]+1);//加一个元素4个字节 
            printf("&a[0][0]+1=%p
    ",&a[0][0]+1);//加上一个元素 
    
            return 0; 
    } 

    结果:加了取地址符,

    sizeof a =24 
    sizeof a[0]=12 
    sizeof a[0][0]=4 
    ------------------------------- 
    &a=0xbeed3190 
    a=0xbeed3190 
    &a[0]=0xbeed3190 
    &a[0][0]=0xbeed3190 
    ------------------------------ 
    &a+1 =0xbeed31a8 
    ----------------------------- 
    a+1=0xbeed319c 
    &a[0]+1=0xbeed319c 
    =---------------------------- 
    a[0]+1=0xbeed3194 
    &a[0][0]+1=0xbeed3194 

    5,数组指针

    #include <stdio.h> 
    //分析数组指针 
    void foo(int a[][3],int len) 
    { 
            int i,j; 
    
            printf("int foo,size of a=%u
    ",sizeof a); 
            for(i=0;i<len;i++) 
            {   
                    for(j=0;j<3;j++) 
                    {   
                            printf("a[%d][%d]=%2d
    ",i,j,a[i][j]); 
                    }//%2d其实是表示列宽为2,其实大了会自动补全 
                    putchar('
    '); 
            }   
    } 
    void bar(int(*p)[3],int len) 
    { 
            int i,j; 
    
            for(i=0;i<len;i++) 
            {   
                    for(j=0;j<3;j++) 
                    { 
                            printf("p[%d][%d]=%2d
    ",i,j,*(*(p+i)+j)); 
                    } 
            } 
    
    } 
    int main(void) 
    { 
            int a[2][3]= {6,7,234,45,754,2}; 
    
            int (*p)[3]=NULL;//这个是指针数组,存放数据类型是指针 
    
            p=a;//所以指针要这么赋值指向 
            printf("sizeof a=%u,sizeof p=%u
    ",sizeof a,sizeof p); 
    
            int i,j; 
            for(i=0;i<2;i++)//指针数组的打印形式 
            { 
                    for(j=0;j<3;j++) 
                    { 
                            printf("p[%d][%d]=%2d
    ",i,j,*(*(p+i)+j)); 
                    } 
                    putchar('
    '); 
            } 
    
                                     
     printf("__________________________
    "); 
            foo(a,2); 
            printf("_________________________
    "); 
            bar(a,2); 
    
            return 0; 
    } 

    结果:

    sizeof a=24,sizeof p=4 
    p[0][0]= 6 
    p[0][1]= 7 
    p[0][2]=234 
    p[1][0]=45 
    p[1][1]=754 
    p[1][2]= 2 
    
    __________________________ 
    int foo,size of a=4 
    a[0][0]= 6 
    a[0][1]= 7 
    a[0][2]=234 
    a[1][0]=45 
    a[1][1]=754 
    a[1][2]= 2 
    _______________________ 
    p[0][0]= 6 
    p[0][1]= 7 
    p[0][2]=234 
    p[1][0]=45 
    p[1][1]=754 
    p[1][2]= 2 

    6,指针数组,

    #include <stdio.h> 
    //数值指针 
    int main(void) 
    { 
            int a[3][4]={ 
                    [0][2]=36,[0][3]=48, 
                    [1][1]=66,[1][2]=32, 
                    [2][2]=88,[2][3]=96, 
            };  
            int *p[3]={a[0],a[1],a[2]};//数组指针应用方式 
    
            int i,j; 
            for(i=0;i<3;i++) 
            {   
                    for(j=0;j<4;j++) 
                    {   
                            printf("p[%d][%d]=%2d",i,j,*(*(p+i)+j)); 
                    }   
                    putchar('
    '); 
            }   
            printf("==========================
    "); 
    char *sary[3]={ 
                    "china unix", 
                    "chongqing university", 
                    "uplooking" 
            }; 
            for(i=0;i<3;i++) 
                    puts(sary[i]); 
            return 0; 
    } 

    结果:

    p[0][0]= 0p[0][1]= 0p[0][2]=36p[0][3]=48 
    p[1][0]= 0p[1][1]=66p[1][2]=32p[1][3]= 0 
    p[2][0]= 0p[2][1]= 0p[2][2]=88p[2][3]=96 
    ========================== 
    china unix 
    chongqing university 
    uplooking 

    7,约瑟夫环  从M个人中去的N位置的人

    #include <stdio.h> 
    #include <stdlib.h> 
    
    //函数返回指向数组char[8]的指针 
    char (*alloc_mem(int row))[8] 
    { 
        return malloc(row * sizeof(char) * 8); 
    } 
    
    void rand_mem(char (*p)[8],int row) 
    { 
        int i; 
        for(i=0;i<row;i++) 
        { //格式化打印
            sprintf(p[i],"%c%c%c%c%c%c",rand()%26+'A', 
                    rand()%26+'a',rand()%26+'a', 
                    rand()%26+'a',rand()%26+'a',''); 
    
        } 
    } 
    
    void print_name(char (*p)[8],int row) 
    { 
        int i; 
        for(i=0;i<row;i++) 
        { 
            printf("%2d: %s",i+1,p[i]); 
            if((i+1)%4==0) putchar('
    '); 
        } 
        putchar('
    '); 
    } 
    
    int main(void) 
    { 
        int m,n; 
        char (*pname)[8]; 
    
        printf("input m&n:"); 
        scanf("%d%d",&m,&n); 
    
        pname=alloc_mem(m); 
        rand_mem(pname,m); 
        print_name(pname,m); 
    
        printf("===================
    "); 
        printf("退出序号:
    "); 
    
        int i,out=m,count=0; 
        while(out>0) 
        { 
            for(i=0;i<m;i++) 
            { 
            //    if(pname[i][0]!='')    有问题
                    count++; 
                if(count==n) 
                { 
                    printf("%2d:%s
    ",i+1,pname[i]); 
    
                    out--; 
                    count=0; 
        //            pname[i][0]='';   有问题
                } 
            } 
        } 
        free(pname); 
            return 0; 
    
    } 
    
    //犯过的错误1,没有对这个进行%26出现乱码 
    //char (*pname)[8];定义指针数组
    //我不明白这个pname[i][0]=''有什么用,存在反而有问题,待考证的项目 

    结果:

    will@will-laptop:~/ex/7$ ./a.out 
    input m&n:4 3 
     1: Nwlrb 2: Bmqbh 3: Cdarz 4: Owkky 
    
    =================== 
    退出序号: 
     3:Cdarz 
     2:Bmqbh 
     1:Nwlrb 
     4:Owkky 
    will@will-laptop:~/ex/7$ ./a.out 
    input m&n:6 6 
     1: Nwlrb 2: Bmqbh 3: Cdarz 4: Owkky 
     5: Hiddq 6: Scdxr 
    =================== 
    退出序号: 
     6:Scdxr 
     6:Scdxr 
     6:Scdxr 
     6:Scdxr 
     6:Scdxr 
     6:Scdxr 

    8.应用到动态内存分配的去掉空格和逗号的处理

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    //输入一个连续带空格的字符串,输出无间隔的字符串 
    char s[1024]; 
    char *sary[64]; 
    
    int main(void) 
    { 
        printf("input a string:"); 
        gets(s); 
    
        int i=0,count=0,j; 
        int word_start,word_len; 
    
        while(1) 
        { 
            if(s[i]!=' '&&s[i]!=',') 
            { 
                word_start=i; 
                while(s[i]!=' '&&s[i]!=','&&s[i]!='') 
                    i++; 
                word_len=i-word_start; 
                //计算一个连续字符串的长度 
    
                sary[count]=malloc(word_len+1); 
                //分配空间 
                if(NULL==sary[count]) 
                    goto err0; 
                memcpy(sary[count],s+word_start,word_len); 
                //内存交换 
     
                sary[count][word_len]=''; 
                //最后赋予一个结束符 
    
                count++; 
            } 
            if(s[i]=='')//判断是否转换完成 
                break; 
            i++; 
        } 
        printf("----------------------
    "); 
        for(i=0;i<count;i++) 
            printf("%s",sary[i]); 
        for(i=0;i<count;i++) 
            free(sary[i]); 
        return 0; 
    err0: 
        for(j=0;j<i;j++) 
            free(sary[j]); 
    } 
    //出现错误段错误:err0没有处理好,一厢情愿的认为释放count就好,不知道 
    //count=0的时候无法释放,还有就是第32行没有两个等于,也会出现段错误。 
    //显示乱码错误:结果是21行少一个等于号

    结果:

    will@will-laptop:~/ex/7$ gcc 7.8.c 
    7.8.c: In function ‘main’: 
    7.8.c:11:2: warning: ‘gets’ is deprecated (declared at /usr/include/stdio.h:638) [-Wdeprecated-declarations] 
    will@will-laptop:~/ex/7$ ./a.out 
    input a string:what your name wo,sn,sn 
    ---------------------- 
    whatyournamewosnsn

    9.二级指针与二维数组用法

    #include <stdio.h> 
    //二级指针和二维数值是可替换的关系 
    
    int main(void) 
    { 
        char *sary[3]={ 
            "china unix", 
            "chongqing university", 
            "uplooking" 
         
        }; 
        char **p=NULL; 
        p=sary; 
    
        int i; 
        for(i=0;i<3;i++) 
            puts(p[i]); 
        return 0; 
    }

    结果:

    will@will-laptop:~/ex/7$ ./a.out 
    china unix 
    chongqing university 
    uplooking 
  • 相关阅读:
    LinkButton(按钮)
    清理SharePoint 2010的SQL Server 2008 R2日志数据库的方法
    Sharepoint日志文件增长巨大的解决办法/缩小日志/删除日志
    PDF2SWF简单使用
    SharePoint 2010 网站备份还原简单介绍
    SolidWorks二次开发的研究
    基于VB语言对SolidWorks参数化设计的二次开发
    什么是PDM?
    SharePoint 2010配置PDF文件全文检索
    《博客园精华集--Sharepoint分册》第三轮结果(转)
  • 原文地址:https://www.cnblogs.com/will-boot/p/3303734.html
Copyright © 2020-2023  润新知