str3[]是字符数组,所以str3可以直接作为地址,在scanf语句当中就不用&str3的表达方式了。
"hello"这个字符串有5个字符,字符串结尾还有一个\0,所以一共有6个。
x/6cb:表示向下打印6个字符,用比特为单位。
用scanf输入str2,对其进行改动,不能完成值的更改,因为指针的内容在运行过后,会储存在代码段,无法被更改。
char类型的指针变量里面的值在代码段
用scanf输入数组类型的值时 可以不用加& 因为数组名称本身就是地址
指针类型的字符串不能输入 char *p="hello world" 中的hello world 不不允许被修改的,因为它储存于代码段,而非堆或栈中
只有堆和栈里面可以进行修改数据,代码段不允许修改数据
字符串遇到\0就结束不会打印后面
char str3[10];
scanf("%s",str3);
scanf("%s",str1);可以写会覆盖
scanf("%s",str2);指针不能写
str2内是world以及world的地址,world存在代码段,代码段不能被程序员更改
写写心得体会。
char *str2 = "world";
定义一个字符指针变量str2,
在gdb中用「p str2」查询到str2所指向的值,在内存中的位置是在低地址位的代码段,
而不是在高地址位的栈里面,结果是这样的:「$1 = 0x400774 "world"」。
str2本身是指针,它本身的所在是在栈里面的,用「p &str2」来查询,得到「$2 = (char **) 0x7fffffffda98」。
所以,如果用输入语句来试图对str2指向的地址赋值的话,是会出现「内存段错误的」!
比如:「scanf("%s",str2);」,这样的语句运行时是会出现内存段错误的。
原因就在于C语言不运行程序在运行中对内存中的代码段进行修改。
再对输入语句进行深入剖析,比如有「int a; scanf("%d",a);」这样的语句,当输入整型数值时,数值被传入内存,保存到了变量a所在的地址,实际上就是变量a本身所代表的含义就是它自身所在的内存地址,所以数值传入给a,实际上是传入给a指向的地址,而a作为一个整型变量,它指向的地址就是它本身所在的地址,它是在内存中的栈里的,所以输入值、传入值,没有问题,不会出现内存段错误。
但是,如果是像上面的把输入的字符串传入给字符指针str2的话,实际要执行的传入过程是把字符串传入到str2指向的地址,而这个地址是在内存的代码段里,这是不允许的,所以就会出现内存段错误!
++++++++++++++
所以,对于指针变量,它在定义或初始化的时候,它的默认指向地址是在内存的「代码段」里的,也就是说,在这种情况下,对指针变量取值的话,得到的值实际上是从内存的「代码段」里取出来的,根据C语言的规定,当然就无法对这个值进行重新赋值了!
所以,要改变指针变量所指向的内存的值,不能直接去对指针变量指向的值进行赋值,而是要改变指针的指向,也就是说,「要把地址赋值给指针变量」,而不是把值赋值给指针变量最初所指向的值。
++++++++++++++
再贴一段助于理解指针的试验代码:
#include <stdio.h> int main() { char a[10]="hello"; char b[10]="world"; char *c="81"; printf("char *c=81, c is %s\n",c); c=&a; printf("c = &a,c is %s\n",c); printf("address of a is %d\n",a); printf("address of value pointed by c is %d\n",&(*c)); printf("address of c itself is %d\n",&c); return 0; }
输出结果如下:
char *c=81, c is 81 c = &a,c is hello address of a is -358473008 address of value pointed by c is -358473008 address of c itself is -358473016
指针c本身也是在栈里面的,对c取地址的话取到的是c本身的地址,而要想取到c所指向的值的地址的话,要先对c取值,再对值取地址:&(*c)。
#include<stdio.h>
int main(void)
{
char str[] = "hello";
char *str2 = "world";
char str3[100];
printf("input the value \n");
scanf("%s", str3);
printf("str is %s\n", str);
printf("str2 is %s\n", str2);
printf("str3 is %s\n", str3);
}
代码段不能随便修改,堆和栈可以修改
只有堆和栈里面可以进行修改数据,代码段不允许修改数据