C_Learning(2)

/指针

  /指针变量指向一个变量的地址  

  /给指针变量赋的值只能是地址

 

  /指针变量的赋值   

    /{ int a; int *p; p=&a; } or { int a; int *p=&a; }   

    /指针必须先定义后使用   

    /不能把一个具体的数赋给指针

  

  / &是取地址运算符,&q 表示取变量 q 的地址  

  / *是指针运算符,*p 表示返回指定地址内变量的值  

  / 因此,p=&q 表示的是地址;scanf 中 &q 表示往该地址写入操作数;printf 中的 q 表示输出变量 q 地址中存放的操作数;*p 表示输出变量 p 指向的地址中存放的操作数

 

  / &* 和 *& 的区别   

    / & * 的运算优先级相同,按自右向左方向结合   

    / &* 表示先进行指针运算,再取地址;(&*p=&(*p)=&a)——是一个地址   

    / *& 表示先取地址,再进行指针运算;(*&p=*(&p))——是地址中的操作数      

 

  / 指针的自增自减(p++,p--)造成内存地址按照其所指向的数据类型的直接长度的增或减     

 

  / 指针与数组   

    / { int a[100],*p; p=a;}   

    / p=a表示将数组 a[100] 的首地址赋给指针变量 p,即 p=&a[0]   

    / *(p+n)=*(a+n) ,表示数组 a[100] 第n个元素   

    / &a[i][j]、(a[i]+j) 表示第 i 行第 j 列的元素"地址"!

 

  / 指针与字符串   

    / { char *str="hello"; printf ("%s",str); }   

    / 这里不是将 hello 赋给指针变量 str ,而是把字符串 "hello" 的首字母地址赋给 str     

    

  / 指针数组   

    / { char *str[]={"abc","def","ghi"} }   

    / 一个数组,其元素均为指针类型数据,则称为指针数组   

    / 由于字符型数组的长度必须大于最长元素的长度,因此,使用指针数组可以大大减少这样的存浪费     

 

  / 指向指针的指针   

    / 这种问题只有在实战当中才能得到深刻理解,实例参见:count_even.c / count_even_2.c / count_even_3.c     

 1 // 统计数组中偶数的个数
 2 
 3 #include <stdio.h>
 4 
 5 int main()
 6 {
 7         int a[10], *p, **q, i, n=0;
 8         printf ("Please input:");
 9         for (i=0; i<10; i++)
10                 scanf ("%d",&a[i]);
11         p=a;
12         q=&p;
13         printf ("The array is :");
14         for (i=0; i<10; i++)
15         {
16                 if (*(*q+i)%2==0)
17                 {
18                         n++;
19                         printf ("%5d",*(*q+i));
20                 }
21         }
22         printf ("\n");
23         printf ("The number is :%d.\n",n);
24         
25         return 0;
26 }
count_even.c

 

 1 // 统计数组元素中偶数的个数(2)
 2 
 3 #include <stdio.h>
 4 
 5 int main()
 6 {
 7     int a[10], *p, **q, n=0;
 8     printf ("Please input:\n");
 9     for (p=a; p-a<10; p++)
10     {
11         q=&p;
12         scanf ("%d",*q);
13     }
14     printf ("The array is:");
15     for (p=a; p-a<10; p++)
16     {
17         q=&p;
18         if (**q%2==0)
19         {
20             printf ("%5d",**q);
21             n++;
22         }
23     }
24     printf ("\n");
25     printf ("The number is:%d.\n",n);
26     
27     return 0;
28 }
count_even2.c
 1 // 统计数组元素中的偶数个数(3)
 2 
 3 #include <stdio.h>
 4 
 5 int main()
 6 {
 7     int a[10], *p, n=0;
 8     printf ("Please input:\n");
 9     for (p=a; p-a<10; p++)
10     {
11         scanf ("%d",p);
12     }
13     printf ("The array is:\n");
14     for (p=a; p-a<10; p++)
15     {
16         if (*p%2==0)
17         {
18             printf ("%5d",*p);
19             n++;
20         }
21     }
22     printf ("\n");
23     printf ("The number is:%d.",n);
24 
25     return 0;
26 }
count_even3.c

  

  / 指针变量作函数参数   

    / 实例参见swap.c / swap2.c     

 1 // 交换两个数swap.c
 2 
 3 #include <stdio.h>
 4 
 5 // 定义交换函数swap
 6 int swap(int *a, int *b);
 7 
 8 // 主函数
 9 int main()
