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 
原文地址:https://www.cnblogs.com/will-boot/p/3303734.html