这题好像有几个版本的,下面第一个是我接触到的第一个版本的
- 第一个版本的题目:
下面程序的运行结果是______
#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的类型不对的问题
好,改一下:
- 改了之后
#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;
}
改了错误现在再体会下结果
不得不说一涉及到指针,题目难度瞬间就拔高了,下面讲一下结果
- 第一版的结果
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
是不是感觉出来了些什么,结合这篇文章的题目,是的,这道题是一个错误倒序输出的例子,不过非常利于思考关于指针的运算,
- 第二版
下面程序的运行结果___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