getchar与putchar缓冲区以及字符串数组、指针

getcharputchar缓冲区

有下面的语句段:

while ((s = getchar()) != '\n'){
        putchar(s);
        putchar("\n");
    }

这个while循环是怎么工作的呢?
首先getchar在数据缓冲区里读数据进来,这个读取数据是一个个读的,循环依次判断读进来的字符是不是为换行符,是的话就跳出循环,不是就打印出该字符。其实在getchar读取字符之前,通过键盘输入的字符已经通过stdin流全部存入了缓冲区中,getchar只在用户输入了换行符时才会去读取缓冲区里的数据。

C字符串数组与指针

在C中字符串实质上是最后一个元素为空字符的char数组,而我们知道数组与指针是有关联的。声明一个字符串有以下两种方式:

char *string1 = "foo";
//通过指针声明,string1其实是指向"foo"这个字符串第一个char字符'f'的地址
char string2[4] = "foo";
//通过char数组生明字符串,string2是一个数组

这两种声明方式有一点不同,就是数组名string2是个常量,而指针名string1是一个量。数组形式的string[4]是计算机内存中分配的用于存储四个字符‘f‘,‘o‘,‘o‘,‘o‘,‘\0‘string2既是数组名,也是首个字符string[0]的地址,string2的值不能更改,可以通过string2+1来访问第二个字符‘o‘,但不能这样用:++string2,C中规定++自增符号只能用于变量,string2这里显然是个常量,它的值是该数组首个元素的地址。对于string1形式,C Primer Plus中这样说:

指针形式(也就是我们这里的string1)会在静态存储区为字符串预留4个元素的空间(最后一个存储空间用来放‘\0‘)。一旦程序开始执行,还要为指针变量string1另外预留一个存储位置,以在该指针变量中存储字符串地址。这个变量初始时指向字符串的第一个字符,但是它的值是可以改变的。因此,可以对它使用增量运算符(例++string1将指向第二个字符‘o‘)。总之数组形式的字符串初始化是从静态存储区把一个字符串赋值给数组,而指针初始化只是复制字符串的地址。

这里我们就很清楚了两种形式的不同。一般推荐用数组来定义字符串,因为用指针形式定义字符串时,若是修改了指针指向的字符串某个字符可能会导致所有使用该地址字符的值发生变化,这和编译器的实现方式有关。
在访问字符串,例如puts时,不管是数组形式还是指针形式,会一直打印字符知道碰到空字符才结束。

字符串数组

考虑到一下形式定义:

char (*list)[2] ={"a","b"};//1
const char *multiple_strings[3] = {//2
    "I love you",
    "You are beautiful",
    "You makes me happy"};

你会发现1处会报警告:Incompatible pointer types initializing ‘char (*)[2]‘ with an expression of type ‘char [2]‘; take the address with &因为此处声明的list是一个指向由两个字符构成的元素的元素的地址,而"a"是一个字符串,并不是个字符,因此我们得把"a"改成‘a‘。其实这样也是错误的,我们声明list是个指针,指向一个二维数组的第一个元素,那么就不要用一整个二维数组类型去初始化它,最好这样:

char (*list)[2] = {'a','b'};
char test[2][2] = {{'a','b'},{'b','c'}};
list = test;

这样不会有任何警告。
再看注释2处什么意思呢?这其实定义了一个字符串数组,但是这是一个一位数组,而不是二维数组(我们知道二维数组指针形式声明并不是这样的),数组里面的每个元素都是一个char类型元素的地址,每个元素都是对应字符串第一个字符的地址,也就有下列关系成立:
*multiple_strings[0] == ‘I‘; *multiple_strings == ‘Y‘。对指针进行数组式操作在这里也是成立的:
multiple_strings[1][2]就对应的就是第二个字符串You中的‘u‘
关于这部分的详细知识可以参见C Primer Plus的第十一章关于字符串数组的部分。
总结:

声明一个数组将为数据分配存储空间;而生明一个指针只为一个地址分配存储空间。

原文地址:https://www.cnblogs.com/bobliao/p/9916846.html

时间: 2024-11-10 20:20:44

getchar与putchar缓冲区以及字符串数组、指针的相关文章

C语言中的字符串数组 指针