10 {
11     int x, y, *p_x, *p_y;
12     printf ("Please input two number:\n");
13     scanf ("%d,%d", &x, &y);
14     p_x=&x;
15     p_y=&y;
16     swap(p_x, p_y);
17     printf ("x=%d or *p_x=%d", x, *p_x);
18     printf ("y=%d or *p_y=%d", y, *p_y);
19     
20     return 0;
21 }
22 
23 // 交换函数swap定义区域
24 int swap(int *a, int *b)
25 {
26     int tmp;
27     tmp=*a;
28     *a=*b;
29     *b=tmp;
30     
31     return 0;
32 }
33 
34 
35 // 为什么不能使用如下源程序swap2.c?
36 /* 
37 #include <stdio.h>
38 
39 int swap(int a, int b);
40 
41 int main()
42 {
43     int x, y;
44     printf ("please input two number:\n");
45     scanf ("%d%d", &x, &y);
46     swap(x,y);
47     printf ("x=%d.\n", x);
48     printf ("y=%d.\n", y);
49     
50     return 0;
51 }
52 
53 int swap(int a. int b)
54 {
55     int tmp;
56     tmp=a;
57     a=b;
58     b=tmp;
59 }
60 */
61 // 在函数调用过程中,主调用函数与被调用函数之间的数值传递是单向的,即只能把实参的值传递给形参,而不能把形参传递给实参。因此,如果使用swap2.c,形参的值会发生改变,但实参的值却不会发生任何变化。
62 // 而使用指针来传递参数,既可以减少值传递带来的开销,也可以使函数调用不产生值传递,即只要保证指针指向的地址是正确的即可。
swap.c
 1 // 交换两个数swap2.c
 2 
 3 #include <stdio.h>
 4 
 5 int swap(int a, int b);
 6 
 7 int main()
 8 {
 9     int x, y;
10     printf ("please input two number:\n");
11     scanf ("%d%d", &x, &y);
12     swap(x,y);
13     printf ("x=%d.\n", x);
14     printf ("y=%d.\n", y);
15     
16     return 0;
17 }
18 
19 int swap(int a. int b)
20 {
21     int tmp;
22     tmp=a;
23     a=b;
24     b=tmp;
25 }
swap2.c

 

  / 指向函数的指针   

    / 指针可以指向函数,一个函数在编译时被分配给一个入口地址,这个函数的入口地址就称为函数的指针   

    / 一个函数可以返回一个整型值、字符值、实型值等,也可以返回指针型的数据,即地址   

    / 实例见 perimeter.c     

 1 // 根据指针函数的概念,使用指针函数计算长方形周长
 2 
 3 #include <stdio.h>
 4 
 5 int *per(int a, int b);
 6 int perimeter;
 7 
 8 int main()
 9 {
10     int width, lenth;
11     int *result;
12     printf ("please input width and lenth:");
13     scanf ("%d%d", &width, &lenth);
14     result=per(width, lenth);
15     printf ("\nthe perimeter is :%d", *result);
16     
17     return 0;
18 }
19 
20 int *per(int a, int b)
21 {
22     int *p;
23     p=&perimeter;
24     perimeter=2*(a+b);
25     return p;
26 }
perimeter.c

 

  / 指针数组作 main 函数的参数   

    / main 函数可以是无参函数,也可以是有参函数   

    / main 函数的带参形式:main(int argc, char *argv[])   

    / argc 记录了命令和参数的个数,指针数组 argv[] 的大小由命令和参数的个数决定   

    / 实例见main_pointer.c

 1 // main 函数的有参实例
 2 
 3 #include <stdio.h>
 4 
 5 main(int argc, char *argv[])
 6 {
 7     printf ("the list of parameter:\n");
 8     printf ("command:\n");
 9     printf ("%s\n",*argv);
10     printf ("the number of parameter:");
11     printf ("%d",argc);
12 }
13 
14 // 运行的结果如下:
15 the list of parameter:
16 command:
17 C:\Administrator\Desktop\jan5\main_parameter.exe
18 the number of parameter:1
main_parameter.c

posted @ 2013-10-21 18:00  Jan5  阅读(335)  评论(0编辑  收藏  举报