C语言指针学习(转载)

http://blog.chinaunix.net/uid-22889411-id-59688.html

c语言中指针学习:

入门介绍:

int i=30;//定义一个int型的变量i(两个字节的内存,不同系统可能情况不一样,将这两个字节的内存命名为i,将30转成二进制存入这两个内存中)

int *pi;//定义一个指针变量(与定义普通变量并没有什么不同,差异体现在其存入的内容,这个指针的内容是一个指向int型变量的地址。在32位机器中,其长度为4个字节)

pi=&i;//将i的地址存入pi中,假设i的地址是0x89770708

printf(“%d”,*pi);//打印出pi中内容指向的int的内容。pi中的内容是0x89770708,指向的是30,所以打印出30。也就是说*pi就是i

习题:

char  a,*pa

a=10

pa=&a

*pa=20//可以用*pi来更改变量的值

printf( “%d”, a)//输出应该还是20

指针与数组:

~~int i,a[]={1,2,3,4,5};

for(i=0;i<=5;i++){printf(“%d”,a[i]);}

~~ int i,a[]={1,2,3,4,5};

for(i=0;i<=5;i++){printf(“%d”,*(a+i));}

~~ int i,*pa,a[]={1,2,3,4,5};

for(i=0;i<=5;i++){printf(“%d”,pa[i]);}

~~ int i,*pa,a[]={1,2,3,4,5};

for(i=0;i<=5;i++){printf(“%d”,*(pa+i));}   是不是说明指针与数组名无差?并不是!

~~int i,*pa,a[]={1,2,3,4,5};

  pa=a;

  for(i=0;i<5;i++){printf(“%d”,*pa);pa++}//这里,指针值被修改。如果改成a++会发生编译出错。

  实际上面的指针是指针变量,而数组名是指针常量,其值不可被修改。

  是否存在指针常量?有的!

 int *const pa=a;//这里定义一个指针常量,指向int型的数据,然后把a赋给了pa,相当于:

int *const pa;pa=a;//因为数组名a就表示这个数组的地址,所以无需使用&。

       //注意这里定义指针常量的格式不是int const *pa;

const是一个声明常量的关键字。int const *pa,与const int *pa意义一致。也就是说const 与 int的顺序无所谓。

 

对比int const *pa与int *const pa

int const *pi:

****************代码开始*******************

int i1=30;
int i2=40;
const int * pi=&i1;//等价于int const *pi=&i1;
pi=&i2;    //4.注意这里,pi可以在任意时候重新赋值一个新内存地址
i2=80;    //5.想想看:这里能用*pi=80;来代替吗?当然不能
printf( “%d”, *pi ) ;  //6. 输出是80

****************代码结束*********************

const int * pi=&i1;//等价于int const *pi=&i1;const修饰的是*pi,所以*pi的值是不可以被更改的。而pi本身是一个变量(pi前面没有const修饰),所以pi可以更改,同时pi指向的int值也是可以更改的。(重点在于看const到底修饰哪些部分,被const修饰的部分是不可以被改变的。)

int *const pa

*************代码开始 ***************
int i1=30;
int i2=40;
int * const pi=&i1;
//pi=&i2;    4.注意这里,pi不能再这样重新赋值了,即不能再指向另一个新地址。
   //pi的前方有const修饰了它。所以我已经注释了它。
i1=80;    //5.想想看:这里能用*pi=80;来代替吗?可以,这 里可以通过*pi修改i1的值。
     //请自行与前面一个例子比较。
printf( “% d”, *pi ) ;  //6.输出是80
***************代码结束 *********************

pi值不能进行修改了。它永远指向初始化时的内存地址。但是可以通过*pi来修改i的值。

 

补充的三种情况:

**********begin*****************

const int i1=40;

int *pi;

pi=&i1; //这样可以吗?不行,VC下是编译错。

//const int 类型的i1的地址 是不能赋值给指向int 类型地址的指针pi的。否则pi岂不是能修改i1的值了吗!

pi=(int* ) &i1;  // 这样可以吗?强制类型转换可是C所支持的。
 //VC下编译通过,但是仍 不能通过*pi=80来修改i1的值。***********end***************

//*********begin****************
const int i1=40;
const int * pi;
pi=&i1;//两个类型相同,可以这样赋值。很显然,i1的值无论是通过pi还是i1都不能修 改的。
//*********end*****************

//***********begin****************
int i
const int * const pi=&i;//你能想象pi能够作什么操作吗?pi值不能改,也不能通过pi修改i的值。因为不管是*pi还 是pi都是const的。
//************end****************

C语言中函数参数传递讲解:

值传递,地址传递,引用传递

*************************************

void Exchg1(int x, int y)
{

//x=a;y=b;在函数调用时隐含了这两句
int tmp;
tmp=x;
x=y;
y=tmp;
printf (“x=%d,y=%d ”,x,y)
}
void main()
{
int a=4,b=6;
Exchg1 (a,b) ;
printf(“a=%d,b=%d ”,a,b)
}

*************************************

以上为值传递过程。我们发现对于x,y的操作是不会对a与b的值有任何的影响的。也就相当于:

int x; int a=5; x=a; x=x+4;得到x=9,而a=5;只是把a的值赋给了x,x做运算,对于a的值没有任何改变!!

*************************************

Exchg2(int *px, int *py)
{
int tmp=*px;
*px=*py;
*py=tmp;
print(“*px=%d,*py=%d ”,*px,*py);
}
main()
{
int a=4;
int b=6;
Exchg2( &a,&b);
Print (“a=%d,b=%d ”, a, b);
}

***************************************

*************************************

Exchg2(int &x, int &y)
{
int tmp=x;
x=y;
y=tmp;
print(“x=%d,y=%d ”,x,y);
}
main()
{
int a=4;
int b=6;
Exchg2(a,b);
Print(“a=%d,b=%d ”, a, b);
}

关于指针的一个补充:

int a;

int b=exchange(&a,9);

exchange函数如下:

exchange(int *xp,int y){

         int x=*xp;

         *xp=y;

         return x;

}

指针的指针:

short int i=50;

short int *pi;

pi=&i;

short int **ppi;

ppi=&pi;

得到:

ppi是什么?pi的地址

*ppi是什么?pi的值(也就是i的地址)

**ppi是什么?i的值(也就是*pi)

ps:还有函数的指针,查看html文档

原文地址:https://www.cnblogs.com/litian0605/p/5249778.html