倒序输出(关于指针)

这题好像有几个版本的,下面第一个是我接触到的第一个版本的

  1. 第一个版本的题目:

下面程序的运行结果是______

#include<stdio.h>
#include<string.h>
void fun(char *w,int n)
{
char t,*s1,*s2;
s1=w;s2=w+n-1;
while(s1<s2)
{
t=*s1++;
*s1=*s2--;
*s2=t;
}
}
void main()
{

char *p;
p="1234567";
fun(p,strlen(p));
puts(p);
}

A.7654321 B,1714171 C.1711717 D.7177171
猜一猜结果是多少,

选C,答对了吗,当然这题目确实有点小问题,没法运行出来,原因在主函数里:

void main()
{

char *p;//这里是定义p指向的值,这样写其实就跟int n 是一样的意思,只不过也说明p是指针
p="1234567";//p是指针,这个样子说明"1234567"是字符串常量
fun(p,strlen(p));//strlen()函数是只能用于数组的,而p是一个字符串指针,这里是一个错误,
puts(p);
}

strlen()函数头文件是#include<string.h>,是用来计算字符串数组中的字符串长度的

上面说了“123456”是字符串常量,因为字符串常量赋值给指针是合法的,但是,
要注意的是,字符串常量是不可以修改的,可是后面是将他放入了fun函数进行了修改的,就这两个错误,
怎么解决呢,可以看出这两个错误,都是因为p的类型不对的问题
好,改一下:

  1. 改了之后
#include<stdio.h>
#include<string.h>
void fun(char *w,int n)
{
    char t,*s1,*s2;
    s1=w;s2=w+n-1;
    while(s1<s2)
    {
        t=*s1++;
        *s1=*s2--;
        *s2=t;
    }
}
int main()
{
	char p[]="1234567";//只要把p改成数组的就好了,
	fun(p,strlen(p));
	puts(p);
	return 0;
}

改了错误现在再体会下结果

不得不说一涉及到指针,题目难度瞬间就拔高了,下面讲一下结果

  1. 第一版的结果

main函数里就没什么好说的了,fun需要两个值,这里是输入了数组指针p和数组p的长度

puts()就等价于printf(“%s\n”, ),

讲之前,说一下*,他是解引的,形象点,比如*p,那么他就是一个值,p指针指向地址存放的值

#include<stdio.h>
#include<string.h>
void fun(char *w,int n)
{
    char t,*s1,*s2;//两个指针,一个变量
    s1=w;//指针赋指针,把p赋给了s1,那么s1现在就指向数组p的第一位元素
    s2=w+n-1;//这里也就是s2=p+7-1,s2指向第7位元素
    while(s1<s2)
    {
        t=*s1++;//注意*的优先级是要高于++的,那么这里就是t=1, 然后指针自增指向下一个地址,也就是第二个元素
        *s1=*s2--;//这里就是第7个元素的值赋给了第二个元素,然后s2指针自减,指向上一个地址
        *s2=t;//这里把t的值赋给了第六个元素,注释说的是第一次while循环时
    }
}
int main()
{
	char p[]="1234567";
	fun(p,strlen(p));
	puts(p);
	return 0;
}

结合注释可以看出,第一个元素和第7个元素的值是没有改变的,第二个变成了7,第6个变成了1,
第二次s1为2,s2为6,符合条件继续循环,t=7,第三个变成1,第5个变成7
第三次s1为3,s2为5,符合,t=1;第四个先是在*s1=*s2–,被赋为7,但随后s2指针的自减,s2也指向了第四个,*s2=t,第四个又被赋为1,
第四次s1为4,s2为4,不符合,跳出循环,回到主函数打印
综合起来就是"1711717",也就是C

是不是感觉出来了些什么,结合这篇文章的题目,是的,这道题是一个错误倒序输出的例子,不过非常利于思考关于指针的运算,

  1. 第二版
    下面程序的运行结果___A____
#include<stdio.h>
#include<string.h>
void fun(char *w,int n)
{
    char t,*s1,*s2;
    s1=w;s2=w+n-1;
    while(s1<s2)
    {
        t=*s1;
        *s1=*s2;
        *s2=t;
        s1++;
        s2--;
    }
}
int main()
{
	char p[]="1234567";
	fun(p,strlen(p));
	puts(p);
	return 0;
}

A.7654321 B,1714171 C.1711717 D.7177171

这题答案索性就直接写了,这个就是第一版改正后的,正确的倒序输出的写法
算得上是倒序输出的模板了
讲下不同,剩下的差不多与上面差不多,就不再多讲了

#include<stdio.h>
#include<string.h>
void fun(char *w,int n)
{
    char t,*s1,*s2;
    s1=w;s2=w+n-1;
    while(s1<s2)
    {
        t=*s1;
        *s1=*s2;
        *s2=t;
        s1++;//与上面的是他把两个自增都放下面去了,这样置换就换对了
        s2--;
    }
}
int main()
{
	char p[]="1234567";
	fun(p,strlen(p));
	puts(p);
	return 0;
}

把模板提出来:

#include<stdio.h>
#include<string.h>

void fun(char *w, int n)
{
    char t, *s1, *s2;
    s1 = w;
    s2 = w + n - 1;

    while(s1 < s2)
    {
        t = *s1;
        *s1 = *s2;
        *s2 = t;
        s1++;
        s2--;
    }
}

void main()
{
    char p[100];
    scanf("%s", p);
    fun(p, strlen(p));
    puts(p);
}

以下是一个有些缺陷的倒序输出,似乎是因为没有得到数组的具体长度,指针指向空时,输出似乎不会停

#include<stdio.h>
# define M 8 //宏定义不占用运行时间,只占用编译时间,可以加快速度
int main()
{
	int a[M],i,j,t=0;
	for(i=0;i<M;i++)
	scanf("%d",a+i);
	i=0;j=M-1;//上面那循环结束后,i的值会保留,所以i=0必须写在这
	while(i<j)
	{
	    t=*(a+i);
	    *(a+i)=*(a+j);
	    *(a+j)=t;
	    i++;
	    j--;
	}
	for(i=0;i<M;i++)
	printf("%d ",*(a+i));
	return 0;
}

这个程序由于指针指向空好像也没关系,我定义的M是8,假如你只输7个元素,就会

0 7 6 5 4 3 2 1 

这基本更加确定了,就这样了,稍微拓展一下

有没有想过只取数组中部分元素从大到小输出:

下面代码是实现了a[2]到a[7]从大到小输出,其他元素不动

#include<stdio.h>
void sort(int a[],int m)
{
    int i,j,t;
    for(i=0;i<m;i++)
    {
        for(j=i+1;j<m;j++)
        {
            if(a[i]<a[j])
            {
                t=a[i];
                a[i]=a[j];
                a[j]=t;
            }
        }
    }
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	int a[n];
	getchar();
	for(int i=0;i<n;i++)
	{
	    scanf("%d",&a[i]);
	}
	sort(a+2,m);
	for(int i=0;i<n;i++)
      {
          printf("%d ",a[i]);
      }
	return 0;
}

输入:

10 5
1 2 3 4 5 6 7 8 9 10

输出:

1 2 7 6 5 4 3 8 9 10 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值