我有这个:
int main()
{
char m[] = "12aa34";
for (int i = 0; m[i] != '\0'; i++)
{
//printf("%c\n", m[i]);
m[i] = m[i] + (isdigit(m[i]) ? -2 : 1);
puts(m);
printf("\n");
}
//printf("\n");
//puts(m);
return 0;
}
puts(m) output: /2aa34
/0aa34
/0ba34
/0bb34
/0bb14
/0bb12
关于puts(m)输出的第一个问题:
经过一番挖掘后我想到它与ASCII有关。是否可以说代表级别的操作?我检查了它并以某种方式与/
的结果相关联(即1
的十进制值为49 => 49 - 2 = 47
/
),然后2
为{{{ 1}}是50 => 50 - 2 = 48
,然后0
是a
97 => 97 + 1 = 98
,依此类推。
关于第一个评论b
的第二个问题:
printf
是指针的焦点吗?现在不应该更改m[]
修改字符串以给我新值而不是旧值?
答案 0 :(得分:1)
字符是整数值,从中添加/减去1
会影响整数值。如果那是你在"代表级别"的操作的意思,那么 - 是 - 这就是发生的事情。
对于ASCII字符集,'0' - 1
(即从字符1
中减去数值'0'
)是字符'/'
。请注意,虽然很多实现(编译器,库)支持ASCII,但C标准实际上并不需要它。但是,还没有任何标准化字符集,字符'0'
的数值为零。
关于你的第二个问题......首先,你的声明" m[]
是一个指针的焦点"是不正确的(事实上,这是没有意义的)。 m
是char
的数组。其次,在实际修改该字符之前,注释掉的printf
在循环的每次迭代中打印出m[i]
(数组i
中的m
个字符)。使用语句(对于循环的每次迭代)
printf("%c\n", m[i]);
m[i] = m[i] + (isdigit(m[i]) ? -2 : 1);
puts(m);
printf("\n");
有一系列固定的事件。第一个printf()
语句输出m[i]
的值,然后修改m[i]
(即m
中只有一个字符),然后puts(m)
输出整个数组{ {1}},然后输出换行符。如果您希望在第一个m
之前修改m[i]
,那么您需要再次思考。源文件中的语句顺序很重要。
答案 1 :(得分:0)
你是对的,C中字符的表示是一个数字。
就是在C,一个' char'通常是一个签名的字母'或者是一个字节数,范围是-128 .. 127.您可以为其指定字符,例如m [1] =' a',但这仍然是整数赋值。唯一的区别是它只有-128 .. 127 的范围ASCII字符集为0 .. 127,但char也可以表示负数。
如果您使用的是无符号字符,则该范围将被视为代表0..255,而127以上的字符则称为控制字符。
本声明
char m[] = "12aa34";
表示在堆栈上创建一个7字节数组,并使用对应于' 1',' 2'' a&#39的ascii字符的字节值对其进行初始化;,'一个'&#39 3'' 4'' \ 0' (NUL)
当你使用它时,唯一可以被认为是指针的是变量m本身。但是这里m存储将分配在堆栈上,而不是堆。 当您编译程序时,编译器会存储字符串" 12aa34 \ 0"在编译的代码中。当你的函数被调用时,编译的代码将通过递增堆栈指针在堆栈上分配至少7个字节,然后通过从" 12aa34"复制它们来初始化这7个字节。存储在代码中的字符串。因此,完全允许您的代码更改堆栈中m变量中的值。
如果你这样做了:
char *m = "12aa34";
然后代替m在堆栈上有7个字节的存储空间,这是字节值' 1' (49),' 2' (50)等。相反,m指的是在堆栈上分配的8个字节的位置,它是指向直接指向" 12aa34"的指针(64位存储器地址)。内存中的字符串,由编译器存储在可执行文件中,并在执行程序时加载到内存中。在这种情况下,不应该允许修改m [i],因为加载可执行代码的内存部分通常是只读的。 这在C ++中更清晰,其中' type'一个字符串文字"例子"不只是" char *",但" char const *",表示您无法修改char值。
在您的示例代码中,您的注释printf确实应该在更改之前打印每个未修改的字符。
为了帮助解决正在发生的事情,请尝试以下方法:
char *orig = ”12aa34";
char *another = "12aa34";
char m[] = "12aa34";
printf(" %p %s\n", orig,orig);
printf("%p %s\n", another, another);
printf("%p %s\n", m, m);
m[0] = 'x';
printf("%p %s\n", m, m);
你会发现,' orig'的指针和字符串值。和另一个'将是完全相同的。
而为' m'打印指针值。虽然字符串值最初会相同,但在修改之后会有所不同。
答案 2 :(得分:-2)
我并没有真正解读你的问题,但我正在努力提供帮助。
在循环中,首先修改字符串的一个字符,然后打印整个字符串stdout。因为正如你所说,那些输出字符是由ASCII字符集引起的。
char m [] = "foo";
与写作相同
char * m = "foo";
唯一的区别是,您可以在编写
时使用第一种方法初始化空字符串char m [20];
m [19] = '\0';
您将创建一个长度为20个字符的空字符串。您必须将最后一个字符设置为\ 0,以便终止字符串
使用char *方式时,您必须创建稍微不同的循环,例如:
char * ptr;
for (ptr = m; * ptr != '\0'; ptr++){
//Do something, * ptr is used to get and modify the current value
}
访问没有索引的char [],比如(只是名称)引用数组或字符串中第一个元素的指针。
我希望这是你想要的,如果没有,请告诉我。