字符指针传入一个字符变量会发生什么?

#include <stdio.h>
#define N 81
void fun(char *s)
{
    char c=*s;
    for(;*(s+1);s++)
        *s=*(s+1);
    *s=c;
    *(s+1)='\0';
}
void main()
{
    char a[N];
    gets(a);
    fun(a);
    puts(a);
}

这是一道期末考试题目,主要的作用是将输入的字符串第一个字符取出来放到这串字符的末尾,我主要的疑问是这一句话char c=*s;,为什么字符变量C存储的是字符数组a中的第一个字符,而不是最后一个字符?我有这个疑问是因为在<C陷阱与缺陷>P12页中提到:有些C编译器允许在一个字符常量(以及字符串常量)中包含多个字符,二最后这个字符变量的值按照特定编译器实现中定义的方式组合得到。在Visual C++和Gcc v2.95中采取的做法是,依次用后一个字符覆盖前一个字符,最后得到的整数值即最后一个字符的整数值。我用Dev C++运行。

阅读 3.9k
4 个回答

你理解错书的内容了,书里其实指的是一种奇技淫巧,多字节字符字面量:

int t;
……
switch(t){
case 'TAG1':
……
}

32位的int可以放下4个字节ASCII。
C语言里数组名可以当做一个指针常量,s[i]就是*(s+i)。*s就是取的数组地址的一个字符。

想复杂了,书中那段描述不是说的这种场景。这里理解字符数组的逻辑顺序足够了。

上面代码的for循环把第2个字符赋给第1个位置,第3个字符赋给每个位置。。。 直到字符串结尾,自然先要把第1个位置的字符保存下来。

*(s+1)='0';这行貌似是不需要的。for循环的中止条件就是它是'0'。

void fun(char* s)的功能是这样:
保存第一个字符,从第二个字符起,全部向前移动一位,然后把第一个字符接在最后,然后加一个'\0'来结束字符串。
至于为什么不直接将第一个字符接到最后,有几个原因,直接接的话,第一个字符的内存就失去所有权了,而且这个字符串的末尾不一定有预留的空间,如果直接接到后面,可能引起内存越界。

问题:为什么字符变量C存储的是字符数组a中的第一个字符,而不是最后一个字符?
s是指向a数组的指针,s就指向了a数组的第一的元素,再将值赋给c保存,之后进行一个for循环将数组的元素进行前移,随之指针s所指向的地址也改变了,最后再将c赋值给*s,就实现了第一个字符取出来放到这串字符的末尾。@白纸无字说的也有道理。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进