c语言入门经典(第4版)例题7.13题,红线的部分想了两天一直不清楚
以下为全部代码
/* Program 7.13 Generalizing string input */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const size_t BUFFER_LEN = 128; /* Length of input buffer */
const size_t NUM_P = 100; /* maximum number of strings */
int main(void)
{
char buffer[BUFFER_LEN]; /* Input buffer */
char *pS[NUM_P] = { NULL }; /* Array of string pointers */
char *pbuffer = buffer; /* Pointer to buffer */
int i = 0; /* Loop counter */
printf(“\nYou can enter up to %u messages each up to %u characters.”,
NUM_P, BUFFER_LEN-1);
for(i = 0 ; i<NUM_P ; i++)
{
pbuffer = buffer ; /* Set pointer to beginning of buffer */
printf(“\nEnter %s message, or press Enter to end\n”,
i>0? “another” : “a”);
/* Read a string of up to BUFFER_LEN characters */
while((pbuffer – buffer < BUFFER_LEN-1) &&
((*pbuffer++ = getchar()) != “\n”));
/* check for empty line indicating end of input */
if((pbuffer – buffer) < 2)
break;
/* Check for string too long */
if((pbuffer – buffer) == BUFFER_LEN && *(pbuffer-1)!= “\n”)
{
printf(“String too long – maximum %d characters allowed.”,
BUFFER_LEN);
i–;
continue;
}
*(pbuffer – 1) = “\0”; /* Add terminator */
pS[i] = (char*)malloc(pbuffer-buffer); /* Get memory for string */
if(pS[i] == NULL)
{
printf(“\nOut of memory – ending program.”);
return 1;
}
/* Copy string from buffer to new memory */
strcpy(pS[i], buffer);
}
/* Output all the strings */
printf(“\nIn reverse order, the strings you entered are:\n”);
while(–i >= 0)
{
printf(“\n%s”, pS[i] ); /* Display strings last to first */
free(pS[i]); /* Release the memory we got */
pS[i] = NULL; /* Set pointer back to NULL for safety */
}
return 0;
}
问题如下:
1、问一下这一段
if((pbuffer – buffer) == BUFFER_LEN && *(pbuffer-1)!= “\n”)
{
printf(“String too long – maximum %d characters allowed.”, BUFFER_LEN);
i–;
continue;
}
*(pbuffer – 1) = “\0”;
为什么判断pbuffer – buffer能否等于BUFFER_LEN,而不是BUFFER_LEN – 1?
while((pbuffer – buffer < BUFFER_LEN-1) && ((*pbuffer++ = getchar()) != “\n”));这个语句当pbuffer – buffer == BUFFER_LEN-1时已经结束while循环,那pbuffer – buffer又怎么可能会等于BUFFER_LEN。
2、while((pbuffer – buffer < BUFFER_LEN-1) && ((*pbuffer++ = getchar()) != “\n”));能否等价于
for(; ; )
{
*pbuffer++ = getchar();
if(*(pbuffer – 1) == “\n”)
break;
if(pbuffer – buffer >= BUFFER_LEN-1)
break;
}
3、printf()那一句为什么最大字符数是BUFFER_LEN?字符数组字节长度都是包括了”\0″终止符的啊,最大长度应该是BUFFER_LEN – 1吧?前面的语句printf(“\nYou can enter up to %u messages each up to %u characters.”, NUM_P, BUFFER_LEN-1);不是说每个字符串最多BUFFER_LEN – 1的字符?
4、 *(pbuffer – 1) = “\0”;这一语句,假充BUFFER_LEN = 5,NUM_P = 3,假如本人输入abcd然后回车,输出字符串结果为abc,问一下这是为什么啊?
以下为全部代码
/* Program 7.13 Generalizing string input */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const size_t BUFFER_LEN = 128; /* Length of input buffer */
const size_t NUM_P = 100; /* maximum number of strings */
int main(void)
{
char buffer[BUFFER_LEN]; /* Input buffer */
char *pS[NUM_P] = { NULL }; /* Array of string pointers */
char *pbuffer = buffer; /* Pointer to buffer */
int i = 0; /* Loop counter */
printf(“\nYou can enter up to %u messages each up to %u characters.”,
NUM_P, BUFFER_LEN-1);
for(i = 0 ; i<NUM_P ; i++)
{
pbuffer = buffer ; /* Set pointer to beginning of buffer */
printf(“\nEnter %s message, or press Enter to end\n”,
i>0? “another” : “a”);
/* Read a string of up to BUFFER_LEN characters */
while((pbuffer – buffer < BUFFER_LEN-1) &&
((*pbuffer++ = getchar()) != “\n”));
/* check for empty line indicating end of input */
if((pbuffer – buffer) < 2)
break;
/* Check for string too long */
if((pbuffer – buffer) == BUFFER_LEN && *(pbuffer-1)!= “\n”)
{
printf(“String too long – maximum %d characters allowed.”,
BUFFER_LEN);
i–;
continue;
}
*(pbuffer – 1) = “\0”; /* Add terminator */
pS[i] = (char*)malloc(pbuffer-buffer); /* Get memory for string */
if(pS[i] == NULL)
{
printf(“\nOut of memory – ending program.”);
return 1;
}
/* Copy string from buffer to new memory */
strcpy(pS[i], buffer);
}
/* Output all the strings */
printf(“\nIn reverse order, the strings you entered are:\n”);
while(–i >= 0)
{
printf(“\n%s”, pS[i] ); /* Display strings last to first */
free(pS[i]); /* Release the memory we got */
pS[i] = NULL; /* Set pointer back to NULL for safety */
}
return 0;
}
问题如下:
1、问一下这一段
if((pbuffer – buffer) == BUFFER_LEN && *(pbuffer-1)!= “\n”)
{
printf(“String too long – maximum %d characters allowed.”, BUFFER_LEN);
i–;
continue;
}
*(pbuffer – 1) = “\0”;
为什么判断pbuffer – buffer能否等于BUFFER_LEN,而不是BUFFER_LEN – 1?
while((pbuffer – buffer < BUFFER_LEN-1) && ((*pbuffer++ = getchar()) != “\n”));这个语句当pbuffer – buffer == BUFFER_LEN-1时已经结束while循环,那pbuffer – buffer又怎么可能会等于BUFFER_LEN。
2、while((pbuffer – buffer < BUFFER_LEN-1) && ((*pbuffer++ = getchar()) != “\n”));能否等价于
for(; ; )
{
*pbuffer++ = getchar();
if(*(pbuffer – 1) == “\n”)
break;
if(pbuffer – buffer >= BUFFER_LEN-1)
break;
}
3、printf()那一句为什么最大字符数是BUFFER_LEN?字符数组字节长度都是包括了”\0″终止符的啊,最大长度应该是BUFFER_LEN – 1吧?前面的语句printf(“\nYou can enter up to %u messages each up to %u characters.”, NUM_P, BUFFER_LEN-1);不是说每个字符串最多BUFFER_LEN – 1的字符?
4、 *(pbuffer – 1) = “\0”;这一语句,假充BUFFER_LEN = 5,NUM_P = 3,假如本人输入abcd然后回车,输出字符串结果为abc,问一下这是为什么啊?
解决方案
40
问题1,原因是上面的循环在输入为\n时结束,此时pBuffer还会自加1,所以已经指向了下一个字符
40
问题2,不等于
前者在&&前半部分为假时则不会执行后半部分
而后者总会至少执行一次getchar
前者在&&前半部分为假时则不会执行后半部分
而后者总会至少执行一次getchar
40
buffer是数组首地址,pbuffer初次等于buffer,你可以想象一格一格(表示内存空间)的作文纸,buffer表示起始格(buffer[0])地址,后面一格是buffer[1],最后一格是buffer[BUFFER_LEN-1],这BUFFER_LEN格是连续排列的。pbuffer首先指向buffer[0],pbuffer++可以使pbuffer指向下一格(即buffer[1]),假如pbuffer指向buffer[3](第3格),pbuffer-buffer==3(就是第3格与起始格第0格的距离),pbuffer-buffer==BUFFER_LEN-1表示pbuffer指向最后一格了,pbuffer-buffer<BUFFER_LEN-1表示pbuffer还没到最后一格,然后*pbuffer = getchar()读一个字符存入 pbuffer指向的格,然后pbuffer++指向下一格,然后判断刚才读入的那格字符是不是”\n”回车符,假如pbuffer还没到最后一格而且读入的不是回车字符,
while((pbuffer – buffer < BUFFER_LEN-1) &&((*pbuffer++ = getchar()) != “\n”));
语句是反复执行的(后面有一个;号表示空语句),直到条件不满足(到达了最后一格,或读入了回车符)。
while((pbuffer – buffer < BUFFER_LEN-1) &&((*pbuffer++ = getchar()) != “\n”));
语句是反复执行的(后面有一个;号表示空语句),直到条件不满足(到达了最后一格,或读入了回车符)。