关于C和 C++中 字符串用getchar()输入,以及结束标志的有关问题
关于C和 C++中 字符串用getchar()输入,以及结束标志的问题
我自己的分析:用getchar()循环的读入单个字符,第一次执行getchar()时候,我输入12345,按下enter键,这时候,标准输入流中包括换行符共有六个字符。
接下来,执行循环,每次getchar()自动的从当前流中读取一个字符,每当读取一个字符执行一次循环,直到循环结束。
这时形成了一个以str为首地址的字符串,这时候当前流的状态是'4''5''\n'。
在用cout输出的时候,它是怎么判断字符串什么时候,结束的。用strlen(str)输出长度为3,strlen()函数是以'\0'作为字符串结束标志判断字符串长度的。
我的想法哪有错吗?希望大家指正。
我想知道这个空字符到底哪儿来的????
如下:
#include <iostream>
#include <cstdio>
#include<cstring>
using namespace std;
int main()
{
char *str=new char[3];
int i=0;
while(i!=3)
{
str[i]=getchar( );
++i;
}
cout<<str<<endl;
cout<<strlen(str)<<endl;
return 0;
}

------解决思路----------------------
其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。
理解和讨论之前请先学会如何观察!
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
对学习编程者的忠告:
多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
------解决思路----------------------
内存空间是连续的,而且是很大的。不是因为你开辟的三个,就只有三个,然后就“结束了”。
你开辟的三个空间只是一个很大的内存空间中的三个位置,在它前面和后面都还有很大的内存空间。
strlen 等程序并不知道(也不可能知道)哪些空间被分配给你了,哪些没有。它只是拿到一个地址,然后一直向后处理直到遇到一个 '\0' 为止。在你开辟的三个空间之后的内存并没有分配给你,也不由你控制。你不会知道其中都有什么内容(当然如果你想读,是可以读到的。其实 strlen 就是读到了其中的内容)。但是你不知道其中的内容(并且你不能控制其中的内容)并不意味着其中没有内容(这些内容可能是有除了你的程序以外的其它程序控制的)。strlen 会一直向后读到不知道哪一个位置碰巧是 '\0' 了为止。
我自己的分析:用getchar()循环的读入单个字符,第一次执行getchar()时候,我输入12345,按下enter键,这时候,标准输入流中包括换行符共有六个字符。
接下来,执行循环,每次getchar()自动的从当前流中读取一个字符,每当读取一个字符执行一次循环,直到循环结束。
这时形成了一个以str为首地址的字符串,这时候当前流的状态是'4''5''\n'。
在用cout输出的时候,它是怎么判断字符串什么时候,结束的。用strlen(str)输出长度为3,strlen()函数是以'\0'作为字符串结束标志判断字符串长度的。
我的想法哪有错吗?希望大家指正。
我想知道这个空字符到底哪儿来的????
如下:
#include <iostream>
#include <cstdio>
#include<cstring>
using namespace std;
int main()
{
char *str=new char[3];
int i=0;
while(i!=3)
{
str[i]=getchar( );
++i;
}
cout<<str<<endl;
cout<<strlen(str)<<endl;
return 0;
}
------解决思路----------------------
其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
------解决思路----------------------
内存空间是连续的,而且是很大的。不是因为你开辟的三个,就只有三个,然后就“结束了”。
你开辟的三个空间只是一个很大的内存空间中的三个位置,在它前面和后面都还有很大的内存空间。
strlen 等程序并不知道(也不可能知道)哪些空间被分配给你了,哪些没有。它只是拿到一个地址,然后一直向后处理直到遇到一个 '\0' 为止。在你开辟的三个空间之后的内存并没有分配给你,也不由你控制。你不会知道其中都有什么内容(当然如果你想读,是可以读到的。其实 strlen 就是读到了其中的内容)。但是你不知道其中的内容(并且你不能控制其中的内容)并不意味着其中没有内容(这些内容可能是有除了你的程序以外的其它程序控制的)。strlen 会一直向后读到不知道哪一个位置碰巧是 '\0' 了为止。