回 帖 发 新 帖 刷新版面

主题:指针急救!!!

#include<stdio.h>
main()
{ char *p;
p="visual c++";
scanf("%s",p);
printf("%s\n",p);
}
如果这样写程序运行就会出错,而如:
#include<stdio.h>
main()
{ char *p,s[14]="visual c++";
p=s;
scanf("%s",p);
printf("%s\n",p);
}
这样写就是正确的。不知道是什么原因造成的请那位大侠帮帮忙解释一下,要详细点哦。并说说他们的区别。拜托!!!

回复列表 (共17个回复)

沙发

p="visual c++";
p=s;
这两句不一样的,定义了指针p,p的值是地址不能付值为字符串的。第2句中s是数组的首地址,因此可以付给p。
p的值是地址,*p是地址p上存储的数据,*(p+1)是地址p+1上存储的数据。

板凳

你应该成char *p="Visual C++"
那种赋初值应该是错误的

3 楼

如果用2楼说的方法初始化字符指针,那么这个指针不能再scanf了,因为指针指向的是一个字符串常量,篡改常量的值是不允许的(老谭用TC,硬说这样可以,其实是TC不严谨)

4 楼

第一个,因为初始化指针后,系统给p的只是一个4字节的指针地址,不能赋值为一个字符串常量,如果写成char *p="Visual C++",系统将p看作是const char *类型,将字符串常量的首地址赋值给p,但从此p变为只读类型,不能更改,但可以指向别的char类型,例如*(p+1)='a'是错的,char a='A';p=&a;是正确的。
第二个,在通常情况下,指针和数组是等价的,但这只是指针最一般的用法,就像你写的,p=a;此时p和a是等价的,p[1]和a[1]只指向的同一个内存单元。但这只是通常情况,当在其他文件中定义了一个数组时,在其他地方在声明是,必须用数组,用指针就是错误的。
不知道你明白了没有,这个是我个人理解。

5 楼

[quote]第一个,因为初始化指针后,系统给p的只是一个4字节的指针地址,不能赋值为一个字符串常量,如果写成char *p="Visual C++",系统将p看作是const char *类型,将字符串常量的首地址赋值给p,但从此p变为只读类型,不能更改,但可以指向别的char类型,例如*(p+1)='a'是错的,char a='A';p=&a;是正确的。
第二个,在通常情况下,指针和数组是等价的,但这只是指针最一般的用法,就像你写的,p=a;此时p和a是等价的,p[1]和a[1]只指向的同一个内存单元。但这只是通常情况,当在其他文件中定义了一个数组时,在其他地方在声明是,必须用数组,用指针就是错误的。
不知道你明白了没有,这个是我个人理解。
[/quote]
我觉得第二点里你说的区别我就没太看懂……最好带个代码例子……
数组名当指针用也能取得相应的值,只不过风格不太合适

6 楼


版副,你好。
    当你在一个文件中定义char a[];在另一个文件中调用的话,声明为
extern char a[];是没有问题的,要是声明为char *a就会出现不可预知的错误,因为声明是不分配内存的,a将就是数组a[]的首地址,如果取*(a+i),我们想要取的是a[i]中的值,应用指针,将表示为取a[i]中值当做该指针存储的地址,指向这块地址,取该地址中的值,就会造成不可预知的错误。
     不知道你是怎么看的

7 楼

第一种写法,p指向了一块只读的空间,而scanf会试图向那个空间写东西,这就是运行时出错的原因
第二种写法,p指向一个数组分配的空间,一般我们分配的数组空间都是可读写的,所以第二个就是正确的了。

8 楼

[quote]
版副,你好。
    当你在一个文件中定义char a[];在另一个文件中调用的话,声明为
extern char a[];是没有问题的,要是声明为char *a就会出现不可预知的错误,因为声明是不分配内存的,a将就是数组a[]的首地址,如果取*(a+i),我们想要取的是a[i]中的值,应用指针,将表示为取a[i]中值当做该指针存储的地址,指向这块地址,取该地址中的值,就会造成不可预知的错误。
     不知道你是怎么看的[/quote]
汗……extern的时候当然应该跟原始定义保持一致……这点没有任何问题啊……
我说的是观点都围绕在“数组名和指针在使用中”,而不是说在声明本身上的问题。归根结底,char[]和char*是不同的数据类型,只不过在内存访问的时候有相似的行为而已。如果你在另一个文件char[],而在这个文件extern char*的话,编译器因为找不到这个char*就会建立一个新指针,这点没有任何问题啊……不知道你是怎么理解这个问题的

9 楼


我不这么认为,对于声明的变量,编译器是不会为它再去分配内存的,当它找不到定义位置时会报错,但是在另一个文件char a[],而在这个文件extern char* a的话,我认为编译器会认为a就是一个char *类型,从而不报错,就用a中的值来进行操作,造成错误

10 楼

[quote]
我不这么认为,对于声明的变量,编译器是不会为它再去分配内存的,当它找不到定义位置时会报错,但是在另一个文件char a[],而在这个文件extern char* a的话,我认为编译器会认为a就是一个char *类型,从而不报错,就用a中的值来进行操作,造成错误[/quote]
我觉得咱俩说的不是同一件事……
我说的是:对于如下用例:
file1:
char a[50]
file2:
extern char* a
file2里extern的时候认为char[50]和char*不是同一个类型,于是不会让file2里的a指向file1里面那片内存。当然编译是没问题的,因为声明一个指针的时候不必同事进行初始化。
你是不是认为我说“在使用中指针和数组有相似的行为方式”就认为我说指针和数组名可以视为同样的东西了?显然不是,数组和指针是不同的数据类型,在内存分配上是不同的。所以我不明白你在向我纠正什么?

我来回复

您尚未登录,请登录后再回复。点此登录或注册