zoukankan      html  css  js  c++  java
  • 全国计算机等级考试二级教程-C语言程序设计_第8章_地址和指针

    面试:

    unsigned int *p1 = #
    int *p2 = #

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 main()
     7 {
     8     int num = -1;
     9     unsigned int *p1 = &num;
    10     int *p2 = &num;
    11 
    12     printf("%u,%d", *p1, *p2);
    13 
    14     system("pause");
    15 }

    输出结果:

    4294967295,-1请按任意键继续. . .

    //左边是指针指向内容的大小,右边是指针的大小

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 main()
     7 {
     8     int *p;
     9     double *pb;
    10     //左边是指针指向内容的大小,右边是指针的大小
    11     printf("%d,%d
    ", sizeof(*p), sizeof(p));
    12     printf("%d,%d
    ", sizeof(*pb), sizeof(pb));
    13 
    14     system("pause");
    15 }

    //指针相减,如果值为正,p1在p2后面,值为负,p1在p2后面
    //具体之差就意味着指针之间相隔几个元素的大小
    //具体之差不是地址之差,而是地址之差除以指向元素的大小

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 main()
     7 {
     8     int a = 10;
     9     int b = 20;
    10     int *p1 = &a;
    11     int *p2 = &b;
    12 
    13     int num = p1 - p2;
    14     //指针相减,如果值为正,p1在p2后面,值为负,p1在p2后面
    15     //具体之差就意味着指针之间相隔几个元素的大小
    16     //具体之差不是地址之差,而是地址之差除以指向元素的大小
    17     printf("%x,%x,%d", p1, p2, num);
    18 
    19     system("pause");
    20 }

    1、  若有p=a(p指向数组a),则:

    np++(或p+=1),表示p指向下一元素。

    n*p++与*(p++)等价。同样优先级,结合方向为自右向左。

    n*(p++) 与*(++p)。

          前者是先取*p的值,后使p值加1,相当于a[i++];后者是先使p加1,再取*p,相当于a[++i]。

    n(*p)++表示p所指向的元素值加1,而非指针值加1。

    2、 a是一个数组

     int  *p=a; 

     p++; 

      p++是先引用,再自增,自增一个sizeof(指针指向的类型)的大小。

      ++指针在数组内部向前移动一个元素的大小

      p=p+1; 

      指针在数组内部向前移动一个元素的大小

       *p++  等价于  *(p++) ,   ++是先引用再自增

       指针在数组内部向前移动一个元素的大小

     ++p  先自增,再引用

     *(p++)  和 *(++p)的区别?

    *(p++) 先引用*p,再自增p++,a[i++]

      *(++p) 先自增,再引用

    (*p)++   取出指针指向的内容自增一下

      1 #define _CRT_SECURE_NO_WARNINGS
      2 
      3 #include<stdio.h>
      4 #include<stdlib.h>
      5 
      6 main1()//p++
      7 {
      8     int a[10] = { 1,2,3,4,5 ,6,7,8,9,10 };
      9     int i;
     10     int *p = a;
     11 
     12     for (i = 0;i < 10;i++)
     13     {
     14         printf("%d,%x
    ", a[i], &a[i]);
     15     }
     16 
     17     printf("%x
    ", p);
     18 
     19     printf("%x
    ", p++);//++就是先引用,再自增,自增一个sizeof指针指向的类型的大小
     20 
     21     printf("%x
    ", p);//++指针在数组内部向前移动一个元素的大小
     22 
     23     system("pause");
     24 }
     25 
     26 main2()//++p
     27 {
     28     int a[10] = { 1,2,3,4,5 ,6,7,8,9,10 };
     29     int i;
     30     int *p = a;
     31 
     32     for (i = 0;i < 10;i++)
     33     {
     34         printf("%d,%x
    ", a[i], &a[i]);
     35     }
     36 
     37     printf("%x
    ", p);
     38 
     39     printf("%x
    ", ++p);//++就是先自增,再引用
     40 
     41     printf("%x
    ", p);//++指针在数组内部向前移动一个元素的大小
     42 
     43     system("pause");
     44 }
     45 
     46 main3()//p = p + 1
     47 {
     48     int a[10] = { 1,2,3,4,5 ,6,7,8,9,10 };
     49     int i;
     50     int *p = a;
     51 
     52     for (i = 0;i < 10;i++)
     53     {
     54         printf("%d,%x
    ", a[i], &a[i]);
     55     }
     56     
     57     printf("%x
    ", p);
     58     p = p + 1;//指针在数组内部向前移动一个元素的大小
     59     printf("%x
    ", p);
     60 
     61     system("pause");
     62 }
     63 
     64 main4()//*p++
     65 {
     66     int a[10] = { 1,2,3,4,5 ,6,7,8,9,10 };
     67     int i;
     68     int *p = a;
     69 
     70     for (i = 0;i < 10;i++)
     71     {
     72         printf("%d,%x
    ", a[i], &a[i]);
     73     }
     74 
     75     printf("%x
    ", p);
     76     printf("%d
    ", *p++);//++先引用*p,再自增p++,*p=1,等价于*(p++),类似a[i++]
     77     printf("%x
    ", p);//指针在数组内部向前移动一个元素的大小
     78     printf("%d
    ", a[0]);
     79 
     80     system("pause");
     81 }
     82 
     83 main5()//*(++p)
     84 {
     85     int a[10] = { 1,2,3,4,5 ,6,7,8,9,10 };
     86     int i;
     87     int *p = a;
     88 
     89     for (i = 0;i < 10;i++)
     90     {
     91         printf("%d,%x
    ", a[i], &a[i]);
     92     }
     93     
     94     printf("%x
    ", p);
     95     printf("%d
    ", *(++p));//++先自增,再引用
     96     printf("%x
    ", p);
     97     printf("%d
    ", a[0]);
     98 
     99     system("pause");
    100 }
    101 
    102 main6()//(*p)++
    103 {
    104     int a[10] = { 1,2,3,4,5 ,6,7,8,9,10 };
    105     int i;
    106     int *p = a;
    107 
    108     for (i = 0;i < 10;i++)
    109     {
    110         printf("%d,%x
    ", a[i], &a[i]);
    111     }
    112 
    113     printf("%x
    ", p);
    114     printf("%d
    ", (*p)++);//取出指针指向的内容自增一下
    115     printf("%x
    ", p);
    116     printf("%d
    ", a[0]);
    117 
    118     system("pause");
    119 }
    120 
    121 main()//++(*p)
    122 {
    123     int a[10] = { 1,2,3,4,5 ,6,7,8,9,10 };
    124     int i;
    125     int *p = a;
    126 
    127     for (i = 0;i < 10;i++)
    128     {
    129         printf("%d,%x
    ", a[i], &a[i]);
    130     }
    131     
    132     printf("%x
    ", p);
    133     printf("%d
    ", ++(*p));//先自增,再引用
    134     printf("%x
    ", p);
    135     printf("%d
    ", a[0]);
    136 
    137     system("pause");
    138 }

    //地址的比较没有意义,只能判断哪个地址也就是内存编号比较靠前
    //不在数组,没有太大意义

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 main()
     7 {
     8     int num1 = 18, num2 = 28;
     9     int *p1 = &num1;
    10     int *p2 = &num2;
    11 
    12     printf("num1=%d,*p1=%d
    ", num1, *p1);
    13     printf("num2=%d,*p2=%d
    ", num2, *p2);
    14 
    15     printf("%x,%x
    ", &num1, p1);
    16     printf("%x,%x
    ", &num2, p2);
    17 
    18     //地址的比较没有意义,只能判断哪个地址也就是内存编号比较靠前
    19     //不在数组,没有太大意义
    20     if (p1 > p2)
    21     {
    22         printf("p1的地址比较靠后");
    23     }
    24     else
    25     {
    26         printf("p2的地址比较靠后");
    27     }
    28 
    29     system("pause");
    30 }

    指针比较 

    if (p1 == p2)为真,则p1和p2指向同一个变量

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 main()
     7 {
     8     int num = 10;
     9     int *p1 = &num;
    10     int *p2 = &num;
    11 
    12     if (p1 == p2)
    13     {
    14         printf("指向同一个变量
    ");
    15     }
    16     else
    17     {
    18         printf("不是指向同一个变量");
    19     }
    20 
    21     //num,*p1,*p2三者改变其中一个,另外两个都会改变
    22     num = 3;//直接赋值
    23     printf("%d,%d,%d
    ", num, *p1, *p2);
    24 
    25     *p1 = 4;//间接赋值
    26     printf("%d,%d,%d
    ", num, *p1, *p2);
    27 
    28     *p2 = 5;//间接赋值
    29     printf("%d,%d,%d
    ", num, *p1, *p2);
    30 
    31     system("pause");
    32 }

    p++;//指针++,就是按照指针类型的大小,前进一个类型的大小,如果是int,前进4个字节
    printf("%d", *p);//指针++,只有在数组内部才有意义

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 #include<windows.h>
     6 
     7 main()
     8 {
     9     int num = 100;
    10     int *p = &num;
    11     p++;//指针++,就是按照指针类型的大小,前进一个类型的大小,如果是int,前进4个字节
    12     printf("%d", *p);//指针++,只有在数组内部才有意义
    13 
    14     system("pause");
    15 }

    int *p1 = &num;//地址的赋值
    int *p2 = p1;//指针的赋值
    //num,*p1,*p2一个改变,其他两个都会跟着改变

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 main()
     7 {
     8     int num = 10;
     9     int *p1 = &num;//地址的赋值
    10     int *p2 = p1;//指针的赋值
    11     //num,*p1,*p2一个改变,其他两个都会跟着改变
    12 
    13     *p2 = 3;
    14 
    15     printf("%d,%d,%d", num, *p1, *p2);
    16 
    17     system("pause");
    18 }

    //.c比较宽泛,所以只是警告
    //.cpp就是类型不匹配
    //整数与指针最好不要直接运算

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 main()
     7 {
     8     int a = 5;
     9 
    10     int *p = a;
    11 
    12     *p = 3;
    13     //.c比较宽泛,所以只是警告
    14     //.cpp就是类型不匹配
    15     //整数与指针最好不要直接运算
    16 
    17     system("pause");
    18 }

    //指针存储的是地址,地址是首地址,从哪里开始
    //从哪里结束,由类型决定
    //类型决定长度,决定如何解析

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 main()
     7 {    
     8     char ch = 'A';
     9     int num = 45;
    10     double db = 12.5;
    11     char *p1 = &ch;
    12     int *p2 = &num;
    13     double *p3 = &db;
    14 
    15     printf("%x,%x,%x
    ", p1, p2, p3);
    16     printf("%c,%d,%f
    ", *p1, *p2, *p3);
    17     //指针存储的是地址,地址是首地址,从哪里开始
    18     //从哪里结束,由类型决定
    19     //类型决定长度,决定如何解析
    20 
    21     system("pause");
    22 }

    二级指针:

    第一,函数内部改变外部的指针变量用到二级指针

    第二,游戏外挂改变外部的指针变量

    函数调用,改变原来的数据,传地址,可以根据地址改变;传数据,就无法改变(形式参数会新建一个变量,接收实际参数的值)

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 void change(int *p)
     7 {
     8     *p = 99;
     9 }
    10 
    11 main()
    12 {
    13     int num = 10;
    14 
    15     int *p = &num;
    16 
    17     //change(10);传递实际参数,不会改变
    18     //change(num);传递实际参数,不会改变
    19     //change(*p);传递实际参数,不会改变
    20 
    21     change(p);
    22 
    23     printf("%d", num);
    24 
    25     system("pause");
    26 }

    int *p = &num;

     1 #define _CRT_SECURE_NO_WARNINGS
     2 
     3 #include<stdio.h>
     4 #include<stdlib.h>
     5 
     6 main()
     7 {
     8     int num = 10;
     9     int *p = &num;//&num是一个地址,是一个常量
    10     //p是一个指针变量,可以存储一个地址
    11     
    12     system("pause");
    13 }

    int * p;

    int * 是数据结构。

    p 是变量名字。

    * p 是以 p 的内容为地址的变量。


    指针:表示一些复杂的数据结构,快速的传递数据,使函数返回一个以上的值,能直接访问硬件,能够方便的处理字符串,是理解面向对象语言中引用的基础。

    总结:指针是C语言的灵魂。


    地址:内存单元的编号,从零开始的非负整数,范围:4G


    指针:

     1 #include <stdio.h>
     2 main()
     3 {
     4     int * p;        /* int *是数据类型,所谓int *类型就是存放int变量地址的类型,表示p变量存放的是int类型变量的地址
     5                     p是变量的名字 */
     6     int i = 3;
     7 
     8     int j;
     9 
    10     p = &i;        /* OK
    11                 1 p保存了i的地址,因此p指向i。
    12                 2 p不是i,i也不是p,更准确的说:修改p的值不影响i的值,修改i的值也不会影响p的值
    13                 3 如果一个指针变量指向了某个普通变量,则*指针变量 就完全等同于 普通变量
    14                 例子:如果p是个指针变量,并且p存放了普通变量i的地址,则p指向了普通变量i
    15                 *p 就完全等同于 i
    16                 或者说:在所有出现*p 的地方都可以替换成i
    17                 在所有出现i 的地方都可以替换成*p
    18                 *p 就是以 p 的内容为地址的变量
    19                 */
    20 
    21                 //p = i;        // ERROR,因为类型不一致,p只能存放int类型变量的地址,不能存放int类型变量的值
    22 
    23                 //p = 55;        // ERROR,原因同上
    24 
    25     j = *p;        //等价于j=i
    26 
    27     printf("i=%d,j=%d,*p=%d
    ", i, j, *p);
    28 }

    输出格式:


    i=3,j=3,*p=3
    请按任意键继续. . .


    a b 互换功能

    不能完成互换功能

     1 #include <stdio.h>
     2 void huhuan(int a, int b)        /*不能完成互换功能*/
     3 {
     4     int t;
     5     t = a;
     6     a = b;
     7     b = t;
     8 
     9     return;
    10 }
    11 main()
    12 {
    13     int a = 3;
    14     int b = 5;
    15 
    16     huhuan(a, b);
    17 
    18     printf("a=%d,b=%d", a, b);
    19 }

    可以完成互换功能

     p 是 int *,* p 是 int

     1 #include <stdio.h>
     2 void huhuan1(int * p, int * q)
     3 {
     4     int t;        /* 如果要互换*p和*q的值,则t必须定义成int,不能定义为int*,否则语法出错 */
     5 
     6     t = *p;        /* p是int *,* p int */
     7     *p = *q;
     8     *q = t;
     9 }
    10 main()
    11 {
    12     int a = 3;
    13     int b = 5;
    14 
    15     huhuan1(&a, &b);        /*
    16                         huhuan1(*p, *q);错误
    17                         huhuan1(a, b);错误
    18                         */
    19 
    20     printf("a=%d,b=%d", a, b);
    21 }

     

     * 的含义

    1 乘法


    2 定义指针变量

    出现在定义语句,代表定义了一个指针变量。

    int * p;

    定义了一个名字叫 p 的变量,int * 表示 p 只能存放 int 变量的地址


    3 指针运算符,间址运算符

    出现在执行语句,代表引用当前指针变量的内容。

    该运算符放在已经定义好的指针变量的前面

    如果 p 是一个已经定义好的指针变量

    则 * p 表示以 p 的内容为地址的变量


     * 与 & 是逆预算

     * 间址运算符,求当前地址的内容、元素

     & 地址运算符,求当前内容、元素的地址


    a[0]a[1] a[2]a[3] a[4]

     11   22    33   44    55

      p              q


    指针内容相减:

     * q - * p = 22;

    指针相减:

     q - p = 2;


    如何通过被调函数修改主调函数普通变量的值

    1 实参必须为该普通变量的地址

    2 形参必须为指针变量

    3 在被调函数中通过

     * 形参名 = ...

     的方式就可以修改主调函数相关变量的值

    1 #include <stdio.h>
    2 main()
    3 {
    4     int * p;        /*建议写这个*/
    5     int *p;        /*都一样*/
    6     int* p;        /*都一样*/
    7     int*p;        /*都一样*/
    8 }

     

    8.1 用指针指向两个变量,通过指针运算选出值小的那个数。

     1 #include <stdio.h>
     2 main()
     3 {
     4     int a, b, min, *pa, *pb, *pmin;
     5     pa = &a;
     6     pb = &b;
     7     pmin = &min;
     8     scanf("%d %d", pa, pb);
     9     printf("a=%d,b=%d
    ", a, b);
    10 
    11     *pmin = *pa;
    12     if (*pa > * pb)
    13     {
    14         *pmin = *pb;
    15     }
    16     printf("min=%d
    ", min);
    17 }

     

    8.2 编写函数 myadd(int * a, int * b) ,函数中把指针 a 和 b 所指的存储单元中的两个值相加,然后将和值作为函数值返回。在主函数中输入两个数给变量,把变量地址作为实参,传送给对应形参。

     1 #include <stdio.h>
     2 int myadd(int * a, int * b)
     3 {
     4     int sum;
     5     sum = *a + *b;
     6     return sum;
     7 }
     8 
     9 main()
    10 {
    11     int x, y, z;
    12     printf("Enter x,y:");
    13     scanf("%d %d", &x, &y);
    14     z = myadd(&x, &y);
    15     printf("%d+%d=%d
    ", x, y, z);
    16 }

    8.3 调用 swap 函数,交换主函数中变量 x 和 y 中的数据。

     1 #include <stdio.h>
     2 void swap(int *, int *);
     3 main()
     4 {
     5     int x = 30, y = 20;
     6     printf("(1)x=%d y=%d
    ", x, y);
     7     swap(&x, &y);
     8     printf("(4)x=%d y=%d
    ", x, y);
     9 }
    10 
    11 void swap(int * a, int * b)
    12 {
    13     int t;
    14     printf("(2)a=%d b=%d
    ", *a, *b);
    15     t = *a;
    16     *a = *b;
    17     *b = t;
    18     printf("(3)a=%d y=%d
    ", *a, *b);
    19 }

    8.4 编写函数 order(int * a, int * b) ,使调用函数中的第一个实参总是存放两个数中的较小的数,第二个参数存放两个数中较大的数。

     1 #include <stdio.h>
     2 void swap(int * x1, int * x2)
     3 {
     4     int t;
     5     t = *x1;
     6     *x1 = *x2;
     7     *x2 = t;
     8 }
     9 
    10 void order(int * a, int * b)
    11 {
    12     if (*a > * b)
    13     {
    14         swap(a, b);
    15     }
    16 }
    17 
    18 main()
    19 {
    20     int x, y;
    21     printf("Enter x,y:");
    22     scanf("%d %d", &x, &y);
    23     printf("x=%d y=%d
    ", x, y);
    24     order(&x, &y);
    25     printf("x=%d y=%d
    ", x, y);    
    26 }

     

    8.5 以下函数把主函数中变量 i 和 j 中存放较大数的那个地址作为函数值传回。

     1 #include <stdio.h>
     2 int * fun(int *, int *);        /* 函数说明语句 */
     3 main()
     4 {
     5     int * p, i, j;
     6     printf("Enter two number:");
     7     scanf("%d %d", &i, &j);
     8     p = fun(&i, &j);        /* p将得到i或j的地址 */
     9     printf("i=%d,j=%d,* p=%d
    ", i, j, *p);
    10 }
    11 
    12 int * fun(int * a, int * b)
    13 {
    14     if (*a > * b)
    15     {
    16         return a;
    17     }
    18     return b;
    19 }

     

    8.6 请编写程序,其功能是对传送过来的两个浮点数求出和值与差值,并通过形参传送回调用函数。

     1 #include "Stdio.h"
     2 void f(float x, float y, float *ps, float *pd)
     3 {
     4     *ps = x + y;
     5     *pd = x - y;
     6 }
     7 main()
     8 {
     9     float x, y, sum, diff;
    10     printf("input x y=?
    ");
    11     scanf("%f %f", &x, &y);
    12     f(x, y, &sum, &diff);
    13     printf("%f+%f=%f  %f-%f=%f", x, y, sum, x, y, diff);
    14 }

    8.7 请编写函数,对传送过来的三个数选出最大数和最小数,并通过形参传回调用函数。

     1 #include "Stdio.h"
     2 void f(int a, int b, int c, int *pmax, int *pmin)
     3 {
     4     *pmax = *pmin = a;
     5     if (*pmax > b)
     6     {
     7         *pmin = b;
     8     }
     9     if (*pmin < b)
    10     {
    11         *pmax = b;
    12     }
    13     if (*pmax > c)
    14     {
    15         *pmin = c;
    16     }
    17     if (*pmin < c)
    18     {
    19         *pmax = c;
    20     }
    21 }
    22 main()
    23 {
    24     int a, b, c, max, min;
    25     printf("input a b c=?
    ");
    26     scanf("%d %d %d", &a, &b, &c);
    27     f(a, b, c, &max, &min);
    28     printf("max=%d,min=%d", max, min);
    29 }

     

  • 相关阅读:
    Android:JNI之Java和C层的相互调用及多线程的回调实现
    高通sdm845_la2.0源码编译及使用QFIL刷机
    git常用指令
    Bouml快速使用指南
    Linux内核数据结构之kfifo详解
    输入系统:进程间双向通信(socketpair+binder)
    Android : 跟我学Binder --- (6) JAVA实现
    【LeetCode】167. Two Sum II
    【LeetCode】1. Two Sum
    【LeetCode】206. Reverse Linked List
  • 原文地址:https://www.cnblogs.com/denggelin/p/5379876.html
Copyright © 2011-2022 走看看