C-for条件下的字符串与数组

C-for条件下的字符串与数组,c,arrays,string,C,Arrays,String,今天我试图用C语言编写一个简单的“程序”,我想做以下工作:当你输入大写字符串时,程序会将所有字符转换成小写。但我好奇得发呆 char uppword[26]; int i; printf("Gimme a word in uppercase.: "); scanf("%s", uppword); for (i=0; i < uppword[i]; i++){ uppword[i] = uppword[i] + 32; } printf("%s", uppword); retur

今天我试图用C语言编写一个简单的“程序”,我想做以下工作:当你输入大写字符串时,程序会将所有字符转换成小写。但我好奇得发呆

char uppword[26];
int i;
printf("Gimme a word in uppercase.: ");
scanf("%s", uppword);
for (i=0; i < uppword[i]; i++){
    uppword[i] = uppword[i] + 32;
}

printf("%s", uppword);

return 0;
char-upword[26];
int i;
printf(“给我一个大写的单词:”;
scanf(“%s”,upword);
for(i=0;i

正如您所看到的,for循环中有一个条件
i
,但我不知道这是为什么。换句话说,我可以用
i
替换这个条件,它也可以工作。但我不认为这和数组是一样的。为什么这个阵列可以工作?数组中的“i”位于开头0,因此条件为非真,无法继续

uppword[i]
将在字符串末尾为0(
scanf
为您执行此操作,除非您尝试读取过多字符,否则编译器可能会吃掉您的猫)<代码>i<0
在该点将为0。根据某些假设,仅在该点为0:这些假设是(i)
uppword
最多包含32个字符(您允许25个字符加上nul终止符),以及(ii)在ASCII中,至少您通常不会遇到少于32个字符(因为它们是控制集)

聪明,如果读起来有点难的话

智能亚历克程序员也可能要考虑这个代码假定ASCII编码的事实,因此不是可移植的C.


考虑改用
strlen
,但要预先计算:不要把它作为循环条件,因为你会将一个O(N)进程转换成一个O(N*N)进程-只有来自神的编译器才会知道
strlen
在迭代之间不会改变,因为你的循环体会改变字符串。

upword[i]
之所以有效,是因为当
i
较小时,它指的是使用ASCII格式化的字符串,因为ASCII中的'A'总是大于
26
,数组
upword[26]

i
不断增加直到
uppword[i]
指向字符串的空终止字符时,条件将为false,因为
i
必须大于0(空字符)。因此,它将离开循环

这意味着该循环将在到达空字符时停止

数组中的“i”位于开头0,因此条件为非真,无法继续

条件是检查
i
是否小于
upford[i]
;在开始时,您要检查
0
是否小于
upford[0]
,这几乎肯定是正确的

假设您输入字符串
“Hello”
。在
upword
中存储的是字符序列
{'H','e','l','l','o',0}
。每次通过循环,您都要进行以下比较:

0 < 'H' (72)  true
1 < 'e' (101) true
2 < 'l' (108) true
3 < 'l' (108) true
4 < 'o' (111) true
5 < 0         false
0<'H'(72)正确
1<'e'(101)正确
2<'l'(108)正确
3<'l'(108)正确
4<'o'(111)正确
5<0假
循环将在命中0终止符时退出,因为0不会大于索引值。正如Bathsheba所说,此代码假定字符串永远不包含任何控制字符

如前所述,这不是一个好代码——它对底层字符集进行了各种假设,不清楚,也不安全。更好的版本应该是这样的

#include <ctype.h>
...
scanf( "%25s", upword );  // use an explicit field with modifier so that
                          // we don't try to store more characters than
                          // upword is sized to hold.  Leave room for trailing 0

for ( char *p = upword; *p != 0; p++ )
  *p = toupper( *p );
#包括
...
scanf(“%25s”,向上);//使用带修饰符的显式字段,以便
//我们不会尝试存储超过个字符的字符
//上风的大小可以容纳。为后面的0留出空间
对于(char*p=upford;*p!=0;p++)
*p=最大值(*p);

此代码使用指针
p
遍历字符串,并循环直到看到
0
字符串终止符。它还使用
toupper
库函数,a)考虑当前字符编码(ASCII、EBCDIC等),b)如果没有可用的大写等效字符(例如标点符号),则返回原始字符

我同意你的观点,这就是原因,但为什么循环中没有崩溃??何时达到离开循环的条件?计算最后一个字符时会发生什么情况??它将尝试访问uppword中不存在的字符循环在到达
uppword
中的nul terimator时结束。啊,好的,它会自动附加nul字符。YC没有字符串类型。