C语言博客作业05--指针
|这个作业属于哪个班级|C语言--网络2011/2012 |
| ---- | ---- | ---- |
| 这个作业的地址 | C语言博客作业05--指针 |
| 这个作业的目标 | 学习指针相关内容|
| 姓名 | 陈佳桐 |
0.展示PTA总分(0----2)
展示关于“指针题目集”分数截图。
1.本章学习总结(3分)
整理指针主要知识点,必须包含内容有:
1.1 指针定义、指针相关运算、指针做函数参数。
每个知识点具体展开介绍。
指针定义:
指针,是一个无符号整数(unsigned int),它是一个以当前系统寻址范围为取值范围的整数。
在程序中声明一个变量并使用地址作为该变量的值,这个变量就是指针变量。
类型名 *指针变量名;
指针相关运算:
int i,*p;
p=&i; //p指向变量i或存放i的地址。
p=Null; //p指向了一个地址为0的内存,赋值给指针时代表空指针。
p=(int*)1732; //使用强制类型转换(int *),p指向地址为1732的int型变量,不常用。
将指针p所指向变量的值加1
*p=*p+1;
++*p
(*P)++
将*p的值作为表达式的值,再将指针p的值加1
*p++
*(p++)
指针赋值
int a=3,*p1,*p2; //定义整型变量指针p1和p2
p1=&a; //使指针p1指向整型变量a
p2=p1; //将p1的值赋给指针p2,p2也指向整型变量a
注意:只能将一个指针的值赋值给另一个相同类型的指针。
指针做函数参数:
将变量的地址作为函数的实参时,相应的形参就是指针。
当指针变量作为函数参数时,
1.2 字符指针
包括指针如何指向字符串、字符串相关函数及函数代码原型的理解、字符串相关函数用法(扩展课堂未介绍内容)
指针如何指向字符串:
指针如何指向字符串
char a[5] = "wolf"; //定义字符数组
char* p = a; //指针指向该数组
printf("%s", p); //输出首地址字符
printf("%s", p+n); //输出首地址之后第n-1个位置对应的地址下的字符
字符串相关函数及函数代码原型:
Strcat函数原型:
char *strcat(char *strDest, const char *strScr) //将源字符串加const,表明其为输入参数
{
char * address = strDest;
assert((strDest != NULL) && (strScr != NULL));
while(*strDest) //是while(*strDest!=’\0’)的简化形式
{
strDest++;
}
while(*strDest++ = *strScr++)
{
NULL;
}
return address;
}
Strcpy函数原型:
char *strcpy(char *strDest, const char *strScr)
{
char *address=strDest;
assert((strDest != NULL) && (strScr != NULL));
while(*strScr) //是while(*strScr != ’\0’)的简化形式;
{
*strDest++ = *strScr++;
}
*strDest = '\0';
return address;
}
3、Strcmp函数原型:
int strcmp (const char *str1,const char *str2)
{
int len = 0;
assert((str1 != '\0') && (str2 != '\0'));
while(*str1 && *str2 && (*str1 == *str2))
{
str1++;
str2++;
}
return *str1-*str2;
}
Strlen函数原型:
int strlen(const char *str)
{
int len = 0;
assert(str != NULL);
while(*str++)
{
len++;
}
return len;
}
字符串相关函数:
函数名 | 定义 | 功能 | 返回值 |
---|---|---|---|
strcmp | int strcmp(char* str1, char* str2); | 比较字符串 | 返回正值或者1;返回0;返回负值或者-1; |
strcat | char* strcat(char* str1, char* str2); | 连接字符串 | str1字符串的首地址 |
strcpy | char* strcpy(char* str1, char* str2); | 复制字符串 | str1字符串 |
strlen | int strlen(char* str1); | 求字符串长度 | 字符串长度 |
1.3 指针做函数返回值
具体格式是什么,注意事项。
具体格式:
void Change(char *p)
{
*p = 'b';
}
void main()
{
char a = 'a';
char* p = &a;
Change(p);
printf("%c\n", a); //改变a值
}
注意事项:
指针做函数返回值时应该返回地址,因为函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式####参数。
1.4 动态内存分配
为什么要动态内存分配,堆区和栈区区别。动态内存分配相关函数及用法。举例为多个字符串做动态内存要如何分配。
动态内存分配的原因:
动态的分配内存。可以做到准确分配空间大小。不浪费资源,而且也不会发生程序不断使用预先分配内存不足。
堆区和栈区:
堆区:内存由用户通过动态分配获取,并指明大小
栈区:栈区内存由系统自动分配,函数结束时释放
申请效率:栈由系统自动分配,速度较快;堆是由new分配的内存,一般速度较慢,容易导致内存碎片出现,但是使用方便。
动态内存分配函数及用法:
动态储存分配函数malloc:
函数原型:
void *malloc(unsigned size);
p=(int *)malloc(n*sizeof(int));
//
计数动态储存分配函数calloc
void *calloc(unsigned n ,unsigned size)
分配调整函数realloc()
void *realloc (void *ptr ,unsigned size)
1.5 指针数组及其应用
多个字符串用二维数组表示和用指针数组表示区别?
二维数组:存放字符
char str[i][j] = { "have","nice","day"};
指针数组:存放地址
char * str[] ={"joker","always","like","smiling"};
1.6 二级指针
指针是一种变量,它本身也是可用指针指向的对象。
一级指针表示所指向变量的首地址。
二级变量表示对应值。
int * p1;
int * * p2;
p2=&p1;
1.7 行指针、列指针
定义格式
行指针: int (*p)[n]
列指针: int *p;
主要用法
示例1:用列指针输出二维数组。
#include<stdio.h>
void main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int *p= a[0]; // 列指针的定义法
for(; p < a[0] + 12; p++)
{
printf("%d ",*p);
}
return 0;
}
示例2:用行指针输出整个二维数组。
#include<stdio.h>
void main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int (*p)[4]= &a[0]; // 行指针定义法或者int (*p)[4]= a;
int i, j;
for(i = 0; i < 3; i++)
{
for(j = 0; j < 4; j++)
{
printf("%d ",*(*(p + i) + j));
}
return 0;
}
}
2.PTA实验作业
2.1 题目名1
2.1.1 伪代码
定义 i,j,k,slen,tlen ;
char *p=NULL;
将slen赋值主串长度
将tlen赋值子串长度
for 0 to slen-1 do
j=i;
while(主串和子串出现相同)
k++;
j++;
if(k值大于等于子串长度)
将主串位置传递给p;
返回p值。
end if
k=0 //清零,开始下一轮
end while
end for
未找到,则最终返回p初值NULL
2.1.2 代码截图
2.1.3 找一份同学代码比较,说明各自代码特点。
我的代码:遍历s主串,当s主串与t子串中元素对应时,进行累加,当累加次数超出或等于t子串长度时,返回子串t在s中的首地址。如果没有,则将null输出。
同学代码:先遍历主串,如果有和子串相同,记录其在主串中坐标,在子串主串同时移动,出现不相同或者子串结束停止。
移动结束后,若子串在结束符,说明找到,返回主串位置,否则则表明未找到,子串回到首位,继续下一轮移动。
2.2 题目:合并2个有序数组。
2.2.1 伪代码
定义 i=0,j=0,k=0;
定义 新指针c进行内存动态分配,可存放下m+n个元素;
while(i+j<m+n) //未完成合并时
if(j>=n) //b数组放完,只需放a数组
then c[k++]=a[i++];
else if (i>=m) //a数组放完,只需放b数组
then c[k++]=b[j++];
//a、b数组都没放完,比较a、b数组此时需放置的元素数组大小
else if (a数组元素小于b数组)
then 放置a数组元素
else
then 放置b数组元素
end if
for from 0 to m+n-1
将排序好的c输入回a数组。
end for
2.2.2 代码截图
2.2.3 同学代码比较,说明各自代码特点。
展示同学代码:
代码特点:
同学的想法是从后往前判断,把b数组直接放入a数组。
我的想法是借用指针c,将a、b数组排好序后再放回a数组。
2.3 题目名3 说反话-加强版
2.3.1 伪代码
定义 数据数组a,指针变量p,j,flag,number,len。
fgets读取数据
for p from a+len-1 to 0 //逆向判断
do if(对应数据不是空格)
then number++ //当前单词字母数累加
else if(number不为0)
then
if(flag==1)
then flag=0 //标志可以输出
else
输出空格
end if
for j from p+1 to p+number
do 正向输出该单词
end for
number=0
end for
if(只有一个单词)
then 输出空格
end if
for j from p+1 to p+number
do 正向输出该单词
end for
2.3.2 代码截图
根据超星视频和询问同学后
数组做法
2.3.3 和超星视频做法区别,各自优缺点。
超星视频代码:使用函数封装,让主函数简单清晰,同时调试方便。
使用flag作为标志符,用if语句判断单个单词的特殊情况,但感觉还可以简化。
送懒惰的自己一句话:
It's impossible,so more worthy to be believed.
Faust 6420