精华内容
下载资源
问答
  • void (*p)()一个指向函数的指针,表示一个指向函数入口的变量函数的返回类型void类型。它的用法可参看下例: 例如:有一返加void值的函数swap,(swap用来交换两个数) void (*p)(); /*定义指向函数...
    void (*p)()是一个指向函数的指针,表示是一个指向函数入口的指地变量,该函数的返回类型是void类型。它的用法可参看下例:
    例如:有一返加void值的函数swap,(swap用来交换两个数)
    void (*p)();    /*定义指向函数的指针变量p*/
    p=swap;    /*使指针变量p指向函数max*/
    (*p)(a,b);   /*通过指针变量p调用函数max*/
    它等价于:
    swap(a,b)
    
    void *p()是一个指针型函数,它的函数名为p,返回了一个指针,因为是void,这个指针没有定义类型,所以返回的是一个通用型指针。
    给你举一个例子:
    #include<stdio.h>
    int *max(int *p);
    void main()
    {
        int a[10]={96,23,45,86,79,63,58,36,29,95};
        int *p;
        p=max(a);
        printf(“max=%d\n”,*p);
    }
    int *max(int *p)
    {
         int i,*q=p;
         for(i=1;i<10;i++)
         if(*(p+i)>*q)
              q=p+i;
         return q;
    }
    
    
    void *(*p)(void):函数返回值是void *指针类型。*p则是一个函数指针。括号中的void表示函数指针指向的函数参数为void。
    
    
    展开全文
  • void(*p)()和void*p()区别

    千次阅读 2015-01-15 17:23:26
    整理来源:...void (*p)()一个指向函数的指针,表示一个指向函数入口的变量函数的返回类型void类型。它的用法可参看下例: 例如:有一返
    
    
    整理来源:http://zhidao.baidu.com/link?url=lYBzk1BiYAVy20H4HBOXqAC70E0o616Z0HvvOQeP-2PCoFTjTWZXr-_c1At2OyfyULfUPD4BkVbOFtLSDdzH7q
    
    void (*p)()是一个指向函数的指针,表示是一个指向函数入口的指地变量,该函数的返回类型是void类型。它的用法可参看下例:
    例如:有一返加void值的函数swap,(swap用来交换两个数)
    void (*p)();    /*定义指向函数的指针变量p*/
    p=swap;    /*使指针变量p指向函数max*/
    (*p)(a,b);   /*通过指针变量p调用函数max*/
    它等价于:
    swap(a,b)
    
    void *p()是一个指针型函数,它的函数名为p,返回了一个指针,因为是void,这个指针没有定义类型,所以返回的是一个通用型指针。
    给你举一个例子:
    #include<stdio.h>
    int *max(int *p);
    void main()
    {
        int a[10]={96,23,45,86,79,63,58,36,29,95};
        int *p;
        p=max(a);
        printf(“max=%d\n”,*p);
    }
    int *max(int *p)
    {
         int i,*q=p;
         for(i=1;i<10;i++)
         if(*(p+i)>*q)
              q=p+1;
         return q;
    }
    
    
    
    
    整理自:http://www.cnblogs.com/leon3000/archive/2007/11/15/2037989.html
    
    
    
    
    
    

    void (*b[10]) (void (*)());

    void (*b[10]) (void (*)());

    看到这行代码,相信程序员们都会倒吸一口冷气吧。如果非常不幸的在维护的代码中看到类似的表述,除了想办法找出写出这种天书的猛人来,只能自己硬着头皮搞清楚了。

    在C和C++中,构造这类声明表达式只有一条简单的规则:按照使用的方式来声明。

    C变量的声明都是由两部分组成的:类型,以及一组类似表达式的声明符(declarator)。声明符类似于表达式,对它求值应该返回一个声明中给定类型的结果。例如,我们来看一个简单的声明:

    float f;

    这里f就是声明符,对其求值,应该得到一个float型的数值。

    然后看括号的作用,比如:

    float ((f));

    很简单,这个声明的含义就是,((f))的类型为浮点类型。因为括号和f之间没有其他的修饰了,所以,我们可以推知,f也是浮点型。

    再来看稍微复杂点的:

    float f();

    我们注意到有一个()表达式出现,这个声明符的含义是一个函数。所以这个声明的含义就是,f()的求值结果是一个浮点数,也就是说,f是个返回值为浮点数的函数。

    OK,这些都很简单,再看一个:

    float *f();

    这个就是表示*f()是个浮点表达式,而()的结合优先级高于*,所以,*f()也就是*(f()),f是个函数,返回值是个指针,这个指针指向一个浮点数。

    如果*f是先结合的呢?比如:

    float (*f)();

    这时,f就不是和()结合而成为一个函数名,而是和*结合成为一个指针名,这个指针,是指向函数入口的函数指针,而这个函数,返回值是浮点型。

    现在我们知道怎么声明一个指定类型的变量了。在这个声明表达式中,把变量名,和声明末尾的分号去掉,剩余的部分用一个括号整个括起来,这样就得到了这个变量的类型声明了,比如:

    float (*f)();

    这个表示f是一个指向返回值为浮点型的函数指针。而我们把f这个变量名,和最后的;号去掉,就得到:

    ( float (*)() )

    这个就表示,这个表达式是一个类型,即“指向返回值为浮点型的函数的指针”。如果用这个类型去修饰一个变量名,我们就叫它类型转换符。

    现在有了这些预备知识,我们可以回头看标题的声明到底是什么意思了:

    void (*b[10]) (void (*)());

    首先,表达式的后半部分被两个()分隔开了,我们分别分析它们。( *b[10] ),其中出现了变量名b,很容易就知道,b是一个有10个元素的数组,每个元素都是一个指针。

    然后,看(void(*)()),其中没有出现变量名,所以它代表了一个类型,即“指向返回值为void型的函数的指针“,而我们知道,C语法中,类型修饰符是必须出现在变量名的左边的,而在整个表达式中这个类型符是在变量名b的右边,所以, (void(*)())最外层的这个(),表示了定义了一个函数,这个函数有一个参数,就是一个指针,具体来说,就是“指向返回值为void型的函数的指针“。

    这样就很清楚了,b数组里,每一个指针元素,都是一个函数指针,这个函数有一个参数,这个参数是一个函数指针。整个表达式最左边的void,则定义了b数组中函数指针所指向函数的返回值类型。

    在一串绕口令式的解说后,我们终于看到了事实的真相:这行代码就是逗你玩...

    如果不是故意偷懒,这样代码的作者真是在玩弄阅读者的感情,如果非要实现这样一个复杂的定义的话,我们也是有更好的方法的,就是使用typedef来进行类型声明。

    在面对void (*b[10]) (void (*)());时,我们可以先声明后半部分的类型:

    typdef void (*pFunParam)();

    即表示,类型pFunParam,是一个函数指针。

    然后,针对整个表达式声明一个类型:

    typedef void (*pFun)(pFunParam);

    即表示,类型pFun,是一个函数指针。此函数的参数类型为pFunParam。

    最后,进行变量的声明:

    pFun b[10];

    这样,就清晰许多了吧。最重要的时,利用这样的方式,将编写者的设计思路也体现在了代码中。

    最后,介绍一个更快速的阅读方法:从右向左。

    编译器在进行代码扫描时是从左向右的,而我们在解读这个表达式的时候,从右向左的方法会更容易些,如:

    从右向左扫描以上表达式,首先我们看到一个“)”,因为其右边再没有变量,所以我们知道这是一个函数定义,然后,又看到一对“()“,显然也是函数定义,在就是(*),显然和后面的()联合起来表达了一个函数指针,再左边的void,即修饰了此指针的类型;然后出现了和最右边”)"对应的”(”,显然这个函数定义也完成了,再左边的[10]表达了一个数组,左边是它的名字b,而更左边的“*”和后面的“(“一起表达了一个函数指针,这个函数指针定义了b数组中元素的类型。再往左,指针元素的定义void也出现了。这样,我们就又看到了此表达式的真相。

    展开全文
  • 通常指针变量的使用:先定义指针变量,后给指针变量赋值,最后引用指针变量。现说明如下:  (1)定义指针变量  在变量定义语句int *p, *p1, *q; 中用 * 定义的变量均为指针变量。因此语句定义了名...
    通常指针变量的使用是:先定义指针变量,后给指针变量赋值,最后引用指针变量。现说明如下:
      (1)定义指针变量
      在变量定义语句int *p, *p1, *q; 中用 * 定义的变量均为指针变量。因此该语句定义了名为p、p1与q三个整型指针变量。因为指针变量用于存放变量地址,而地址通常为4字节,所以指针变量的长度均为4个字节。
      (2)指针变量赋值
      指针变量定义后其值为随机数,若此随机数为系统区的地址,则对该指针变量所指系统区某存储单元进行赋值运算,将改变系统区该单元中内容,可能导致系统的崩溃。所以,指针变量定义后必须赋某个变量的地址或0。
      从上面例子可以看出,给指针变量赋初值有三种情况:
      第一种情况是用取地址运算符"&"将变量地址赋给指针变量。如:p=&a;
      第二种情况是将一个指针变量中的地址赋给另一个指针变量,如:p1=p;
      第三种情况是给指针变量赋空值0,如q=0;表示该指针变量不指向任何变量。
      经过赋值后,使指针变量p、p1指向变量a,q不指向任何单元,如图7.2所示。
      (3)指针变量的引用
      指针变量的引用是通过指针运算符"*"实现。在上例中,*p与*p1均表示变量a,因此,第一个输出语句 cout<<*p 被执行后,输出的是变量a的内容100。而赋值语句 *p1=200;是通过指针变量p1间接的将数据200赋给变量a,因此,第二个输出语句中,a 、*p、 *p1同为赋值后变量a的内容200。
      (4)指针变量初始化
      指针变量可以象普通变量一样,在定义指针变量时赋初值,如上例中,定义指针变量p的语句可写成:int *p=&a;
    7.1.3 指针变量的运算

      指针变量的运算有三种:赋值运算、关系运算与算术运算。
      1.指针变量赋值运算
      指针变量赋值运算就是将变量的地址赋给指针变量,上节内容已介绍过,现再举一例加深读者对指针变量赋值运算的理解。
      【例7.2】定义三个整型变量a1、a2、a3,用指针变量完成a3=a1+a2的操作。再定义两个实型变量b1、b2,用指针变量完成b1+b2的操作。
     # include <iostream.h>
     void main (void)
     { int a1=1,a2=2,a3;
      int *p1,*p2,*p3;
      float b1=12.5,b2=25.5;
      float *fp1,*fp2;
      p1=&a1;
      p2=&a2;
      p3=&a3;
      *p3= * p1 + *p2;
      fp1=&b1;
      fp2=&b2;
      cout<<" *p1="<<*p1<<'/t'<<" *p2="<<*p2<<'/t' <<"*p1+*p2="<<*p3<<'/n';
      cout<<"a1="<<a1<<'/t'<<" a2="<<a2<<'/t' <<"a1+a2="<<a3<<'/n';
      cout<<"b1=" <<*fp1<<'/t'<<" b2="<<*fp2<<'/t'<<"b1+b2="<<*fp1+*fp2<<'/n';
     }
     
      程序执行后,输出:
      *p1=1 *p2=2 *p1+ *p2=3
      a1=1 a2=2 a1+a2=3
      b1=12.5 b2=25.5 b1+b2=38
      在此例中,经过指针变量赋值运算后,整型指针变量p1、p2、p3分别指向变量a1、a2、a3,因此,*p1=a1,*p2=a2,*p3=a3。所以,*p3= * p1 + *p2 操作就是a3=a1+a2 操作。如图7.3(a)所示。
        2.指针变量的算术运算

      指针变量的算术运算主要有指针变量的自加、自减、加n和减n操作。
      (1)指针变量自加运算
      指令格式:<指针变量>++;
      指针变量自加运算并不是将指针变量值加1的运算,而是将指针变量指向下一个元素的运算。当计算机执行 <指针变量>++ 指令后,指针变量实际增加值为指针变量类型字节数,即:<指针变量>=<指针变量>+sizeof(<指针变量类型>)。假设数组a的首地址为1000,如图7.4所示。
    int *p=&a[0]; //p=1000,指向a[0]元素
      p++;
      第一条语句将数组a的首地址1000赋给指针变量p,使p=1000。第二条语句使p作自加运算:
      p=p+sizeof(int)=p+4=1004,使p指向下一个元素a[1] 。
       (2)指针变量自减运算
      指令格式:<指针变量>――;
      指针变量的自减运算是将指针变量指向上一元素的运算。当计算机执行 <指针变量>―― 指令后,指针变量实际减少为指针变量类型字节数,即:
      <指针变量>=<指针变量>―sizeof(<指针变量类型>)
      自加运算和自减运算既可后置,也可前置。
      (3)指针变量加n运算
      指令格式:<指针变量>=<指针变量>+n;
      指针变量的加n运算是将指针变量指向下n个元素的运算。当计算机执行 <指针变量>+ n 指令后,指针变量实际增加值为指针变量类型字节数乘以n,即:
    <指针变量>=<指针变量>+sizeof(<指针变量类型>)*n
      (4)指针变量减n运算
      指令格式:<指针变量>=<指针变量>―n;
      指针变量的减n运算是将指针变量指向上n个元素的运算。当计算机执行 <指针变量>― n 指令后,指针变量实际减少值为指针变量类型字节数乘以n,即:
      <指针变量>=<指针变量>―sizeof(<指针变量类型>)*n
    【例7.3】指针变量的自加、自减、加n和减n运算。假设数组a的首地址为1000,如图7.4所示。

     # include <iostream.h>
     void main( void)
     { int a[5]={0,1,2,3,4};
      int *p;
      p=&a[0]; //p指向a[0],p=1000
      p++ ; //p指向下一个元素a[1],p=1004
      cout<< *p<<'/t'; //输出a[1]的内容1。
      p=p+3; //p指向下3个元素a[4],p=1016
      cout<< *p<<'/t'; //输出a[4]的内容4。
      p――; //p指向上一个元素a[3],p=1012
      cout<< *p<<'/t'; //输出a[3]的内容3。
      p=p―3; //p指向上3个元素a[0],p=1000
      cout<< *p<<'/t'; //输出a[0]的内容0。
     }
      程序执行后输出:
      1 4 3 0
      从上例可以看出,通过对指针变量的加减算术运算,可以达到移动指针变量指向下n个元素单元或向上n个元素单元的目的。
    3.指针变量的关系运算
      指针变量的关系运算是指针变量值的大小比较,即对两个指针变量内的地址进行比较,主要用于对数组元素的判断。

      【例7.4】用指针变量求一维实型数组元素和,并输出数组每个元素的值及数组和。
     # include <iostream.h>
     void main( void )
     { int a[5]={1,2,3,4,5};
      int *p,*p1;
      p1=&a[4]+1;
      for (p=&a[0];p<p1;p++)
      cout <<*p<<'/t';
      int sum=0;
      p=&a[0];
      while (p!=p1) sum+=*p++;
      cout <<"/n sum="<<sum<<endl;
     }
      执行程序后:输出:
      1 2 3 4 5
      sum=15
      程序中首先将数组尾地址+1赋给p1,如图7.4所示。在for 语句中,指针变量p为循环变量,数组首地址&a[0]赋给p。循环时先将循环控制变量p与p1中地址比较,若p<p1,则以*p方式输出数组元素a[i]的值,并将p自加指向下一个元素。此循环直到p≥p1为止。
      在while语句中,仍用p作为循环控制变量,当p!=p1时,用sum=sum+*p;语句将数组元素值累加到sum中去,同时用 p++语句使指针变量p指向下一个元素,循环直到p=p1为止,最后输出数组元素之和。
    4.指针运算符的混合运算与优先级

      (1)指针运算符* 与取地址运算符&的优先级相同,按自右向左的方向结合。
      设有变量定义语句: int a, *p=&a;
      则表达式:&*p 的求值顺序为先"*"后"&",即& (*p)=&a=p 。
      而表达式:*&a 的求值顺序为先"&"后"*",即* (&a)=*p=a 。
      (2)"++"、"――"、"*"、"&"的优先级相同,按自右向左方向结合。下面结合例子加以说明。设有变量定义语句:
      int a[4]={100,200,300,400},b;
      int * p=&a[0];
      为了叙述方便,假设系统给数组a分配的首地址为1000,如图7.4所示。
      ① b=*p++;
      按自右向左结合的原则,表达式 *p++ 求值序顺为先"++"后"*",即:*(p++)。由于"++"在p之后为后置++运算符,所以表达式的实际操作是先取*p值,后进行p++的自加操作。即赋值表达式 b=*p++; 等同于下面两条语句:
      b=*p; // b=*p=a[0]=100
      p++; //p=p+sizeof(int)= 1004
      最后运算的结果为b=100,p=1004指向a[1]。
      ② b=*++p;
      按自右向左结合的原则,表达式 *++p 求值顺序为先"++"后"*",即:*(++p)。由于++在p之前为前置++运算符,所以表达式的实际操作是进行++p的自加操作,后取*p值。即赋值表达式 b=*++p; 等同于下面两条语句:
      ++p; //p=p+sizeof(int)= 1008,指向a[2]
      b=*p; // b=*p=a[2]=300
      最后运算的结果为b=300,p=1008指向a[2]。
    ③ b=(*p)++;
      由于括号内优先运算,所以表达式先取出*p(即a[2])的值并赋给b,然后将*p的值即a[2]内容加1。所以表达式等同于下面两条语句:
      b=*p; //b=a[2]=300
      a[2]++ ; // a[2]=300+1=301
      ④ b=*(p++);
      由①可知,该表达式等同于*p++,运算结果为:
      b=*p; //b=a[2]=301
      p++; // p=p+sizeof(int)=1012,指向a[3]
      ⑤ b=++*p ;
      该表达式先进行"*"运算,再进行"++"运算,即先取出*p的值,再将该值加1。因此表达式实际进行了如下运算:b=++(*p)=++a[3]=400+1=401; p仍指向a[3]不变。
      将上述讨论中各语句汇总为例题如下:

     
      【例7.5】指针运算符"*"、"&"、"++"优先级与结合律示例。
     # include <iostream.h>
     main()
     { int a[4]={100,200,300,400},b;
      int *p=&a[0];
      cout<<'/t'<<"p="<<p<<endl;
      b=*p++;
      cout<<"b="<<b<<'/t'<<"p="<<p<<endl;
      b=*++p;
      cout<<"b="<<b<<'/t'<<"p="<<p<<endl;
      b=(*p)++;
      cout<<"b="<<b<<'/t'<<"p="<<p<<endl;
      b=*(p++);
      cout<<"b="<<b<<'/t'<<"p="<<p<<endl;
      b=++*p;
      cout<<"b="<<b<<'/t'<<"p="<<p<<endl;
      }
      运行结果为:
      p=0x0065FDE8
      b=100 p=0x0065FDEC
      b=300 p=0x0065FDF0
      b=300 p=0x0065FDF0
      b=301 p=0x0065FDF4
      b=401 p=0x0065FDF4
      说明:在定义数组时,数据a的地址是由操作系统存储管理动态分配的,因此,数组a的地址是不确定的,每次运行的结果都可能会不同。一般用十六进制数表示。本例中系统为数组a分配的首地址为0x0065FDE8。而在图7.4中所假设的地址1000~1016完全是为了便于读者理解。

    展开全文
  • 指针是一个变量,指针存放的内容是一个地址,地址指向一块内存空间 1.2 指针变量的定义 int *p;//定义一个int类型的指针变量 *p;//代表指针所内存的实际数据 注:指针变量只能存放地址,不能将一个int...

    小常识:

    计算机中绝大部分数据都是放在内存中的,不同数据放在不同的内存区域变量放在堆中,常量放在栈中

    • 内存中,数据以二进制的形式存在,以字节单位进行数据的存取,每8个二进制组成一个字节
    • 内存中每个字节都有唯一的编号,按字节编号,从0开使依次递增,如下图冒号左边。
    • 不同数据类型占据的字节数不同,如:int占4个字节,short占2个字节。

                                                

     

    怎样得到变量的内存地址?

    1. 直接寻址

        内存的地址是一个无符号整数,一般用取地址运算符‘&’得到某变量的地址。

    比如定义一个变量i,输出它的值和存取地址:

    int main()
    {
    	int i = 6;
    	printf("i = %d\n", i);
    	printf("i的地址为:%d\n", &i);
    
    	return 0;
    }

    2. 间接寻址

    通过存放变量地址其他变量访问该变量。可通过指针类型来实现该功能

    2.1 指针变量

    定义:具有指针类型的变量

    变量的指针<==>变量的地址

    2.2 指针变量的定义

    int a = 8;    

    int *p;//定义了可以指向int型数据的指针变量。告诉编译器p是一个指针变量,占4个字节,需要用一个int类型的地址给它赋值。“*”表示间接寻址运算符,用来取地址单元p中的内容

    p = &a;//初始化指针,给出指针p指向的地址

    还可以写成

    int* p = &a;

        注:定义指针时必须要初始化指针给出指针指向的地址。指针变量只能存放地址,不能将一个int型变量直接赋值给一个指针。如:p = 10;将整数10直接赋值给指针变量p,是不可以的

    int main()
    {
        int a = 2;
        // int *p ; //定义一个指针变量,*p代表指针所指内存的实际数据
        //p = &a; //这两句实现的功能=int  *p = &a;
        int* p = &a; //声明指针变量时,将*和数据类型放一块。采用int型,即内存中前4个字节保存的数据是p的
        int b = *p; //*紧挨着指针变量代表“取p指针地址指向的数据”
        printf("b =%d\n", b);
        *p = 10;//修改指针变量p所指向的b变量的值,称为指针的解引用,此时b=10
        printf("a = %d\n", a);
        return 0;
    }

    其中*p = 10; 中引用指针指向的变量的值,称为指针的解引用

    注:

    • 指针变量的值一般不能直接赋值一个整数,而是通过取变量地址的方式赋值;
    • *pint的意思是取pint指针指向的变量内存中的数据;
    • pint代表i的地址*pint代表i的值;
    • *pint = 4间接更改i的值,相当于将I的地址编号为0x123里面的值改为4.

            为了访问pint所指向的实际对象,我们必须先用解引用操作符(*)来接除pint的引用。例如:下面我们通过pint间接的给i加1:

    //通过pint间接地给ival加1
    *pint = *pint + 1;
    
    它等价于值传递中直接对i操作的语句:
    
    //直接给i加1
    i = i + 1;

    2.3 无类型指针

        定义一个指针变量,但不指定它指向具体哪种数据类型。可以通过强制转化将void *转化为其他类型指针,也可以用(void*)将其他类型指针强制转化为void类型指针。

        void *p;

    2.4 空指针(NULL)

        空指针表示值为NULL的指针,即无效指针,相当于0。当指针不指向任何一个有效内存地址的时候,我们应该把指针设置为NULL

    并非所有编译器都使空指针指向0地址,有些编译器为空指针使用不存在的内存地址。

        没有指向任何变量地址的指针叫野指针,程序应该避免野指针的存在

    int main()
    {       
        int a = 10;
        int *p = &a;
        p = NULL;
        if (p)
        {
            printf("true\n");
        }
        else
        {
            printf("fasle\n");
        }
        return 0;
    }

    2.5 野指针

    int main () //野指针,不是空指针,只是没有指向具体的地址内存,所以显示不确定
    {
        int a = 10;
        int *p; //避免使用野指针,更不能读写野指针指向的内存
        *p = a;
        printf("a = %d\n", *p);
        return 0;
    }

    会出现错误提示:

    2.6 兼容性问题

        指针间赋值比普通数据类型赋值检测更严格,例如:不能把一个int *赋值给char *类型。原则上一定是相同类型的指针指向相同类型的变量地址,不能用一种类型的指针指向另一种类型的变量地址。

    int main()//指针的兼容性
    {
        int a = 0x1310;
        char *d = &a; //int-char会导致数据丢失,因为d是一个字节的,所以只显示最小的两位
        
        char b = 2;
        int *p = &b; //p为整型,一个字节2位,所以2为02. 
        
        printf("%x %x %x %x\n", a, *d, b, *p);
        return 0;
    }

    1.8 指向常量的指针和指针常量

    名字 形式 例子 区别
    指针常量 *   const  p1 int * const p1 = &data1;

    定义后,就固定指向一个地址, 程序运行期间指针指向的地址不变,但可对该地址对象(*p1)赋值来改变p1所指向空间的内容

    即 *p1 = 200;

    常量指针 const   *  p1 const int *p = &data2;

    const 修饰的是*p,p可以更改自身的指向,但不通过*p给p所指向的空间赋值。

    定义后,只能指向一个变量,但指针的指向地址可以改变

    即 p = &data1;

     

    指向常量的常量指针 const (type) * const 变量名 const int * const p2 = &data1;

    *号左边的const修饰的是*p2,*号右边的const修饰的是p2。p2不能更改自身的指向,也不能通过*p2去修改p2所指向空间的内容

     (1) 常量指针例子:

      const char *p;//定义一个指向常量的指针。
    
        char *const p; //定义一个指针常量,一旦初始化后其内容不可以更改
    
    int main()//常量指针
    {
        int a = 10;
        int b = 4;
        const int *p = &a;//p这个指针只能指向一个常量,即*p是个只读的值,不能修改它的值,但可以修改它指向的地址,比如下面的p = &b
       //*p = 20;  // 不能通过*p的方法修改一个const指针,即不能将const int *作为左值使用
        a = 20; //可通过修改变量的值改变结果
        p = &b;
        printf("*p = %d,a = %d\n", *p, a);
        return 0;
    }

    (2)指针常量的例子:

    int main()//指针常量:一旦定义之后就固定的指向一个地址,这个地址是不能在程序运行期间改变的 
    { 
        int a = 10; 
        int b = 4; 
        int * const p = &a;//定义一个常量指针p,可通过它修改或读取一个变量的值 
        *p = 20; 
        //a = 22; 
        //p = &b; //错误,常量指针一旦定义,就不能修改其指向的变量 
        printf("a = %d %d\n", *p, a); 
        return 0; 
    }

    1.9 指针与数组的关系

        一个变量有地址,一个数组包含若干个元素,每个元素在内存中都有地址。

        int a[10];

        int *p = a;

        此时p和&a[0]的地址相同

        p[10] = 5;//将数组的第11位赋值为5.

    使用指针访问数组,从语法上可以和数组方式一样,就是通过“指针名[下标]”的方式访问

    int main()
    {
        int array[20] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
        int *p = &array;
        printf("%d\n", p[5]);
        p[5] = 10;
        printf("%d\n", p[5]);
        return 0;
    }
    

    1.10 指针运算

        1)指针运算不是简单的整数加减法,而是指针指向的数据类型在内存中占用字节数作为倍数的运算,

        char *p;

        p++; //表示一次移动了sizeof(char)这么多的字节数,即一次一位

        int *p1;

        p++; //表示一次移动了sizeof(int)这么多的字节数,即一次4位

        2)地址可以求差值,p1 - p2,表示同一数组中两元素之间的距离,是位置差。但不能将地址相加,无意义

    注:p++;改变了指针的初始地址

        3)比较两个指针地址是否相等,即通过判断p1==p2来比较两指针是否指向同一个位置。

    1.11 给数组中某元素赋值

    int main() 
    { 
        int buf[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
        int *p = buf; 
        //法1:将数组中下标为3的成员赋值 
        *(p + 3) = 20; 
        //法2:将数组中下标为5的成员赋值 
        p[5] = 10; 
        //法3:将数组中下标为7的成员赋值 
        p += 7; 
        *p = 30; 
        //法一、二都没有改变p指向的内存地址,但法三修改了p指向的值 
        for(int i = 0; i <10; i++) 
        { 
            printf("buf[%d] = %d\n", i, buf[i]); 
        }
        return 0;
    }

    1.12 指针在函数中的作用

    当指针在函数中使用时,可以在函数中通过改变形参的值改变对应实参的值。

    如:

     

    展开全文
  • 1、概念:指针函数,全称指针型函数,是指函数返回值是指针类型的...这种指向函数的指针变量(主语)称为“函数指针变量”。2、定义的一般形式:2.1 指针函数:类型说明符 *函数名(形参表){ ........... /*函数体...
  • 变量的地址是指该变量所在存储区域的第一个字节(单元)的地址。这三个地址就称为变量a、b、c的指针指针变量用于存放地址值。指针变量的定义格式:类型说明符 *指针变量名;例:int *pi ; 定义 pi 为指向 int 类型...
  • 如果自定义一个函数,没有任何返回值,而形参一个指针传入这个函数,在这个函数中,无论如何改变指针的方向,函数结束后对外部数据没有变化,唯独通过指针,来间接改变函数以外的变量的值(例如令*p = 一个新...
  • 1、地址(c语言):C语言地址,是指内存地址概念。计算机内存中各个存储单元都是有序,按字节编码。字节是最小存储单位。(故数组中每个元素地址总比前一个大。) 2、指针(Point):利用地址,它值直接...
  • 这行代码的目的,用 *号定义一个整型指针变量,其中指针变量为i_pointer ,用于存放地址,地址就是我们常说的指针 。 i_pointer = &i; 其中&读作and,作用取地址。这行代码的目的就是取i的地址,并...
  • 指针 ...“野指针”不是NULL指针,指向“垃圾”内存的指针。人们一般不会错用NULL指针,因为用if语句很容易判断。但是“野指针”很危险的,if语句对它不起作用。 野指针的成因主要有两种: 一、
  • 指针的个人见解(1)

    2016-12-02 20:50:50
    指针是什么?...C语言讲该变量的地址称为该变量的“指针”!!!如果使用一个变量存在某个变量的地址,我们就说这个变量是指针变量,称该指针变量指向某个变量;指针变量的相关定义&: 取地址运算符 *:
  • 学习指针(一)

    2015-03-13 23:27:02
    内存单元编号也叫做地址。既然根据内存单元编号或地址就可以找到所需内存单元,所以通常也把这个地址...为了避免混淆,我们中约定:“指针是指地址,是常量,“指针变量是指取值为地址的变量。定义指针的目的
  • (五十五)指针

    2015-12-03 17:00:48
    指针操作符为*和&,其中&变量名为变量的内存地址,*变量名为内存地址的值。 可以通过修改某内存地址的值,来使得其变量的值变化。 如代码: #include int main() { using namespace std; int a=1; //初始化...
  • 1、一个变量的地址称为该变量的指针 一个专门用来存放另一变量的地址(即指针),称它为指针变量。指针变量的值指针(即地址) 如上图2000是变量的指针,pointer指针变量, 赋值语句可以为 *pointer = 3;...
  • C语言基础(16)-指针

    2017-02-07 14:54:00
    指针是一个变量,存放是一个地址,地址指向一块内存空间。 例: int a = 10; int *p = &a; // 定义一个指针变量p,&符号可以取得一个变量在内存当前中地址。 *p = 5; // 修改指针所指的内存...
  • 1、指针赋值 当声明一个指针后没有对其赋初值,指针变量没有存储确定地址,而是一个随机整数。...当赋值为0时表示该指针是一个空指针。因此在未确定赋值给某指针时,我们一般将其设为空指针(避免其随
  • 引用类型值则保存在堆内存中对象,实际上保存的是一个指针,指向内存另一个位置,位置保存对象。 1.动态属性 对于引用类型值,可以为其添加属性与方法,例如 var person=new Object();...
  • 标量变量是指只能存放单个数值的变量 ...参照变量是指用于存放数值指针的变量 LOB变量是指用于存储大批量数据的变量 事务用于确保数据库数据一致性,它由一组相关DML语句组成,组DM...
  • 该变量是可见、能够使用。 2.生存期:也叫存储期。指的是变量从创建到销毁生存时间段。 作用域和存在域两个不同概念。比方在程序某个位置。某变量存在(内存中分配了地址)但不可见(不可使用)。 作用.....
  • C和指针(一)作用域

    2015-11-14 13:22:51
    而标示符的作用域是指程序中标示符可以被使用的区域。例:函数的局部变量的作用域限于函数的函数体,意思是:1.其他函数无法通过这些变量的名字访问它们2.不同作用域的变量可以重名。 编译器将作用域分为四种:...
  • 面试中问到==与equals()区别与用法

    千次阅读 2020-12-14 20:23:55
    == 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。 equals 用来比较的是两个对象的内容是否相等,由于所有的类都是...
  • C语言入门之指针(1)

    2019-06-21 23:06:49
    什么 如果在程序中定义了一个变量,在对程序进行编译时,系统就会给该变量分配内存单元 内存区每一个字节有一个编号,这就是“地址”,它相当于旅馆中房间号。 在地址所标识内存单元中存放数据,这...
  • 指针一种变量,它存储指定类型的变量的内存地址,如char* 来声明一个字符型指针变量,跟其它变量一样,当其值不可改变时,该指针变量就成为了指针常量,既是常量,它当然一直指向同一个内存地址,而不能被改变。...
  • 复合类型是指基于其他类型定义类型,即在基础数据类型基础上,又指明了该变量与基本数据类型有关某种类型。本节将介绍其中两种:引用和指针。1 引用类型1.1 定义与初始化 引用是为变量起了另一个名字,引用...
  • 在我对c语言的认知里,指针和数组有着密不可分的关系,大家从平时的事例中可以看出,譬如说指针存储的其他变量的地址,而数组名表示着数组的地址;在函数传参时,指针和数组经常能互相替换等等这些例子;...
  • C# 委托(Delegate)

    2019-03-14 09:46:04
    C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。 委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 667
精华内容 266
关键字:

)变量的指针是指该变量的(