我有一个像这样的简单程序:
#include <stdio.h>
int main(void)
{
int numbers[] = {1, 2, 3, 4, 5};
char chars[] = {'a', 'i'};
char name[] = "Max";
name[1] = chars[1];
printf("name (before) = %s\n", name);
name[1] = numbers[1];
printf("name (after) = %s\n", name);
return 0;
}
编译并运行:
$ gcc -std=c11 -pedantic -Wall -Werror ex8_simple.c $ ./a.out $ name (before) = Mix $ name (after) = Mx
这不是我想要的。然后我挖出问题Store an integer value in a character array in C并改变了这个程序:
name[1] = '0' + numbers[1]; //replacing >> name[1] = numbers[1];
然后它按照我的期望工作:
$ gcc -std=c11 -pedantic -Wall -Werror ex8_simple.c $ ./a.out $ name (before) = Mix $ name (after) = M2x
我不明白发生在幕后的事情,特别是没有'0' + …
的版本真的很奇怪。为什么字符串被截断?#34;怪异&#34;通往Mx
的方式?
供参考,这是exercise 8 of Learn C The Hard Way的简化版本。
答案 0 :(得分:8)
每个符号都有一个数字表示,所以基本上每个字符都是一个数字。这是字符及其值的表格。
http://www.asciitable.com/index/asciifull.gif
因此,在您的代码 05-04 08:01:33.850 23385-23454/? E/dalvikvm﹕ Could not find class 'android.app.AppOpsManager', referenced from method com.google.android.gms.common.ff.a
05-04 08:01:33.880 23385-23454/? E/dalvikvm﹕ Could not find class 'android.app.Notification$Builder', referenced from method com.google.android.gms.common.ff.b
05-04 08:01:36.010 10233-23463/? E/TalkProvider﹕ replaceContactWithContactId: contactId==0!!! pablogarces123@gmail.com, acct=1
05-04 08:01:36.010 10233-23463/? E/TalkProvider﹕ insert presence failed for account=1 username=pablogarces123@gmail.com client_type=2 status= cap=0 priority=0 mode=3
05-04 08:01:36.090 10233-23463/? E/TalkProvider﹕ replaceContactWithContactId: contactId==0!!! pablogarces123@gmail.com, acct=1
05-04 08:01:36.090 10233-23463/? E/TalkProvider﹕ insert presence failed for account=1 username=pablogarces123@gmail.com client_type=2 status= cap=0 priority=0 mode=3
05-04 08:01:37.469 23385-23466/? E/dalvikvm﹕ Could not find class 'android.os.UserManager', referenced from method com.google.android.gms.common.util.a.b
05-04 08:01:37.469 23385-23466/? E/dalvikvm﹕ Could not find class 'android.os.UserManager', referenced from method com.google.android.gms.common.util.a.c
05-04 08:01:37.469 23385-23466/? E/dalvikvm﹕ Could not find class 'android.os.UserManager', referenced from method com.google.android.gms.common.util.a.e
05-04 08:01:37.499 23223-23241/? E/﹕ statfs /mnt/secure/asec failed, errno: 13
05-04 08:01:40.499 23223-23233/? E/﹕ statfs /mnt/secure/asec failed, errno: 13
05-04 08:01:49.679 10207-10207/? E/Launcher﹕ setWindowOpaque()
05-04 08:01:49.729 10207-10207/? E/Launcher﹕ MTP-LAUNCHER: media scanning not yet finished.
05-04 08:01:57.119 10079-23504/? E/PlayerDriver﹕ Creating Non-Tunnel mode playback - uncompressed MIO
05-04 08:01:57.159 10079-23506/? E/PlayerDriver﹕ Creating Non-Tunnel mode playback - uncompressed MIO
05-04 08:01:57.179 10079-23508/? E/PlayerDriver﹕ Creating Non-Tunnel mode playback - uncompressed MIO
05-04 08:01:57.199 10079-23510/? E/PlayerDriver﹕ Creating Non-Tunnel mode playback - uncompressed MIO
05-04 08:01:57.219 10079-23512/? E/PlayerDriver﹕ Creating Non-Tunnel mode playback - uncompressed MIO
05-04 08:01:57.239 10079-23514/? E/PlayerDriver﹕ Creating Non-Tunnel mode playback - uncompressed MIO
05-04 08:02:04.759 23530-23530/? E/dalvikvm﹕ Could not find class 'android.database.sqlite.SQLiteCantOpenDatabaseException', referenced from method com.google.android.gms.plus.provider.PlusProvider.a
05-04 08:02:15.619 10233-10233/? E/AuthorizationBluetoothService﹕ Proximity feature is not enabled.
05-04 08:02:16.169 23602-23602/? E/dalvikvm﹕ Could not find class 'android.database.sqlite.SQLiteCantOpenDatabaseException', referenced from method com.google.android.gms.plus.provider.PlusProvider.a
05-04 08:02:17.359 10233-10233/? E/AuthorizationBluetoothService﹕ Proximity feature is not enabled.
05-04 08:02:25.849 23551-23551/? E/Finsky﹕ [1] InstallerTask.requireInternalStorageOrCancel: Cancel download of com.google.android.gms because insufficient free space
05-04 08:03:25.599 23641-23641/? E/dalvikvm﹕ Could not find class 'android.database.sqlite.SQLiteCantOpenDatabaseException', referenced from method com.google.android.gms.plus.provider.PlusProvider.a
05-04 08:03:26.139 10233-10233/? E/AuthorizationBluetoothService﹕ Proximity feature is not enabled.
05-04 08:03:26.759 23641-23656/? E/dalvikvm﹕ Could not find class 'android.app.AppOpsManager', referenced from method com.google.android.gms.common.ff.a
05-04 08:03:26.759 23641-23656/? E/dalvikvm﹕ Could not find class 'android.app.Notification$Builder', referenced from method com.google.android.gms.common.ff.b
05-04 08:03:27.959 23641-23656/? E/dalvikvm﹕ Could not find class 'android.security.KeyPairGeneratorSpec$Builder', referenced from method com.google.android.gms.auth.e.a.a
05-04 08:03:30.809 23641-23664/? E/dalvikvm﹕ Could not find class 'android.os.UserManager', referenced from method com.google.android.gms.common.util.a.b
中,您将name[1] = numbers[1];
分配给name[1]
,它等于上面ASCII表中的符号2
,这不是可打印的字符,这就是你输出错误的原因。
当您向STX
添加'0'
时,它等于name[1]
,因此编号为add 48 to 2
的符号为50
,即&#39 ;为什么你得到正确的输出。
答案 1 :(得分:4)
这不是我想要的。
但是,您只为此编写了代码。让我解释一下这个场景。
如果是
name[1] = chars[1];
name[1]
或a
已被chars[1]
或i
取代。所以,o / p是Mix
。
如果是
name[1] = numbers[1];
name[1]
或a
被替换为numbers[1]
或2,(不是'2'
),这是不可打印的。(#note)因此,输出为Mx
。
然而,在你的第二种方法中,
name[1] = '0' + numbers[1];
您通过添加'2'
来存储ASCII等效值'0'
。因此,该打印在输出中包含character
'2'
的表示。
替代方法:
如果您修改yout int
数组以存储数字char
的{{1}}表示的十进制等值,那么您不需要添加0-9
,像
'0'
和
int numbers[] = {'1', '2', '3', '4', '5'};
会给你所需的o / p。
建议:请记住,name[1] = numbers[1];
中的数组索引基于C
。
#注意:请参阅此ASCII table以供参考。
答案 2 :(得分:2)
在这一行:name[1] = numbers[1];
中,您要为int
分配char name[1]
值,以便将numbers[1]
中的int值视为某些char的Ascii代码,并且该char存储在name[1]
中。
执行name[1] = '0' + numbers[1];
时,数字(2)会添加到数字0
的ascii代码中,因此您可以获得实际数字。 0
的ascii代码为48,为其添加2,得到50
,这是2
的ascii代码。
以前,当您仅分配name[1] = numbers[1];
而没有0
时,会打印带有ascii代码0
的字符。因为它不是一个正确的可打印字符,所以没有显示任何内容(在我的机器中它显示为一些奇怪的表情符号)。