1.字符串 用“”引起来的内容,就是字符串. 在C语言中有没有专门的字符串的变量?  没有 所以我们使用字符数组来存储字符串.(把字符串的每一个字符存储到字符数组的每一个元素中,并且会多存放一个‘\0’) '\0' 字符串的结束标记,ascII码表中值是 0 对应的字符.NUT,NULL 2.字符数组 1)定义 char 数祖名[长度]; char str[200]; 表示定义一个长度为200的字符数组,如果用来存储字符串,则字符串的最大长度是199,留出一个给'\0' char str[3]=

C语言学习---day1(字符串数组,指针)

C语言中没有和JAVA中一样的String类型,因此,在C语言中,通过使用字符数组来保存字符串,为了和普通的字符数组区分,我们需要在字符串的尾部添加 一个结束标志:'\0',因此,例如字符串:"bht",那么保存这个字符串的字符数组长度为4. 字符串的初始化: 1 char a[4]={'b','b','t','\0'}; 2 3 char b[4]; 4 b[0]='b'; 5 b[1]='h'....... 6 7 char c[]="bht"; 如果使用第7行

C++ delete []p 数组指针,如何知道该数组大小的

本来只是一时兴起,想动手整整大学学的很渣的C++,可是一段小小的代码缺牵扯出一堆问题来,好有趣. 来看一段代码: void main() { char p[6]; char *buf = new char[4]; strcpy(buf,"012356789");//这里越界不会报错 strcpy(p,"Hello"); //若此处越界立即报错 cout<<p<<endl; cout<<buf<<endl; delete

C++ 一维数组 二维数组 指针

1.int a[3] = {1, 2, 3}a代表数组的首地址&a[0]也是数组的首地址 2.// int a[2][2] = {0, 1, 2, 3}; // **a 就是 a[0][0] 第一行第一列.// *(*a + 1) 就是 a[0][1] 第一行第二列.// **(a + 1) 就是 a[1][0] 第二行第一列.// *(*(a + 1) + 1) 就是 a[1][1] 第二行第二列. 3.int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9

第四章 数组,字符串和指针

数组 数组若没有指定初始值则为内存遗留值 如果指定了部分初始值,那么其余部分也默认被指定为0: long data[100]={0};          //给data数组的所有元素赋0 字符串是附加有特殊字符(/0)的字符序列 数组的填充: char president[]="thank you"; wchar_t president[]=L"thank you";     //Unicode字符串 const int max=80; char name[max]

C++ 字符串指针与字符串数组

在做面试100题中第21题时,发现char *astr="abcdefghijk\0";和char astr[]={"abcdefghijk"};有点区别,以前一直以为是一样的,但是在该程序中采用字符串指针运行一直出错.后来在网上查查,果然发现大大的不同. 展示如何出错 分析:当你需要修改字符串时,采用指针指向该字符串编译通过但是运行出错,而采用字符串数组时不会出现这样的问题.我们知道计算机有堆栈空间供编程人员使用,第一行,astr为栈上分配的一个指针,而右边在堆上

golang 数据一 &nbsp; (字符串、数组和数组指针)

从如下几个方面介绍GO语言的数据 1. 字符串 2. 数组 3. 切片 4. 字典 5. 结构 字符串 Go语言中的字符串是由一组不可变的字节(byte)序列组成从源码文件中看出其本身是一个复合结构 string.go  type stringStruct struct {     str unsafe.Pointer         len int } 字符串中的每个字节都是以UTF-8编码存储的Unicode字符字符串的头部指针指向字节数组的开始但是没有NULL或'\0'结尾标志. 表示方式

指针 指针与数组 指针与字符串 指针与函数 结构体与指针 宏

指针 指针与数组 指针与字符串 指针与函数?? 指针与数组 1.数组名:数组元素首地址 eg: int array[3]={1,3,6}; 这里array 恒等于&array[0] 2.int *p = a; int *p = 0; int a[]={0}; 3.int *p = a; 均指向数组的首地址 *p是? *(p+1)是?(*p)+1是? *(p+1)决定向下移动几个字节是类型 4.指针可以当数组名使用 p[1] = 3; 恒等于a[1] ;恒等于*(p+1);恒等于*(a+1) 5.

【C++基础】 指针&amp;字符串&amp;数组

先贴代码,总结以后再写,和5中内存分配方式密切相关 PS: str 返回整个字符串,str[0],*str返回首字符h char *strA(){ char str[]="hello!"; //局部数组,局部变量, str存在栈区 return str; //局部变量不能传值,估计会成为野指针 //函数返回局部变量的地址,当被调用完成时,str就释放了,因此返回结果是不确定的且不安全的 } char *strA2(){ char *str = "hello2!";/