您的位置:首页 > 编程语言 > C语言/C++

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

2013-09-05 17:19 1351 查看
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\n",p);

free(p);

printf("====================\n");
printf("p=%p\n",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('\n');
}

printf("========================\n");
for(i=0;i<6;i++)
printf("b[0][%d] = %d\n",i,b[0][i]);
printf("=======================\n");
for(i=0;i<2;i++)
for(j=0;j<3;j++)
{
printf("c[%d][%d]=%2d\n",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\n",sizeof a );//代表不同的范围,整个
printf("sizeof a[0]=%u\n",sizeof a[0]);//1行
printf("sizeof a[0][0]=%u\n",sizeof a [0][0]);//二维数组一个元素

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

printf("&a=%p\n",&a);//初始地址都是一样的
printf("a=%p\n",a);
printf("&a[0]=%p\n",&a[0]);
printf("&a[0][0]=%p\n",&a[0][0]);

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

printf("&a+1 =%p\n",&a+1);//整个二维数组+1,就是加上24个字节
printf("-----------------------------\n");
printf("a+1=%p\n",a+1);//这个加12个字节,加一行
printf("&a[0]+1=%p\n",&a[0]+1);//加12个字节
printf("=----------------------------\n");
printf("a[0]+1=%p\n",a[0]+1);//加一个元素4个字节
printf("&a[0][0]+1=%p\n",&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\n",sizeof a);
for(i=0;i<len;i++)
{
for(j=0;j<3;j++)
{
printf("a[%d][%d]=%2d\n",i,j,a[i][j]);
}//%2d其实是表示列宽为2,其实大了会自动补全
putchar('\n');
}
}
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\n",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\n",sizeof a,sizeof p);

int i,j;
for(i=0;i<2;i++)//指针数组的打印形式
{
for(j=0;j<3;j++)
{
printf("p[%d][%d]=%2d\n",i,j,*(*(p+i)+j));
}
putchar('\n');
}

printf("__________________________\n");
foo(a,2);
printf("_________________________\n");
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('\n');
}
printf("==========================\n");
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','\0');

}
}

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('\n');
}
putchar('\n');
}

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("===================\n");
printf("退出序号:\n");

int i,out=m,count=0;
while(out>0)
{
for(i=0;i<m;i++)
{
//    if(pname[i][0]!='\0')    有问题
count++;
if(count==n)
{
printf("%2d:%s\n",i+1,pname[i]);

out--;
count=0;
//            pname[i][0]='\0';   有问题
}
}
}
free(pname);
return 0;

}

//犯过的错误1,没有对这个进行%26出现乱码
//char (*pname)[8];定义指针数组
//我不明白这个pname[i][0]='\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]!='\0')
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]='\0';
//最后赋予一个结束符

count++;
}
if(s[i]=='\0')//判断是否转换完成
break;
i++;
}
printf("----------------------\n");
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


吃表达式的空格和逗号—重点是应用到了动态内存分配
-->
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