这个作业属于哪个班级 | C语言--网络2011/2012 |
---|---|
这个作业的地址 | C博客作业05--指针 |
这个作业的目标 | 学习指针相关内容 |
姓名 | 王小雨 |
目录
0.展示PTA总分
1.本章学习总结
1.1指针定义、只针对相关运算、指针做函数参数。
1.1.1指针定义
1.1.2指针的基本运算
1.1.3指针做函数参数
1.2字符指针
1.3指针做函数返回值
1.4动态内存分配
1.4.1动态存储管理机制
1.4.2堆区和栈区的区别
1.4.3多个字符串做动态内存
1.5指针数组及其应用
1.6二级指针
1.7行指针、列指针
1.7.1定义格式
1.7.2主要用法
2.PTA实验作业
2.1删除字符串中的子串
2.1.1伪代码
2.1.2代码截图
2.1.3代码比较
2.2合并2个有序数组
2.2.1伪代码
2.2.2代码截图
2.2.3代码对比
2.3说反话-加强版
2.3.1伪代码
2.3.2代码截图
2.3.3代码比较
0.展示PTA总分
1.本章学习总结
1.1
指针变量:存放地址的变量
指针的值是某个变量的地址 &取址运算符
&取地址,*取内容
指针变量类型不是指针变量本身类型,是存放地址,它与指向变量类型一致
指针作为函数参数:
形参:指针变量
实参:地址
1.1.1指针定义
·类型 *变量名;
·eg:int *p;
*只有变量名前带有‘ 星号’才说明其为指针变量 *
·eg:
int *p, *s; //ture
int *p,s;==int a;int *p; //error
*在前面已经定义过的指针变量,使用时不能再加‘ 星号’ *
·eg:
int *p,a; *p=&a; //error
int *p,a;p=&a; //ture
**变量定义类型不一致,无法取地址 **
**相同类型的指针变量可以相互赋值 **
·eg:int *p, *t,a;p=&a;t=p;
//p与t,皆指向a;
1.1.2指针相关运算
char *p;
int i=1;
p=&i;
p++;//指i的地址加一
( *p)++;//指i的值加一
·p+t;//一个指针变量加or减一个整数是将该指针变量的原值(是一个地址)和它指向的变量所占用的内存单元字节数相加或相减。这样就保证了p+t指向p下面的第t个元素。
指针变量相减:
如果两个指针变量指向同一个数组的元素,则两个指针变量之差是两个指针之间的元素个数。
**指针变量相加无实际意义 **
指针变量比较:
如果两个指针变量指向同一个数组的元素,则可以进行比较。指向前面元素的指针变量小于指向后面元素的指针变量。
1.1.3指针做函数参数
指针可以作为函数参数传进函数里,而且传入的代价小,并且在函数运算时,可以改变指针指向的变量。
可以打破函数一次只能返回一个值的弱点。
void fiction(int n)
{
n+=1;//一旦函数结束,n值没有变。这里的n和传进来的n不是同一个,生命周期也是随着函数结束而结束。
}
void fiction(int *n)
{
*n+=1;//使用函数就可以改变这个地址内的n值,n的生命周期是随着主函数一起的。这样就不会随着函数而消失。
}
1.2 字符指针
包括指针如何指向字符串、字符串相关函数及函数代码原型的理解、字符串相关函数用法(扩展课堂未介绍内容)
指向字符串
char *p="Hello World!";
字符串相关函数及函数代码原型
·字符串输入函数:
函数 | 格式 | 功能 |
---|---|---|
gets() | gets(字符数组) | 从键盘输入一以回车结束的字符串放入字符数组中, 并自动加' ' |
scanf() | scanf("%s", 字符数组) | 从键盘输入一以空格或回车结束的字符串放入字符数 组中,并自动加' ' |
·字符串输出函数:
函数 | 格式 | 功能 |
---|---|---|
puts() | puts(字符串地址) | 向显示器输出字符串(输出完,换行) |
printf() | printf("%s", 字符串地址) | 依次输出字符串中的每个字符直到遇到字符' '(' '不会被输出) |
·字符串常用函数:
函数 | 格式 | 功能 |
---|---|---|
strlen() | strlen(字符串地址) | 计算字符串长度,返回字符串实际长度,不包括' '在内 |
strcpy () | strcpy (字符数组1,字符串2) | 将字符串2拷贝到字符数组1中去,返回字符数组1的首地址 |
strncpy () | strncpy (字符数组1, 字符串2, 长度n) | 将字符串1前n个字符的子串与字符串2前n个字符的子串进行比较 |
strcmp () | strcmp (字符串1, 字符串2) | 比较两个字符串,对两串从左向右逐个字符比较(ASCII码),直到遇到不同字符或' '为止 |
stricmp() | stricmp(字符串1, 字符串2) | 同strcmp,stricmp在比较两个字符串时不区分大小写,而strcmp则区分大小写 |
strncmp () | strncmp (字符串1, 字符串2, 长度n) | 将字符串1前n个字符的子串与字符串2前n个字符的子串进行比较 |
1.3 动态内存分配
堆区和栈区的区别
栈区(stack)函数运行时分配,函数结束时释放。由编译器自动分配释放,存放为运行函数而分配的局部变量、函数参数、返回地址等。
堆区(heap)一般由程序员分配释放,若程序员不释放,可能导致内存泄漏,内存碎片化。
栈的空间小,如果数据过大超过栈空间,程序会报错栈溢出。堆由程序员自己申请大小,最大不超过主机剩余空间。栈由系统分配,函数结束时释放。
#include<stdlib.h>//要申请动态空间要配上这个头函数
int *p=(int*)malloc(4);
int *p=(int*)malloc(sizeof(int));
类型=(强转)malloc(大小);//malloc申请的空间没有初始化,calloc申请的空间有初始化了
malloc
1.malloc()函数会向堆中申请一片连续的可用内存空间
2.若申请成功 ,,返回指向这片内存空间的指针 ,若失败 ,则会返回NULL, 所以我们在用malloc()函数开辟动态内存之后, 一定要判断函数返回值是否为NULL.
3.返回值的类型为void型, malloc()函数并不知道连续开辟的size个字节是存储什么类型数据的 ,所以需要我们自行决定 ,方法是在malloc()前加强制转 ,转化成我们所需类型 ,如: (int)malloc(sizeof(int)*n).
calloc
1.calloc()函数功能是动态分配num个大小(字节长度)为size的内存空间 .
2.若申请成功 ,,返回指向这片内存空间的指针 ,若失败 ,则会返回NULL, 所以我们在用calloc()函数开辟动态内存之后, 一定要判断函数返回值是否为NULL.
3.返回值的类型为void型, calloc()函数虽然分配num个size大小的内存空间 ,但还是不知道存储的什么类型数据 ,所以需要我们自行决定 ,方法是在calloc()前加强制转 ,转化成我们所需类型 ,如: (int)calloc(num, sizeof(int)).
与malloc()函数的区别只在于, calloc()函数会在返回地址之前将所申请的内存空间中的每个字节都初始化为0.
free
对于申请空间要有始有终,用了之后要换回去,再借不难。
在堆中申请的内存空间不会像在栈中存储的局部变量一样 ,函数调用完会自动释放内存 , 如果我们不手动释放, 直到程序运行结束才会释放, 这样就可能会造成内存泄漏, 即堆中这片内存中的数据已经不再使用, 但它一直占着这片空间, 所以当我们申请的动态内存不再使用时 ,一定要及时释放 。
不能重复释放同一块内存!!!
1.4指针数组及其应用
使用数组需要先申请较大内存存放,浪费空间
指针数组表示多个字符串,节省空间
一维指针数组定义:
类型名* 数组名[数组长度]; int*p[n];
指针数组可以相互赋值
可以间接访问操作数组元素所指向的单元内容
char* color[5]={"red","blue","yellow","green","black"}
* color是一个数组,有五个元素
* 每个元素的类型都是字符指针
* &color[0],&color[1],&color[2]···
* 一维指针数组输入
for(i=0;i<n;i++)
{
scanf("%s",color[i]);
}
* 一维指针数组输出
for(i=0;i<5;i++)
{
printf("%s",color[i]);
}
1.5二级指针
指针是一种变量,它也有自己的地址,所以它本身也是可用指针指向的对象。我们能够将指针的地址存放在还有一个指针中
int * * p;
int * q;
p=&q;
指向指针的指针
一个 * 是表示地址
两个 * * 表示值
char** p;
p = (char**)malloc(sizeof(char*) * 10);
p[0] = (char*)malloc(sizeof(char) * 10);
strcpy(p[0], "hello");
printf("%s", p[0]);
1.6行指针,列指针
行指针:
形式:int (p)[n]
含义:p为指向含n个元素的一维数组的指针变量
a[i][j]=((p+i)+j)=((p+i))[j]=p[i][j]
int a[4][5];
int*(p)[5];
p=a;
//(*p)[0]=a[0][0],(*p)[1]=a[0][1],(*(p+1))[0]=a[1][0],(*(p+1))[1]=a[1][1]
p+i:表示第i行首地址a[i]
eg.(*(p+1))[0]=a[1][0]
列指针:
int a[2][3]
形式:int* p;p=a[0]
*(p+i)表示离a[0][0]第i个位置的元素
int a[3][3],*p;
//p=a;列指针,移动指向下一个元素
p=a[0];
*(p+i):表示离a[0][0]第i个位置的元素
2.PTA实验作业
2.1求出数组中最大数和次最大数
伪代码
for i 0 to 1 do
i-<c
for b c to n-1c do
if a[b]>a[c]
b-<c
a[i]>-<a[c]
代码截图
2.2合并两个有序数组
2.2.1伪代码
让指针都指向数组最后一位
while两个数组都没有结束时 do
if a[i]>=b[j] 则a[i]-<a[k--]
else b[j]-<a[k--]
结束上述循环后
if b数组还有元素
则 b[j]-<a[k--]
end
2.2.2代码截图
2.2.3代码对比
我的代码是选择重构数组,从最后开始比较,同学的代码是从第一个数开始排列
2.3说反话
没有做出来
老师的代码