c博客作业05--指针
| 这个作业属于哪个班级 | C语言--网络2011/2012 |
| ---- | ---- | ---- |
| 这个作业的地址 | C博客作业05--指针 |
| 这个作业的目标 | 学习指针相关内容 |
|姓名|骆念念|
0.展示PTA总分(0----2)
1.本章学习总结(3分)
1.1 指针定义、指针相关运算、指针做函数参数。
指针定义
如果在程序中声明一个变量并使用地址作为该变量的值,那么这个变量就是指针变量。
定义指针变量的一般形式为:
类型名 *指针变量名
指针相关运算
1:取地址运算和间接访问运算
单目运算符&用于给出变量的地址
int *p,a=3;
p=&a;
注意:指针的类型必须和它所指的变量的类型相同;
‘’除了被用于定义指针变量外,还被用于访问指针所指的变量。就是取其内容;
指针的运算优先级
p=p+1、++p和(p)++,都是将指针p所指的变量的值加1,而表达式p++等价于(p++),先取*p的值作为表达式的值,再将指针p的值加1,运算后,p不再指向a
2:赋值运算
int a=3,*p1,*p2;
p1=&a;
p2=p1;
上面表示的是p1和p2都指向a的地址。
注意:只能将一个指针的值赋给另一个相同类型的指针
指针作函数参数
如果将某个变量的地址作为实参,那么相应的形参就是指针。数组有所不同,实参中给出数组名,形参中的数组可以有两种表示形式(int a[]相当于int a)。但是在函数中a表示的是a这个数组中的第一个元素。
1.2 字符指针
字符指针是指向字符型数据的指针变量。每个字符串在内存中都占用一段连续的存储空间,并有唯一确定的首地址。即将字符串的首地址赋值给字符指针,可让字符指针指向一个字符串。
例如:
char *p;
p="hi";
和char *p="hi";
上面都是表示p指向字符串的首地址。
1.3 指针做函数返回值
return *指针名;
用指针作为函数返回值时需要注意的一点是,函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式参数,函数返回的指针请尽量不要指向这些数据,C语言没有任何机制来保证这些数据会一直有效,它们在后续使用过程中可能会引发运行时错误。
1.4 动态内存分配
所谓动态内存分配(Dynamic Memory Allocation)就是指在程序执行的过程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不象数组等静态内存分配方法那样需要预先分配存储空间,而是由系统根据程序的需要即时分配,且分配的大小就是程序要求的大小。
malloc函数的原型为:void *malloc (unsigned int size) 其作用是在内存的动态存储区中分配一个长度为size的连续空间。其参数是一个无符号整形数,返回值是一个指向所分配的连续存储域的起始地址的指针。还有一点必须注意的是,当函数未能成功分配存储空间(如内存不足)就会返回一个NULL指针。所以在调用该函数时应该检测返回值是否为NULL并执行相应的操作。
使用前要stdlib。用完后要释放,free();
1.5 指针数组及其应用
指针数组可以作为函数的参量使用,使用方式与普通数组类似。
指针数组常适用于指向若干字符串,这样使字符串处理更加灵活方便。
应用:指针数组可以作为函数的参量使用,使用方式与普通数组类似。
指针数组常适用于指向若干字符串,这样使字符串处理更加灵活方便。
1.6 二级指针
如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针。
int a =1;
int *p1 = &a;
int **p2 = &p1;
指针变量也是一种变量,也会占用存储空间,也可以使用&获取它的地址。C语言不限制指针的级数,每增加一级指针,在定义指针变量时就得增加一个星号。p1 是一级指针,指向普通类型的数据,定义时有一个;p2 是二级指针,指向一级指针 p1,定义时有两个*。
1.7 行指针、列指针
行指针
int* a;//a是指向整形的指针;
int* a[5];//一维指针数组(这里存放着5个指向整形的指针),a指向第一个元素的地址,a+1指向第二个......(a[5]是一个指针数组);
int (a)[5];//指向数组(这里每个一维数组含5个元素)的指针,a是第一个一维数组的首元素地址,a+1指向第二个一维数组的首元素地址......(a是数组指针);
int (a)();//a是指向函数的指针(函数指针);
int *a();//函数的返回类型是int *,a只是一个函数名;
列指针
a即是它的行指针,a+0表示第0行的地址,a+1表示第1行地址…
或者可以说成&a[0]表示第0行的地址,&a[1]表示第1行的地址…
那么a[0]+0,a[0]+1…就表示第1行第1列的地址,第1行第2列地址…
a[1]+0,a[1]+1就表示第2行第1列地址,第2行第2列地址…
2.PTA实验作业(7分)
2.1 题目名1(2分)
6-2 求出数组中最大数和次最大数
2.1.1 伪代码
定义变量i,t1,t2
t1和t2用来存放a[0]和a[1]的值
for 1 to n-1
if(a[0]<a[i])
a[0]=a[i]
a[i]=t1;
for 2 to n-1
a[1]=a[i]
a[i]=t2;
2.1.2 代码截图
2.1.3 找一份同学代码(尽量找思路和自己差距较大同学代码)比较,说明各自代码特点。
不同点
我用了两个单循环,在第一个单循环中找到最大数,并与a[0]交换,在第二个循环中我从i=2开始,因为此时我已经找到最大值,只需要从a[1]开始找次最大值。我没有用指针作为返回值,所以并没有到达题目本意。曹同学用了选择排序法,不仅复习了之前的排序内容,对选择排序法融会贯通,而且使用指针作为返回值。
2.2 题目名2(2分)
6-9 合并两个有序数组
2.2.1 伪代码
2.2.2 代码截图
2.2.3 找一份同学代码(尽量找思路和自己差距较大同学代码)比较,说明各自代码特点。
汪月月同学的代码
void merge(int* a, int m, int* b, int n) /* 合并a和b到a */
{
int i, j = 0, k = 0;
int s[100000];//将数组a中的数据储存在s中
if (n != 0 && m != 0)//a与b数组均不为零个元素
{
for (i = 0; i < m; i++)
s[i] = a[i];
for (i = 0; i < m + n; i++)//i是新的a数组的下标
{/*下面比较s数组与b数组中数字大小进行排序*/
if (s[j] < b[k])
a[i] = s[j++];
else if (s[j] > b[k])
a[i] = b[k++];
else
{
a[i++] = s[j++];
a[i] = b[k++];
}
if (j == m || k == n)//当有一个数组数据存完后,就结束循环
break;
}
for (++i; i < m + n; i++)
{
if (j == m)//剩余b数组
a[i] = b[k++];
else if (k == n)//剩余a数组
a[i] = s[j++];
}
}
else if (m == 0)//如果a数组个数等于0,只需将b数组存在a中
{
for (i = 0; i < n; i++)
{
a[i] = b[i];
}
}
}
汪月月的同学的代码非常清晰,有相应的解释,看起来很清楚,用了另一个数组来存放俩个数组比较后的值。
2.3 题目名2(2分)
7-4 说反话-加强版