user-0 提问: 读取、逆向输出英文句子（二维数组存储）遇到的问题

回复:
user: user-0
content: 谢谢小灸舞版主以及user-2版主。 十分感谢你们。 明天中秋佳节，大家节日快乐。

user: user-1
content: 1.指针数组中的每个元素都是一个指针，而每个指针指向各自的字符串 相当于你存了很多个字符串（类似二维数组，但和二维稍有区别，每个字符串占据的空间可以不同） 2.可以不添，因为scanf(" %s", sentence[i]);会自动帮你补上'\0' 3.scanf(" %s", sentence[i]);是不能读入回车符的. strlen是以读到'\0'来计算字符串长度的，“abcdef\n"是7和不能读入回车符并没有什么关系 4.可以啊 5.动态分配好处很多，1.动态分配的空间都是在堆上的，空间够大（相比于栈） 2.可能需要根据某些变量才能分配空间（可以省空间）

user: user-0
content: 释放内存和置空用以下的方法合适吗？ free(*sentence); *sentence = NULL; 编译无error、warning，可是不能理解。 或者使用循环来一个个释放和置空

user: user-0
content: @小灸舞 版主，麻烦你再看看啦！ 我重新改了一下，不过还是有一些迷惑的地方，代码后面注释有“问题n：”的是有疑惑的地方，疑惑在最后 #include <stdio.h> #include <string.h> #include <stdlib.h>  #define LENGTH_WORD 20 #define COUNT_WORDS 30   int main(void) {     char *sentence[COUNT_WORDS], ch, punctuation;     //问题1：     int i, len, j;      printf("Enter a sentence: ");     for (i = 0; i < COUNT_WORDS; i++) {         sentence[i] = (char *)malloc(LENGTH_WORD * sizeof(char));         if (sentence[i] == NULL) {             printf("allocation failed“)             exit(1);         }         scanf(" %s", sentence[i]);         ch = getchar();         len = strlen(sentence[i]);         sentence[i][len] = '\0';  //问题2：         if (ch == '\n') {  //问题3：             if (sentence[i][len - 1] == '.'     ||                 sentence[i][len - 1] == '\?'    ||                 sentence[i][len - 1] == '!'                 ) {                 //问题4：                 punctuation = sentence[i][len - 1];                 sentence[i][len - 1] = '\0';             }   //second-if             break;         }   //first-if     }   //for      for ( ; i > 0; i--)         printf("%s ", sentence[i]);     printf("%s%c", sentence[0], punctuation);      return 0; } 问题1：在这里我声明的是指针数组，是一维的？我知道可以把二维数组当成一维数组处理，但是我声明的时候本意是需要二维数组，还是一维数组（这莫非是把一维数组当二维数组用？） 问题2：这里需要添加'\0'吗？ 问题3：在这里我尝试过if(sentence[i][len - 1] == '\n')但是循环没有在我输入换行符的时候跳出，这是说明在最后的换行符不能储存到字符串中吗？可是“abcdef\n"的字符长度还是7啊 问题4：在判断条件中使用sentence[i][len-1] == '.'&&'\?'&&'!'这种做法怎么样（经测试，结果是正确，有没有隐藏的缺陷） 问题5：“动态分配数组”是指动态分配数组元素的个数？可是这样的作用是什么？为了将声明了但没有初始化的数组元素占据的内存释放？ 例子： 声明但没有初始化： int a[20], i; for (i = 0; i < 10; i++)     a[i] = i; 声明了也初始化了： int a[20] = {0}, i; for (i = 0; i < 10; i++)     a[i] = i;  谢谢啦！

user: user-1
content: (*sentence)[COUNT_WORDS]这样写表示的是数组指针      表示：指向数组sentence的指针  而你需要的是存放多个字符串的指针数组（指针数组的每个元素都是一个指针）  你可以网上搜搜资料，看下概念。 http://www.cnblogs.com/Romi/archive/2012/01/10/2317898.html

user: user-0
content: @小灸舞 版主 确实不是很理解，现在在跟着《c语言程序设计-现代方法》自学。  还有一个问题，关于“指针数组”和“指向指针的数组”问题，那既然是指向字符串指针的数组，那这里是不是要这样用 (*sentence)[COUNT_WORDS]  其他的等我再找找资料和看一下“指针的高级应用”这章，有不懂的再请教各位啦。 谢谢大家，溢出节快乐啊！

user: user-1
content: 1.你的scanf,strlen,puts都不需要取地址，sentence[i]本身就是个指针 2.你需要为每个元素都malloc空间（感觉楼主没有很好理解指针数组的概念） 3.最后多puts了一个元素  #include <stdio.h> #include <string.h> #include <stdlib.h> #define LENGTH_WORD 20 #define COUNT_WORDS 3   int main() { 	char *sentence[COUNT_WORDS], ch; 	int i, len, j;  	printf("Enter a sentence: "); 	for (i = 0; i < COUNT_WORDS; i++) { 		sentence[i] = (char *)malloc(sizeof(char)* LENGTH_WORD); 		scanf(" %s", sentence[i]); 		len = strlen(sentence[i]); 		printf("i: %d;len: %d\n", i, len); 		//用来检验字符串长度，显示是正确的，但输出时出现奇怪的错误 	}  	printf("\n"); 	puts(sentence[0]); 	puts(sentence[1]); 	puts(sentence[2]); 	//puts(sentence[3]); }

user: user-0
content: 谢谢！ 翻了翻书，看到后面还有一章讲“指针的高级应用”，我先看看书先，如果还是不能解决再请教，所以先不结帖。 还有，溢出节快乐！

user: user-2
content: 其他问题没细看，如果有不明白，给出问题说明与你输入的内容

user: user-2
content: 方法一中：红色S去掉  char sentence[COUNT_WORDS][LENGTH_WORDS + 1] = {0}, ch, punctuation;

user: user-2
content: 方法二使用指针奨要先为指针分配内存