C语言中字符c语言 指针变量 输出输出的值为什么不是地址

C语言中,为什么字符串可以赋值给字符指针变量
双引号做了3件事:&&
1.申请了空间(在常量区),存放了字符串&
2. 在字符串尾加上了'/0'&&&&
3.返回地址
你这里就是 返回的地址& 赋值给了& p&&&&&&&&&&&&&&&&&&&&&&
char *p = “hello”;
上边的表达式为什么可以,而把p换成数组,然后再赋值就不行了
字符串常量&hello&出现在一个表达式中时,&hello&表达式使用的值就是这些字符所存储的地址(在常量区),而不是这些字符本身。
所以,可以把字符串赋值给指向字符的指针p,而不能把字符串赋值给一个字符数组。&
char a[10] = “hello”; //这样可以,这种情况是c语言初始化所支持的
如果写成char a[10]
然后 a = “hello” 这样就错误了。&&
同样是a数组,char a[10] = “hello”;这种是数组的初始化,和a[0] = ‘h’ a[1] = ‘e’…是一个道理
但是换成char a [10]
然后a = “hello”就不行了 “hello”赋值的值是一个地址,而a虽然也有地址,但是这与指针是不一样的,指针的值是地址,而数组的值虽然也是地址,但是却是一个常量,所以不能给常量赋值。
#include &stdio.h&&
int main()
&&&&&& char *p = &hello&;
&&&&&& printf(&%s&,p);
&&&&&& char a[10];
&&&&&& a = &hello&;
&&&&&& return 0;
error C2440: '=' : cannot convert from 'char [6]' to 'char [10]'
&&&&&&& There is no context in which this conversion is possible
看到这样的错误提示,你是否会想到把char a[10]改成char a[6]呢
error C2106: '=' : left operand must be l-value
运算符的左边应该是一个“左值”。所谓“左值”就是指在程序中占用内存空间、可以被修改的量,比如各种变量。&
继续扩展问题:
在使用指针的时候,指针可以自增,而数组不能自增
编译器给数组分配了空间,数组a的地址就是一个常量了,让常量自增这肯定是不行的。&
继续扩展:
&&&&&&在指针自增的时候,编译器会自动识别类型,比如指针是指向int型的,想获取下一个的地址时,指针直接p++就行了,不要多此一举的p+4了
&&&&&&特别需要注意的是,在void指针使用的时候,不能使用指针运算,应为void型编译器不能识别类型的长度(即指针所指对象的体积),p++这样就是不合法的,即不能进行数学运算,也不能使用*取值操作,想使用必须转换为其它的类型
标题:对字符数组,字符指针,字符串常量
1.以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写
& &abc&,那么编译器帮你存储的是&abc\0&
2.&abc&是常量吗?答案是有时是,有时不是。
&&不是常量的情况:&abc&作为字符数组初始值的时候就不是,如
&&&&&&&&&&&&&&&&& char str[] = &abc&;
&&& 因为定义的是一个字符数组,所以就相当于定义了一些空间来存放&abc&,而又因为
&&& 字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为
&&& char str[3] = {'a','b','c'};
&&&&&&&&&&&&&&&&& 又根据上面的总结1,所以char str[] = &abc&;的最终结果是
&&& char str[4] = {'a','b','c','\0'};
&&& 做一下扩展,如果char str[] = &abc&;是在函数内部写的话,那么这里
&&& 的&abc\0&因为不是常量,所以应该被放在栈上。
&&是常量的情况:& 把&abc&赋给一个字符指针变量时,如
&&&&&&&&&&&&&&&&& char* ptr = &abc&;
&&& 因为定义的是一个普通字符指针,并没有定义空间来存放&abc&,所以编译器得帮我们
&&& 找地方来放&abc&,显然,把这里的&abc&当成常量并把它放到程序的常量区是编译器
&&& 最合适的选择。所以尽管ptr的类型不是const char*,并且ptr[0] = 'x';也能编译
&&& 通过,但是执行ptr[0] = 'x';就会发生运行时异常,因为这个语句试图去修改程序
&&& 常量区中的东西。
&&& 记得哪本书中曾经说过char* ptr = &abc&;这种写法原来在c++标准中是不允许的,
&&& 但是因为这种写法在c中实在是太多了,为了兼容c,不允许也得允许。虽然允许,
&&& 但是建议的写法应该是const char* ptr = &abc&;这样如果后面写ptr[0] = 'x'的
&&& 话编译器就不会让它编译通过,也就避免了上面说的运行时异常。
&&& 又扩展一下,如果char* ptr = &abc&;写在函数体内,那么虽然这里的&abc\0&被
&&& 放在常量区中,但是ptr本身只是一个普通的指针变量,所以ptr是被放在栈上的,
&&& 只不过是它所指向的东西被放在常量区罢了。
3.数组的类型是由该数组所存放的东西的类型以及数组本身的大小决定的。
& 如char s1[3]和char s2[4],s1的类型就是char[3],s2的类型就是char[4],
& 也就是说尽管s1和s2都是字符数组,但两者的类型却是不同的。
4.字符串常量的类型可以理解为相应字符常量数组的类型,
& 如&abcdef&的类型就可以看成是const char[7]
5.sizeof是用来求类型的字节数的。如那么无论sizeof(int)或者是sizeof(a)都
& 是等于4,因为sizeof(a)其实就是sizeof(type of a)
6.对于函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通
& 的指针类型,如对于void func(char sa[100],int ia[20],char *p)
& 则sa的类型为char*,ia的类型为int*,p的类型为char*
7.根据上面的总结,来实战一下:
& 对于char str[] = &abcdef&;就有sizeof(str) == 7,因为str的类型是char[7],
& 也有sizeof(&abcdef&) == 7,因为&abcdef&的类型是const char[7]。
& 对于char *ptr = &abcdef&;就有sizeof(ptr) == 4,因为ptr的类型是char*。
& 对于char str2[10] = &abcdef&;就有sizeof(str2) == 10,因为str2的类型是char[10]。
& 对于void func(char sa[100],int ia[20],char *p);
& 就有sizeof(sa) == sizeof(ia) == sizeof(p) == 4,
& 因为sa的类型是char*, ia的类型是int*,p的类型是char*。
,该贴原址:
这几天搞Unix上的C程序,里面用到了很多字符数组和字符串指针,我记得在学完C语言后相当一段时间里,对指针这个东西还是模模糊糊,后来工作也没怎么用到过C,虽然网上这类的文章也有很多,还是决定自己在这做个小总结,也算加深下自己的印象,写了下面的测试程序:
#include &stdio.h&
int main(int argc, char *argv[])
& char day[15] = &abcdefghijklmn&;
& char* strTmp = &opqrstuvwxyz&;
& printf(&&day is %x\n&,&day);
& printf(&&day[0] is %x\n&,&day[0]);
& printf(&day is %x\n&,day);
& printf(&\n&strTmp is %x\n&,&strTmp);
& printf(&&strTmp[0] is %x\n&,&strTmp[0]);
& printf(&strTmp is %x\n&,strTmp);
& getchar();&
& return 0;
运行后屏幕上得到如下结果:
其实看到结果估计很多东西就好明白了,
&&& 先看看前三个输出也就是关于变量day的,在 char day[15] = &abcdefghijklmn&; 这个语句执行的时候,系统就分配了一段长15的内存,并把这段内存起名为day,里面的值为&abcdefghijklmn&,如下图所示:
&&&&&&& 再看程序,第一个输出,&day,&号是地址运算符,也就是day这个变量的内存地址,很明显,在最前面,也就是a字符所在字节的地址;
&&&&&&&&对于第二个输出也就好理解了,&day[0],就是day数组中第一个变量(也就是a)的地址,因此他们两个是一样的;
&&&&&&& 第三个输出是day,对于数组变量,可以使用变量名来索引变量中的内容,其实这里的day可以理解成数组变量退化的指针,并且指向数组的开头,既然把它理解成指针,那么它的值肯定是地址了,所以他的值和上面两个也一样。
&&& 再看看后面三个输出,关于字符串指针strTmp,在执行char* strTmp = &opqrstuvwxyz&;后,内存的图示如下:
如图所示,内存分配了两段内存,一个名为strTmp,类型是一个字符指针,另外一段是一个字符串常量,且strTmp里面存放着字符常量的首地址,注意这里无法通过strTmp修改这段字符串,因为是常量;于是程序中的后面三个输出就好理解了;
& &strTmp:strTmp这个字符指针的地址
& &strTmp[0]:strTmp所指字符常量第一个字符的地址
& strTmp:strTmp这个字符指针的值,即字符常量的首地址
因此,最后两个的值是一样的。
&&&&& 指针可以这样理解,指针这种类型,和int,char,double等等是一样的,只是它用来保存地址值的,而int变量保存整数,char变量保存字符,仅此而已,就char型指针或者int指针,本质是一样的,都是存放的地址,只不过那个地址所里面的变量类型不同而已,还有一种void型指针,就是可以放任何类型变量的地址。
五、个人代码以及注释,纯属个人理解,定有不妥之处,望批评指正:
#include &stdio.h&
int main(int argc, char *argv[])
&char* strTmp = &abcd&;
&printf(&strTmp is %s\n&,strTmp);//将字符串常量&abcd&的地址所隐含的内容转换成“string类型”
&printf(&strTmp is %d\n&,strTmp);//将字符串常量&abcd&的地址转换成int类型,这里不同的机子不同的时间的运行结果可能会不一样,因为地址可能会发生变化
&printf(&strTmp is %c\n&,strTmp);//将字符串常量&abcd&的地址转换成字符型,这里不同的机子不同的时间的运行结果可能会不一样,因为地址可能会发生变化
&printf(&*strTmp is %c\n&,*strTmp);//将字符串常量&abcd&的地址所隐含的内容转换成字符型,由下面注释的这句会抛出异常可知,这里并无截取字符串,*strTmp长度本身就是1
&//printf(&*strTmp is %s\n&,*strTmp);//不能将字符转换成字符串型
&getchar();&
&return 0;
&六、后来又有看到下面这样的说法可供读者参考:
1. C语言中没有字符串类型,只有用字符数组来表示。这和c++中string是有区别的,C++中string是可以直接赋值如s=&Hello world&;但是C语言中的字符数组却不能这样。所以,这里的strTmp可以理解为字符数组的首地址,也可以用它代表整个字符数组,所以能输出所有字符数组中的内容。
&2.字符串就是字符数组或者是指针。 内存实现都一样的。 数组名字就是一个指针。
char ch[100] ;
3.定义的字符串方式举例:
字符串定义其实很简单在c/c++语言中定义一个字符串可以使用如下的语法:
char&*s1=“string1”;//定义字符串常量,指针形式
char&s2[]=“string2”;//定义字符串常量,数组形式
char&*s3=new&char[10];//定义字符串变量并分配内存&指针形式
strcpy(s3,&string3&);//为s3赋值
char&s4[10];//定义字符串变量,数组形式
strcpy(s4,&string4&);//为s4赋值
以上四种方法都能定义一个字符串,同时通过字符串在内存中的分布可以清楚地知道是什么情况
4. C语言中字符串赋值方法strcpy(char*d,char*s)其中s代表是源字符串,d代表目标字符串,也就是你要赋值的字符串。
5.c语言中的字符串跟java或c++中的字符串不同。如char *p;其中p是一个指针,p中存储一个内存缓冲区的首地址。所谓的内存缓冲区就是一段连续的内存地址,里面存放了一系列的字符。那系统又是如何判断在哪里结束呢。那就是根据符号‘\0’。这个字符占一个字节,8位,每位的值都是0。
本文已收录于以下专栏:
相关文章推荐
C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中,这在《C语言字符数组和字符串》中已经进行了详细讲解,这里不妨再来演示一下:
#include int main(){
废话不多说,直接上代码:
int main()
char str[]=&hello78&;
char *str1=&world&;
printf(&%p...
程序员升职加薪指南!还缺一个“证”!
CSDN出品策划程序员9月规划,专为码农的升职加薪保驾护航,程序员的捷径,你get到了吗?听说阅读了这篇文章的人,都已实现了小梦想~快来揭秘!
1、指针的初始化
指针初始化时,“=”的右操作数必须为内存中数据的地址,不可以是变量,也不可以直接用整型地址值(但是int*p=0;除外,该语句表示指针为空)。此时,*p只是表示定义的是个指针变...
Technorati 标签: 字符串,数组,地址,char *;
对于语句  char *a=“hello”;
        对于这个声明方式,会造成的误解是:声明了一个字符指针,将“字符串”赋...
用字符数组和字符指针变量都可实现字符串的存储和运算。但是两者是有区别的。在使用时应注意以下几个问题:
1.     字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首...
1.字符指针可以指向一个字符串。我们可以用字符串常量对字符指针进行初始化。例如,有说明语句:char *str = &This is a string.&; 是对字符指针进行初始化。此时,字符指针指向...
assignment makes pointer from integer without a cast
    因为这个.c文件里看不到函数原型,编译器不知道返回值啥类型的,推断为int。
C语言中,字符串可以赋值给字符指针变量,或者将字符串用字符数组保存。因为c语言没有直接对字符串提供语法糖方面的支持。而且C标准库很多方法处理字符串是以空字符结尾为前提的,这个必须要记住。char *p...
学了这么多年的C语言,突然发现连字符串赋值都出错,真的很伤心。
char a[10];
怎么给这个数组赋值呢?
1、定义的时候直接用字符串赋值
char a[10]=&hello&;
在建立对象时,系统会为每一个对象分配独立的存储空间,也就是给每个对象中的数据成员都分配有自己独立的存储空间。如果对同一个类定义n个对象,则有n组同样大小的空间以存放对象中的数据成员...
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)C语言(33)
谭浩强(11)
//使用指向指针数据的指针变量,输出一组字符串
#include &stdio.h&
int main()
char * name[]={&beijing&,&huanying&,&nin&,&!&};
for(i=0;i&4;i++)
printf(&%s &,*p);
printf(&\n&);
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:147278次
积分:2695
积分:2695
排名:第13511名
原创:127篇
(35)(12)(24)(37)(19)求大神解答为什么,为什么指针变量可以当做整形数据输出【c语言吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:540,076贴子:
求大神解答为什么,为什么指针变量可以当做整形数据输出收藏
达内c语言培训,0基础从入门到精通120天,先就业后付款,签订c语言就业协议,c语言培训首选达内,不就业免费重学,70000家名企联合招聘!
数据大小相同
因为指针存的是地址,地址在内存中是一个一个已经编好的整型数字,所以指针存的也要是一个整型,一般来讲,同样也是占四个字节数,所以输出指针,就是把这个地址编号输出来
这是一个很有意思的问题。第一,对于题中的指针变量p(用于存放内存单元的编号);要是直接将0以外的其它整数,直接赋值给它,程序就会报错了!但是把整数0赋值给它,却没有报错,是因为这时程序已将0看成是内存中地址编号为0的字节地址了!指针变量存放地址,当然就不会报错了;至于程序为什么不把其它整数也看成地址这个我也就不清楚了。第二,p++为什么成了4?如第一中指出的,p没有自增以前存放地址是编号0,自增一次就应该是1呀!那有为什么是4呢!
这个和数据类型存储所占的字节数还有存放首地址的规定有关,如果一个整型变量 i 占4个字节,取 i 的地址赋给整型指针变量p,则变量p中存放的是 i所占4个字节 中的第一个字节的地址(这个是规定),当执行p++后,执行结果是,p中存放的地址往后数四个字节了(这个和数组操作相同,数组名存放第一个元素的地址,但数组名加一,就存放其第二个元素的地址了);如果是一个字符型变量 i,本身只占一个字节,取地址存放在字符型指针变量p中,执行p++,后,结果是p中存放地址往后数一个字节了。第三,下面附图。
这是整型变量结果,地址4个递增。这是字符型变量,地址1个递增。
不明真相的吃瓜群众
点亮12星座印记,
希望懂得的人多多帮助求助的楼主,大家共同进步!
p本身也是个变量,有自己的值,所以可以打印出来。
登录百度帐号推荐应用}

我要回帖

更多关于 指针输出字符串 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信