2015.8.5关于指针的个人理解

1、要区分指针的类型指针所指向的类型

1.1指针的类型:把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。

eg:   int *a;去掉‘a’,得到“int *”,所以该指针的类型就是int *,即该指针是一个指向整型变量的指针;

       char *str;去掉“str”,得到"char *",所以该指针的类型就是char *,即该指针是一个指向char型变量的指针;

       int **ptr;去掉“ptr”,得到“int **”,故改指针的类型就是“int **,即该指针是一个指向整型指针变量的指针”

       int (*ptr)[3];去掉“ptr”,得到“int(*)[3]”,故改指针的类型就是int(*)[3],即该指针是一个指向整型数组的指针。

1.2指针所指向的类型:把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。

eg:int *a;去掉‘a’和‘*’,得到“int”,故该指针所指向的类型是int型;

      char *str;去掉“str”和‘*’,得到“char”,故该指正指向的类型是char型;

      int **ptr;去掉“ptr”和‘*’,得到“int *”,故该指针指向的类型是int *型;

      int (*ptr)[3];去掉“ptr”和‘*’,得到int [3],故该指针指向的是int [3]型。

2、要理解‘*’在不同场合的不同意义

1 void main()
2 {
3 int *a;
4 int b=10;
5 
6 a=&b;
7 
8 printf(”%d“,*a);
9 }

第3行int *a(定义的时候)‘*’只是表示此时定义的这个变量是指针变量

第8行中的*a,其中的‘*’表示”指向“,”*a“表示指针变量a所指向的变量,也就是b

3、不能给野指针瞎赋值

eg:

1 void swap(int *p1,int *p2)
2 {
3 int *temp;
4 *temp=*p1;
5 *p1=*p2;
6 *p2=*temp;
7 }

第3行定义了一个指向整型变量的指针temp,接下来在第4行就给*temp赋值。这是错误的。

因为*temp是指针temp所指向的变量,但是由于未给temp赋值,所以temp并没有确定的值,所以temp所指向的内存单元也就是不可预见的。那么对*temp赋值就是向一个未知的存储单元赋值,但是这个未知的存储单元有可能是一个存放着重要数据的单元,这样就会造成系统运行错误。

4、数组名和指针变量的区别

1 int i, *pa, a[] = {3,4,5,6,7,3,7,4,4,6}; 
2 pa = a; 
3 for (i = 0; i <= 9; i++) 
4 { 
5 printf("%d
", *pa); 
6 pa++; /*注意这里,指针值被修改*/ 
7 }

如上述代码所示,在循环体中我们采用pa++来输出数组中所有元素,但是如果将循环体中的pa改成a还对吗?

答案是不对,为什么呢?因为pa是一个指针变量,而数组名a实质上是一个指针常量,常量的值是不允许修改的,其指向的是数组的首地址。

5、函数参数传递的三种不同方式

5.1、值传递

eg:

void Exchg1(int x, int y) /* 定义中的x,y变量被称为Exchg1
函数的形式参数*/ 
{ 
int tmp; 
tmp = x; 
x = y; 
y = tmp; 
printf("x = %d, y = %d.
", x, y); 
} 


main() 
{ 
int a = 4,b = 6; 
Exchg1(a, b); /*a,b变量为Exchg1函数的实际参数。*/ 
printf("a = %d, b = %d.
”, a, b); 
return(0); 
} 

上述代码的运行结果是:

x=6,y=4

a=4,b=6

函数Exchg1在被调用时只是把实参a,b的值传递给了形参x,y,而在函数Exchg1内对变量a,b本身没有进行别的任何操作,在该函数体内操作的只是变量x,y,故在变量a,b内存储的值还是没有发生改变。以上这种函数参数传递方式叫作值传递方式。

5.2、地址传递方式

 1 void Exchg1(int *x, int *y) /* 定义中的x,y变量被称为Exchg1
 2 函数的形式参数*/ 
 3 { 
 4 int tmp; 
 5 tmp = *x; 
 6 *x = *y; 
 7 *y = tmp; 
 8 printf("*x = %d, *y = %d.
", *x, *y); 
 9 } 
10 
11 
12 main() 
13 { 
14 int a = 4,b = 6; 
15 Exchg1(&a, &b); /*a,b变量为Exchg1函数的实际参数。*/ 
16 printf("a = %d, b = %d.
”, a, b); 
17 return(0); 
18 } 

上述代码的运行结果是:

*x=6,*y=4

a=6,b=4

函数Exchg1的入口参数是两个指向整型变量的指针,在该函数体内,这两个指针所指向的内存单元的值被交换。于是乎在主函数中调用该函数时,传递给该函数的是变量a,b在内存单元中的地址,而该函数执行的操作正是将这两个单元地址里面的值进行交换,故该函数运行结束之后a,b的值已经进行了交换。这种函数参数的传递方式叫作地址传递方式。

5.3、引用传递方式

 1 void Exchg3(int &x, int &y) /* 注意定义处的形式参数的格式与
 2 值传递不同*/ 
 3 { 
 4 int tmp = x; 
 5 27
 6 x = y; 
 7 y = tmp; 
 8 printf("x = %d, y = %d.
", x, y); 
 9 } 
10 main() 
11 { 
12 int a = 4; 
13 int b = 6; 
14 Exchg3(a, b); /*注意:这里调用方式与值传递一样*/ 
15 printf("a = %d, b = %d.
”, a, b); 
16 } 

这种函数参数传递方式叫作引用传递方式,为什么叫作引用传递方式呢?因为在形参x、y前都有一个取地址符号“&”。有了这个,调用Exchg3时函数会将a、b 分别代替了x、y了,我们称:x、y分别引用了a、b变量。这样函数里头操作的其实就是实参a、b本身了,也就是说函数里是可以直接修改到a、b的值了。

 6、最后的一点补充:

6.1:如果指针变量p已指向数组中的一个元素,则p+1指向的是同一数组中的下一个元素,p-1指向的是同一数组中的上一个元素。

caution:执行p+1时并不是将p的值简单地加1,而是加上一个数组元素所占用的字节数

6.2:在32位程序里,所有类型的指针的值都是一个32位整数,因为32位程序里内存地址全都是32位长

原文地址:https://www.cnblogs.com/wan0807/p/4707420.html