
指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。 要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的 类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。让我们分别说明。
先声明几个指针放着做例子:
例一:
(1)intptr;
(2)charptr;
(3)intptr;
(4)int(ptr)[3];
(5)int(ptr)[4];
如果看不懂后几个例子的话,请参阅我前段时间贴出的文章<<如何理解c和c ++的复杂类型声明>>。
指针的类型
从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。让我们看看例一中各个指针的类型:
(1)intptr;//指针的类型是int
(2)charptr;//指针的类型是char
(3)intptr;//指针的类型是int
(4)int(ptr)[3];//指针的类型是int()[3]
(5)int(ptr)[4];//指针的类型是int()[4]
怎么样?找出指针的类型的方法是不是很简单?
指针所指向的类型
当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。
从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符去掉,剩下的就是指针所指向的类型。例如:
(1)intptr;//指针所指向的类型是int
(2)charptr;//指针所指向的的类型是char
(3)intptr;//指针所指向的的类型是int
(4)int(ptr)[3];//指针所指向的的类型是int()[3]
(5)int(ptr)[4];//指针所指向的的类型是int()[4]
在指针的算术运算中,指针所指向的类型有很大的作用。
指针的类型(即指针本身的类型)和指针所指向的类型是两个概念。当你对C越来越熟悉时,你会发现,把与指针搅和在一起的"类型"这个概念分成"指针的类型"和"指针所指向的类型"两个概念,是精通指针的关键点之一。我看了不少书,发现有些写得差的书中,就把指针的这两个概念搅在一起了,所以看起书来前后矛盾,越看越糊涂。
指针的值,或者叫指针所指向的内存区或地址
指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长。 指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为si zeof(指针所指向的类型)的一片内存区。以后,我们说一个指针的值是XX,就相当于说该指针指向了以XX为首地址的一片内存区域;我们说一个指针指向了某块内存区域,就相当于说该指针的值是这块内存区域的首地址。
指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例一中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向的内存区是不存在的,或者说是无意义的。
以后,每遇到一个指针,都应该问问:这个指针的类型是什么?指针指的类型是什么?该指针指向了哪里?
指针本身所占据的内存区
指针本身占了多大的内存?你只要用函数sizeof(指针的类型)测一下就知道了。在32位平台里,指针本身占据了4个字节的长度。
指针本身占据的内存这个概念在判断一个指针表达式是否是左值时很有用。
指针的算术运算
指针可以加上或减去一个整数。指针的这种运算的意义和通常的数值的加减运算的意义是不一样的。例如:
例二:
1、chara[20];
2、intptr=a;
3、ptr++;
在上例中,指针ptr的类型是int,它指向的类型是int,它被初始化为指向整形变量a。接下来的第3句中,指针ptr被加了1,编译器是这样处理的:它把指针ptr的值加上了sizeof(int),在32位程序中,是被加上了4。由于地址是用字节做单位的,故ptr所指向的地址由原来的变量a的地址向高地址方向增加了4个字节。
由于char类型的长度是一个字节,所以,原来ptr是指向数组a的第0号单元开始的四个字节,此时指向了数组a中从第4号单元开始的四个字节。
我们可以用一个指针和一个循环来遍历一个数组,看例子:
例三:
intarray[20];
intptr=array;
//此处略去为整型数组赋值的代码。
for(i=0;i<20;i++)
{
(ptr)++;
ptr++;
}
这个例子将整型数组中各个单元的值加1。由于每次循环都将指针ptr加1,所以每次循环都能访问数组的下一个单元。
再看例子:
例四:
1、chara[20];
2、intptr=a;
3、ptr+=5;
在这个例子中,ptr被加上了5,编译器是这样处理的:将指针ptr的值加上5乘sizeof(int),在32位程序中就是加上了5乘4=20。由于地址的单位是字节,故现在的ptr所指向的地址比起加5后的ptr所指向的地址来说,向高地址方向移动了20个字节。在这个例子中,没加5前的ptr指向数组a的第0号单元开始的四个字节,加5后,ptr已经指向了数组a的合法范围之外了。虽然这种情况在应用上会出问题,但在语法上却是可以的。这也体现出了指针的灵活性。
如果上例中,ptr是被减去5,那么处理过程大同小异,只不过ptr的值是被减去5乘sizeof(int),新的ptr指向的地址将比原来的ptr所指向的地址向低地址方向移动了20个字节。
总结一下,一个指针ptrold加上一个整数n后,结果是一个新的指针ptrnew,ptrnew的类型和ptrold的类型相同,ptrnew所指向的类型和ptrold所指向的类型也相同。ptrnew的值将比ptrold的值增加了n乘sizeof(ptrold所指向的类型)个字节。就是说,ptrnew所指向的内存区将比ptrold所指向的内存区向高地址方向移动了n乘sizeof(ptrold所指向的类型)个字节。
一个指针ptrold减去一个整数n后,结果是一个新的指针ptrnew,ptrnew的类型和ptrold的类型相同,ptrnew所指向的类型和ptrold所指向的类型也相同。ptrnew的值将比ptrold的值减少了n乘sizeof(ptrold所指向的类型)个字节,就是说,ptrnew所指向的内存区将比ptrold所指向的内存区向低地址方向移动了n乘sizeof(ptrold所指向的类型)个字节。
运算符&和
这里&是取地址运算符,是书上叫做"间接运算符"。
&a的运算结果是一个指针,指针的类型是a的类型加个,指针所指向的类型是a的类型,指针所指向的地址嘛,那就是a的地址。
p的运算结果就五花八门了。总之p的结果是p所指向的东西,这个东西有这些特点:它的类型是p指向的类型,它所占用的地址是p所指向的地址。
例五:
inta=12;
intb;
intp;
intptr;
p=&a;
//&a的结果是一个指针,类型是int,指向的类型是int,指向的地址是a的地址。
p=24;
//p的结果,在这里它的类型是int,它所占用的地址是p所指向的地址,显然,p就是变量a。
ptr=&p;
//&p的结果是个指针,该指针的类型是p的类型加个,在这里是int 。该指针所指向的类型是p的类型,这里是int。该指针所指向的地址就是指针p自己的地址。
ptr=&b;
//ptr是个指针,&b的结果也是个指针,且这两个指针的类型和所指向的类型是一样的,所以用&b来给ptr赋值就是毫无问题的了。
ptr=34;
//ptr的结果是ptr所指向的东西,在这里是一个指针,对这个指针再做一次运算,结果就是一个int类型的变量。
指针表达式
一个表达式的最后结果如果是一个指针,那么这个表达式就叫指针表式。
下面是一些指针表达式的例子:
例六:
inta,b;
intarray[10];
intpa;
pa=&a;//&a是一个指针表达式。
intptr=&pa;//&pa也是一个指针表达式。
ptr=&b;//ptr和&b都是指针表达式。
pa=array;
pa++;//这也是指针表达式。
例七:
chararr[20];
charparr=arr;//如果把arr看作指针的话,arr也是指针表达式
charstr;
str=parr;//parr是指针表达式
str=(parr+1);//(parr+1)是指针表达式
str=(parr+2);//(parr+2)是指针表达式
由于指针表达式的结果是一个指针,所以指针表达式也具有指针所具有的四个要素:指针的类型,指针所指向的类型,指针指向的内存区,指针自身占据的内存。
好了,当一个指针表达式的结果指针已经明确地具有了指针自身占据的内存的话,这个指针表达式就是一个左值,否则就不是一个左值。
在例七中,&a不是一个左值,因为它还没有占据明确的内存。ptr是一个左值,因为ptr这个指针已经占据了内存,其实ptr就是指针pa,既然pa已经在内存中有了自己的位置,那么ptr当然也有了自己的位置。
数组和指针的关系
如果对声明数组的语句不太明白的话,请参阅我前段时间贴出的文章<<如何理解c和c++的复杂类型声明>>。
数组的数组名其实可以看作一个指针。看下例:
例八:
intarray[10]={0,1,2,3,4,5,6,7,8,9},value;
value=array[0];//也可写成:value=array;
value=array[3];//也可写成:value=(array+3);
value=array[4];//也可写成:value=(array+4);
上例中,一般而言数组名array代表数组本身,类型是int[10],但如果把array看做指针的话,它指向数组的第0个单元,类型是int,所指向的类型是数组单元的类型即int。因此array等于0就一点也不奇怪了。同理,array+3是一个指向数组第3个单元的指针,所以(array+3)等于3。其它依此类推。
例九:
charstr[3]={
"Hello,thisisasample!",
"Hi,goodmorning",
"Helloworld"
};
chars[80];
strcpy(s,str[0]);//也可写成strcpy(s,str);
strcpy(s,str[1]);//也可写成strcpy(s,(str+1));
strcpy(s,str[2]);//也可写成strcpy(s,(str+2));
上例中,str是一个三单元的数组,该数组的每个单元都是一个指针,这些指针各指向一个字符串。把指针数组名str当作一个指针的话,它指向数组的第0号单元,它的类型是char,它指向的类型是char。
str也是一个指针,它的类型是char,它所指向的类型是char,它指向的地址是字符串"Hello,thisisasample!"的第一个字符的地址,即'H'的地址。 str+1也是一个指针,它指向数组的第1号单元,它的类型是char,它指向的类型是char。
(str+1)也是一个指针,它的类型是char,它所指向的类型是char,它指向 "Hi,goodmorning"的第一个字符'H',等等。
下面总结一下数组的数组名的问题。声明了一个数组TYPEarray[n],则数组名称array就有了两重含义:第一,它代表整个数组,它的类型是TYPE[n];第二 ,它是一个指针,该指针的类型是TYPE,该指针指向的类型是TYPE,也就是数组单元的类型,该指针指向的内存区就是数组第0号单元,该指针自己占有单独的内存区,注意它和数组第0号单元占据的内存区是不同的。该指针的值是不能修改的,即类似array++的表达式是错误的。
在不同的表达式中数组名array可以扮演不同的角色。
在表达式sizeof(array)中,数组名array代表数组本身,故这时sizeof函数测出的是整个数组的大小。
在表达式array中,array扮演的是指针,因此这个表达式的结果就是数组第0号单元的值。sizeof(array)测出的是数组单元的大小。
表达式array+n(其中n=0,1,2,。)中,array扮演的是指针,故array+n的结果是一个指针,它的类型是TYPE,它指向的类型是TYPE,它指向数组第n号单元。故sizeof(array+n)测出的是指针类型的大小。
例十
intarray[10];
int(ptr)[10];
ptr=&array;:
上例中ptr是一个指针,它的类型是int()[10],他指向的类型是int[10] ,我们用整个数组的首地址来初始化它。在语句ptr=&array中,array代表数组本身。
本节中提到了函数sizeof(),那么我来问一问,sizeof(指针名称)测出的究竟是指针自身类型的大小呢还是指针所指向的类型的大小?答案是前者。例如:
int(ptr)[10];
则在32位程序中,有:
sizeof(int()[10])==4
sizeof(int[10])==40
sizeof(ptr)==4
实际上,sizeof(对象)测出的都是对象自身的类型的大小,而不是别的什么类型的大小。
指针和结构类型的关系
可以声明一个指向结构类型对象的指针。
例十一:
structMyStruct
{
inta;
intb;
intc;
}
MyStructss={20,30,40};
//声明了结构对象ss,并把ss的三个成员初始化为20,30和40。
MyStructptr=&ss;
//声明了一个指向结构对象ss的指针。它的类型是MyStruct,它指向的类型是MyStruct。
intpstr=(int)&ss;
//声明了一个指向结构对象ss的指针。但是它的类型和它指向的类型和ptr是不同的。
请问怎样通过指针ptr来访问ss的三个成员变量?
答案:
ptr->a;
ptr->b;
ptr->c;
又请问怎样通过指针pstr来访问ss的三个成员变量?
答案:
pstr;//访问了ss的成员a。
(pstr+1);//访问了ss的成员b。
(pstr+2)//访问了ss的成员c。
虽然我在我的MSVC++60上调式过上述代码,但是要知道,这样使用pstr来访问结构成员是不正规的,为了说明为什么不正规,让我们看看怎样通过指针来访问数组的各个单元:
例十二:
intarray[3]={35,56,37};
intpa=array;
通过指针pa访问数组array的三个单元的方法是:
pa;//访问了第0号单元
(pa+1);//访问了第1号单元
(pa+2);//访问了第2号单元
从格式上看倒是与通过指针访问结构成员的不正规方法的格式一样。
所有的C/C++编译器在排列数组的单元时,总是把各个数组单元存放在连续的存储区里,单元和单元之间没有空隙。但在存放结构对象的各个成员时,在某种编译环境下,可能会需要字对齐或双字对齐或者是别的什么对齐,需要在相邻两个成员之间加若干个"填充字节",这就导致各个成员之间可能会有若干个字节的空隙。
所以,在例十二中,即使pstr访问到了结构对象ss的第一个成员变量a,也不能保证(pstr+1)就一定能访问到结构成员b。因为成员a和成员b之间可能会有若干填充字节,说不定(pstr+1)就正好访问到了这些填充字节呢。这也证明了指针的灵活性。要是你的目的就是想看看各个结构成员之间到底有没有填充字节,嘿,这倒是个不错的方法。
过指针访问结构成员的正确方法应该是象例十二中使用指针ptr的方法。
指针和函数的关系
可以把一个指针声明成为一个指向函数的指针。intfun1(char,int);
int(pfun1)(char,int);
pfun1=fun1;
inta=(pfun1)("abcdefg",7);//通过函数指针调用函数。
可以把指针作为函数的形参。在函数调用语句中,可以用指针表达式来作为实参。
例十三:
intfun(char);
inta;
charstr[]="abcdefghijklmn";
a=fun(str);
intfun(chars)
{
intnum=0;
for(inti=0;i{
num+=s;s++;
}
returnnum;
}
这个例子中的函数fun统计一个字符串中各个字符的ASCII码值之和。前面说了,数组的名字也是一个指针。在函数调用中,当把str作为实参传递给形参s后,实际是把str的值传递给了s,s所指向的地址就和str所指向的地址一致,但是str和s各自占用各自的存储空间。在函数体内对s进行自加1运算,并不意味着同时对str进行了自加1运算。
指针类型转换
当我们初始化一个指针或给一个指针赋值时,赋值号的左边是一个指针,赋值号的右边是一个指针表达式。在我们前面所举的例子中,绝大多数情况下,指针的类型和指针表达式的类型是一样的,指针所指向的类型和指针表达式所指向的类型是一样的。
例十四:
1、floatf=123;
2、floatfptr=&f;
3、intp;
在上面的例子中,假如我们想让指针p指向实数f,应该怎么搞?是用下面的语句吗?
p=&f;
不对。因为指针p的类型是int,它指向的类型是int。表达式&f的结果是一个指针,指针的类型是float,它指向的类型是float。两者不一致,直接赋值的方法是不行的。至少在我的MSVC++60上,对指针的赋值语句要求赋值号两边的类型一致,所指向的类型也一致,其它的编译器上我没试过,大家可以试试。为了实现我们的目的,需要进行"强制类型转换":
p=(int)&f;
如果有一个指针p,我们需要把它的类型和所指向的类型改为TYEPTYPE, 那么语法格式是:
(TYPE)p;
这样强制类型转换的结果是一个新指针,该新指针的类型是TYPE,它指向的类型是TYPE,它指向的地址就是原指针指向的地址。而原来的指针p的一切属性都没有被修改。
一个函数如果使用了指针作为形参,那么在函数调用语句的实参和形参的结合过程中,也会发生指针类型的转换。
例十五:
voidfun(char);
inta=125,b;
fun((char)&a);
voidfun(chars)
{
charc;
c=(s+3);(s+3)=(s+0);(s+0)=c;
c=(s+2);(s+2)=(s+1);(s+1)=c;
}
}
注意这是一个32位程序,故int类型占了四个字节,char类型占一个字节。函数fun的作用是把一个整数的四个字节的顺序来个颠倒。注意到了吗?在函数调用语句中,实参&a的结果是一个指针,它的类型是int,它指向的类型是int。形参这个指针的类型是char,它指向的类型是char。这样,在实参和形参的结合过程中,我们必须进行一次从int类型到char类型的转换。结合这个例子,我们可以这样来想象编译器进行转换的过程:编译器先构造一个临时指针chartemp, 然后执行temp=(char)&a,最后再把temp的值传递给s。所以最后的结果是:s的类型是char,它指向的类型是char,它指向的地址就是a的首地址。
我们已经知道,指针的值就是指针指向的地址,在32位程序中,指针的值其实是一个32位整数。那可不可以把一个整数当作指针的值直接赋给指针呢?就象下面的语句:
unsignedinta;
TYPEptr;//TYPE是int,char或结构类型等等类型。
a=20345686;
ptr=20345686;//我们的目的是要使指针ptr指向地址20345686(十进制
)
ptr=a;//我们的目的是要使指针ptr指向地址20345686(十进制)
编译一下吧。结果发现后面两条语句全是错的。那么我们的目的就不能达到了吗?不,还有办法:
unsignedinta;
TYPEptr;//TYPE是int,char或结构类型等等类型。
a=某个数,这个数必须代表一个合法的地址;
ptr=(TYPE)a;//呵呵,这就可以了。
严格说来这里的(TYPE)和指针类型转换中的(TYPE)还不一样。这里的(TYPE)的意思是把无符号整数a的值当作一个地址来看待。上面强调了a的值必须代表一个合法的地址,否则的话,在你使用ptr的时候,就会出现非法 *** 作错误。
想想能不能反过来,把指针指向的地址即指针的值当作一个整数取出来。完 全可以。下面的例子演示了把一个指针的值当作一个整数取出来,然后再把这个整数当作一个地址赋给一个指针:
例十六:
inta=123,b;
intptr=&a;
charstr;
b=(int)ptr;//把指针ptr的值当作一个整数取出来。
str=(char)b;//把这个整数的值当作一个地址赋给指针str。
现在我们已经知道了,可以把指针的值当作一个整数取出来,也可以把一个整数值当作地址赋给一个指针。
指针的安全问题
看下面的例子:
例十七:
chars='a';
intptr;
ptr=(int)&s;
ptr=1298;
指针ptr是一个int类型的指针,它指向的类型是int。它指向的地址就是s的首地址。在32位程序中,s占一个字节,int类型占四个字节。最后一条语句不但改变了s所占的一个字节,还把和s相临的高地址方向的三个字节也改变了。这三个字节是干什么的?只有编译程序知道,而写程序的人是不太可能知道的。也许这三个字节里存储了非常重要的数据,也许这三个字节里正好是程序的一条代码,而由于你对指针的马虎应用,这三个字节的值被改变了!这会造成崩溃性的错误。
让我们再来看一例:
例十八:
1、chara;
2、intptr=&a;
3、ptr++;
4、ptr=115;
该例子完全可以通过编译,并能执行。但是看到没有?第3句对指针ptr进行自加1运算后,ptr指向了和整形变量a相邻的高地址方向的一块存储区。这块存储区里是什么?我们不知道。有可能它是一个非常重要的数据,甚至可能是一条代码。而第4句竟然往这片存储区里写入一个数据!这是严重的错误。所以在使用指针时,程序员心里必须非常清楚:我的指针究竟指向了哪里。在用指针访问数组的时候,也要注意不要超出数组的低端和高端界限,否则也会造成类似的错误。
在指针的强制类型转换:ptr1=(TYPE)ptr2中,如果sizeof(ptr2的类型)大于sizeof(ptr1的类型),那么在使用指针ptr1来访问ptr2所指向的存储区时是安全的。如果sizeof(ptr2的类型)小于sizeof(ptr1的类型),那么在使用指针ptr1来访问ptr2所指向的存储区时是不安全的。
以上是我从以前学过的书上摘的,对你应该适用。
C语言(关于指针)
C语言(关于指针)
C语言(关于指针)
C语言(关于指针)
C语言(关于指针)
,一般来说现在流行在网上 *** 作,如果手机上相对方便一些,因为在手机上只需要网页或者软件APP就可以完成了。
首先更正一下楼主错误,int 型的指针不可以用来获取char型的地址的,这样会产生错误,如果你的编译系统没有报错,实际上也有错误。
第二,字符串实际上就是等于字符数组。
ptr = &str[2];
printf("%d",ptr);
reptr = (ptr);
printf("%c",reptr);
printf("\n");
这个可以输出的。就是C
ptr = &str[2];
printf("%c",(ptr+1));
输出的是第4个字符‘/0’就是“空”,可能楼主由此判断无法输出
ptr = &str[1];
printf("%c",(ptr+1));
就能输出C了
int 应该不可以,不过 int的话就可以
char str[4] = "abc";
int ptr;
char reptr;
ptr =(int)&str[0];
printf("%d",(char )ptr);
reptr = ((char )ptr);
printf("%c",reptr);
printf("\n");
实际上利用强制类型转换,用int来存数据,意义上char 和int都是整形,所以可以一定程度上转换
面我收藏关于指针非文档讲深入楼主要兴趣研究要懂随问我
第章指针概念
指针特殊变量面存储数值解释内存址
要搞清指针需要搞清指针四面内容:指针类型指针所指向 类型指针值或者叫指针所指向内存区指针本身所占据内存区让 我别说明
先声明几指针放着做例:
例:
(1)int ptr;
(2)char ptr;
(3)int ptr;
(4)int (ptr)[3];
(5)int (ptr)[4];
1 指针类型
语角度看要指针声明语句指针名字掉剩部指针类型指针本身所具类型让我看看例各指针 类型:
(1)int ptr; //指针类型int
(2)char ptr; //指针类型char
(3)int ptr; //指针类型 int
(4)int (ptr)[3]; //指针类型 int()[3]
(5)int (ptr)[4]; //指针类型 int ()[4]
找指针类型简单
2指针所指向类型
通指针访问指针所指向内存区指针所指向类型决定编译 器片内存区内容做看待
语看须指针声明语句指针名字名字左边指针声明符 掉剩指针所指向类型例:
(1)int ptr; //指针所指向类型int
(2)char ptr; //指针所指向类型char
(3)int ptr; //指针所指向类型 int
(4)int (ptr)[3]; //指针所指向类型 int()[3]
(5)int (ptr)[4]; //指针所指向类型 int ()[4]
指针算术运算指针所指向类型作用
指针类型(即指针本身类型)指针所指向类型两概念C越 越熟悉发现与指针搅起"类型"概念"指针 类型""指针所指向类型"两概念精通指针关键点我看 少书发现些写差书指针两概念搅起所看起书前矛盾越看越糊涂
3 指针值或者叫指针所指向内存区或址
指针值指针本身存储数值值编译器作址般数值32位程序所类型指针值都32位整数32位程序内存址全都32位
指针所指向内存区指针值所代表内存址始度sizeof(指针所指向类型)片内存区我说指针值XX相于说该指针指向XX首址片内存区域;我说指针指向某块
内存区域相于说该指针值块内存区域首址
指针所指向内存区指针所指向类型两完全同概念例指针所指向类型已经由于指针未初始化所所指向内存区存或者说意义
每遇指针都应该问问:指针类型指针指向类型该指针指向哪
4 指针本身所占据内存区
指针本身占内存要用函数sizeof(指针类型)测知道32位平台指针本身占据4字节度
指针本身占据内存概念判断指针表达式否左值用
第二章指针算术运算
指针加或减整数指针种运算意义通数值加减运算意义例:
例二:
1 char a[20];
2 int ptr=a;
3 ptr++;
例指针ptr类型int,指向类型int初始化指向整 形变量a接第3句指针ptr加1编译器处理:指针ptr值加sizeof(int)32位程序加4由于址用字节做单位故ptr所指向址由原变量a址向高址向增加4字节
由于char类型度字节所原ptr指向数组a第0号单元始四字节指向数组a第4号单元始四字节
我用指针循环遍历数组看例:
例三:
int array[20];
int ptr=array;
//处略整型数组赋值代码
for(i=0;i<20;i++)
{
(ptr)++;
ptr++;
}
例整型数组各单元值加1由于每循环都指针ptr加1所
每循环都能访问数组单元
再看例:
例四:
1 char a[20];
2 int ptr=a;
3 ptr+=5;
例ptr加5编译器处理:指针ptr值加5 乘sizeof(int)32位程序加5乘4=20由于址单位字节故现ptr所指向址比起加5ptr所指向址说向高址向移20字节例没加5前ptr指向数组a第0号单元始四字节加5ptr已经指向数组a合范围外虽种情况应用问题语却体现指针灵性
例ptr减5处理程同异ptr值减5乘sizeof(int)新ptr指向址比原ptr所指向址向低址向移20字节
总结指针ptrold加整数n结新指针ptrnewptrnew类型ptrold类型相同ptrnew所指向类型ptrold所指向类型相同ptrnew值比ptrold值增加n乘sizeof(ptrold所指向类型)字节说ptrnew所指向内存区比ptrold所指向内存区向高址向移n乘sizeof(ptrold所指向类型)字节
指针ptrold减整数n结新指针ptrnewptrnew类型ptrold类型相同ptrnew所指向类型ptrold所指向类型相同ptrnew值比ptrold值减少n乘sizeof(ptrold所指向类型)字节说ptrnew所指向内存区比ptrold所指向内存区向低址向移n乘sizeof(ptrold所指向类型)字节
第三章运算amp;
&取址运算符书叫做"间接运算符"
&a运算结指针指针类型a类型加指针所指向类型a类型指针所指向址嘛a址
p运算结五花八门总p结p所指向东西东西些特点:类型p指向类型所占用址p所指向址
例五:
int a=12;
int b;
int p;
int ptr;
p=&a;//&a结指针类型int指向类型int指向址 a址
p=24;//p结类型int所占用址p所指向 址显p变量a
ptr=&p;//&p结指针该指针类型p类型加int
该指针所指向类型p类型int该指针所指向址指针p自址
ptr=&b;//ptr指针&b结指针且两指针类型所 指向类型所用&b给ptr赋值毫问题
ptr=34;//ptr结ptr所指向东西指针指
针再做运算结int类型变量
第四章指针表达式
表达式结指针表达式叫指针表达式
面些指针表达式例:
例六:
int a,b;
int array[10];
int pa;
pa=&a;//&a指针表达式
int ptr=&pa;//&pa指针表达式
ptr=&b;//ptr&b都指针表达式
pa=array;
pa++;//指针表达式
例七:
char arr[20];
char parr=arr;//arr看作指针arr指针表达式
char str;
str=parr;//parr指针表达式
str=(parr+1);//(parr+1)指针表达式
str=(parr+2);//(parr+2)指针表达式
由于指针表达式结指针所指针表达式具指针所具四要素:指针类型指针所指向类型指针指向内存区指针自身占据内存
指针表达式结指针已经明确具指针自身占据内存指针表达式左值否则左值
例七&a左值没占据明确内存ptr左值ptr指针已经占据内存其实ptr指针pa既pa已经内存自位置ptr自位置
第五章数组指针关系
声明数组语句太明白请参阅我前段间贴文lt;<何理解cc++复杂类型声明>>
数组数组名其实看作指针看例:
例八:
int array[10]={0,1,2,3,4,5,6,7,8,9},value;
value=array[0];//写:value=array;
value=array[3];//写:value=(array+3);
value=array[4];//写:value=(array+4);
例般言数组名array代表数组本身类型int [10]a
rray看做指针指向数组第0单元类型int 所指向类型数组单元类型即intarray等于0点奇怪同理array+3指向数组第3单元指针所(array+3)等于3其依类推
例九:
char str[3]={
"Hello,this is a sample!",
"Hi,good morning",
"Hello world"
};
char s[80];
strcpy(s,str[0]);//写strcpy(s,str);
strcpy(s,str[1]);//写strcpy(s,(str+1));
strcpy(s,str[2]);//写strcpy(s,(str+2));
例str三单元数组该数组每单元都指针些指针各指向字符串指针数组名str作指针指向数组第0号单元类型char指向类型char
str指针类型char所指向类型char指向址字符串"Hello,this is a sample!"第字符址即’H’址
str+1指针指向数组第1号单元类型char指向类型char
(str+1)指针类型char所指向类型char指向"Hi,good morning"第字符’H’等等
面总结数组数组名问题声明数组TYPE array[n]则数组名称array两重含义:第代表整数组类型TYPE [n];第二指针该指针类型TYPE该指针指向类型TYPE数组单元类型该指针指向内存区数组第0号单元该指针自占单独内存区注意数组第0号单元占据内存区同该指针值能修改即类似array++表达式错误
同表达式数组名array扮演同角色
表达式sizeof(array)数组名array代表数组本身故sizeof函数
测整数组
表达式arrayarray扮演指针表达式结数组第0号单元值sizeof(array)测数组单元
表达式array+n(其n=012)array扮演指针故arr
ay+n结指针类型TYPE指向类型TYPE指向数组第n号单元故sizeof(array+n)测指针类型
例十:
int array[10];
int (ptr)[10];
ptr=&array;
例ptr指针类型int ()[10]指向类型int [10]
我用整数组首址初始化语句ptr=&arrayarray代表数组本身
本节提函数sizeof()我问问sizeof(指针名称)测究
竟指针自身类型呢指针所指向类型答案前者例:
int (ptr)[10];
则32位程序:
sizeof(int()[10])==4
sizeof(int [10])==40
sizeof(ptr)==4
实际sizeof(象)测都象自身类型别类型
第六章指针结构类型关系
声明指向结构类型象指针
例十:
struct MyStruct
{
int a;
int b;
int c;
}
MyStruct ss={20,30,40};//声明结构象ss并ss三员初始
化203040
MyStruct ptr=&ss;//声明指向结构象ss指针类型
MyStruct,指向类型MyStruct
int pstr=(int)&ss;//声明指向结构象ss指针
类型指向类型ptr同
请问通指针ptr访问ss三员变量
答案:
ptr->a;
ptr->b;
ptr->c;
请问通指针pstr访问ss三员变量
答案:
pstr;//访问ss员a
(pstr+1);//访问ss员b
(pstr+2)//访问ss员c
呵呵虽我我MSVC++60调式述代码要知道使用p
str访问结构员规说明规让我看看通指
针访问数组各单元:
例十二:
int array[3]={35,56,37};
int pa=array;
通指针pa访问数组array三单元:
pa;//访问第0号单元
(pa+1);//访问第1号单元
(pa+2);//访问第2号单元
格式看倒与通指针访问结构员规格式
所C/C++编译器排列数组单元总各数组单元存放连续存储区单元单元间没空隙存放结构象各员某种编译环境能需要字齐或双字齐或者别齐需要相邻两员间加若干quot;填充字节"导致各员间能若干字节空隙
所例十二即使pstr访问结构象ss第员变量a能保证(pstr+1)定能访问结构员b员a员b间能若干填充字节说定(pstr+1)访问些填充字节呢证明指针灵性要目想看看各结构员间底没填充字节
嘿倒错
通指针访问结构员确应该象例十二使用指针ptr
第七章指针函数关系
指针声明指向函数指针
int fun1(char,int);
int (pfun1)(char,int);
pfun1=fun1;
int a=(pfun1)("abcdefg",7);//通函数指针调用函数
指针作函数形参函数调用语句用指针表达式作
实参
例十三:
int fun(char);
int a;
char str[]="abcdefghijklmn";
a=fun(str);
int fun(chars)
{
int num=0;
for(int i=0;i
{
num+=s;s++;
}
return num;
)
例函数fun统计字符串各字符ASCII码值前面说数组名字指针函数调用str作实参传递给形参s实际str值传递给ss所指向址str所指向址致strs各自占用各自存储空间函数体内s进行自加1运算并意味着同str进行自加1运算
第八章指针类型转换
我初始化指针或给指针赋值赋值号左边指针赋值号右边指针表达式我前面所举例绝数情况指针类型指针表达式类型指针所指向类型指针表达式所指向类型
例十四:
1 float f=123;
2 float fptr=&f;
3 int p;
面例假我想让指针p指向实数f应该搞用面语句
p=&f;
指针p类型int指向类型int表达式&f结
指针指针类型float,指向类型float两者致直接赋值行至少我MSVC++60指针赋值语句要求赋值号两边类型致所指向类型致其编译器我没试家试试实现我目需要进行"强制类型转换":
p=(int)&f; 指针p我需要类型所指向类型改TYEPTYPE
语格式:
(TYPE)p;
强制类型转换结新指针该新指针类型TYPE指向类型TYPE指向址原指针指向址原指针p切属性都没修改
函数使用指针作形参函数调用语句实参形参结合程发指针类型转换
例十五:
void fun(char);
int a=125,b;
fun((char)&a);
void fun(chars)
{
char c;
c=(s+3);(s+3)=(s+0);(s+0)=c;
c=(s+2);(s+2)=(s+1);(s+1)=c;
}
}
注意32位程序故int类型占四字节char类型占字节函数fun作用整数四字节顺序颠倒注意函数调用语句实参&a结指针类型int 指向类型int形参指针类型char指向类型char实参形参结合程我必须进行int类型char类型转换结合例我想象编译器进行转换程:编译器先构造临指针 chartemp执行temp=(char)&a再temp值传递给s所结:s类型char,指向类型char指向址a首址
C语言指针其实也是变量,只不过指针变量存储的是其它变量的地址。
C语言里对变量取地址:&变量名,对指针取指向的变量的值:指针。
指针有类型的区别,即指针指向什么类型,要在定义指针时指定类型。
定义举例:int p;//p是指向int类型的指针,只能把int变量地址赋值给p。
用指针有很多安全隐患,容易内存溢出,泄漏。
java应该是出于安全考虑不用指针,C#语言也是。
以上就是关于什么是C语言的指针,能不能举例说明一下啊大侠帮帮忙!!全部的内容,包括:什么是C语言的指针,能不能举例说明一下啊大侠帮帮忙!!、C语言(关于指针)、c语言 指针 取值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)