C语言指针总结

一、有关指针的数据类型的小结

定义

含义

int i;

定义整型变量i

int  *p;

p为指向整型数据的指针变量

int  a[n];

定义整型数组a,它有n个元素

int  *p[n];

定义指针数组p,它由n个指向整型数据的指针元素组成

扫描二维码关注公众号,回复: 431257 查看本文章

int  (*p)[n];

p为指向含n个元素的一维数组的指针变量

int  f( );

f为带回整型函数值的函数

int  *p( );

p为带回一个指针的函数,该指针指向整型数据

int  (*p)( );

p为指向函数的指针,该函数返回一个整型值

int  **p;

p是一个指针变量,它指向一个指向整型数据的指针变量




二、知识点归纳:

1.指针与指针变量的概念。

(1)指针:就是内存中的一个存储单元的地址,即内存单元的编号。

(2)指针变量:是一个能存放地址值的变量。通过它存放的地址值能间接访问它所指向的变量。

2.指针变量的定义。

类型名 *指针变量名

类型说明中可取C语言的有效类型,* 表示为指针型变量。如:

char *c1,*c2;

表示c1与c2是指针变量,其基类型是字符型。

注意:指针的基类型与其所指向的变量的类型要统一。

3.指针变量的使用方法

1)使指针变量指向某个变量,(即将某变量的地址值赋给指针变量)例:

int x;  int*p=&x; 或    int x ,*p;   p=&x ;

2)用间址运算(运算符为*)访问所指变量,例:

*p=5; //用作左值时代表所指的变量

x=*p+9; //用作右值时代表所指变量的值

注意:指针变量在使用之前一定要指向某变量,而不能用常数直接赋值

4.指针运算的优先级与结合性(主要涉及*、&、++、- -)。

单目运算符优先级是相同的,但从右向左结合

重点理解:

(1)*&a等同于a; &*p等同于&a。

(2)*p++等同于*(p++)

(3)*++p等同于*(++p)

(4)(*p)++与*(p++)的区别。(*p)++是变量值增值,相当于a++;而*(p++)则是用完当前值后,指针值增值,即相当于a, p++,是指向了新的地址。

5.指针与一维数组(整型数组)

(1)数组的地址:即数组中首个元素a[0]的地址

(2)数组地址的表示方法: (1)用数组名a,(2)取首元素的地址,即&a[0]

(3)数组指针:指向数组的指针变量的简称,即指针变量中存放的是某数组的首地址。例,若有 int a[10],*p;p=&a;则可称p为a数组的指针,或称p指向数组a。

(4)指针与数组的关系:通过移动指针使其指向不同的数组元素p,(p+1),(p+2),…,(p+9) 等同于 &a[0],&a[1],&a[2],…,&a[9]。*p,*(p+1),*(p+2),…,*(p+9) 等同于a[0],a[1],a[2],…,a[9]。

(5)总结:一维数组元素的合法引用方式

方式一,数组名[下标], 例如 a[0],a[1],…

方式二,指针名[下标],例如p[0],p[1],…

方式三,*(指针名+下标),例如*p,*(p+0),*(p+1),…

方式四,*(数组名+下标),例如*a,*(a+0),*(a+1),…

(在C中,数组名就是第一个元素的地址,因此对数组的引用可以直接用*a表示a[0],用*(a+1)表示a[1],用*(a+2)表示a[2],…,用*(a+9)表示a[9]。)

6. 数组名或数组指针作函数参数

属于数组、指针、函数的综合应用,注意函数调用时传值和传址的区别:

(1)形参为普通变量时是传值调用

(2)形参为指针变量时是传址调用

例1:传值调用(形参为普通变量,调用后形参不会影响实参)

#include<stdio.h>

void fun(inta,int b)

{  a++;  b++;  }

int main(void)

{

int x=3,y=4,z;

fun(x,y);

printf("%d,%d\n",x,y);

return 0;

}

例2:传址调用(形参为指针,调用后形参值影响实参)

#include<stdio.h>

void fun(int*a,int *b)

{  (*a)++;   (*b)++; }

int main(void)

{

int x=3,y=4,z;

fun(&x,&y);

printf("%d,%d\n",x,y);

return 0;

}

例3 传址调用(形参为指针,可利用此类形参返回多个结果)

#include<stdio.h>

void fun(inta,int b, int *c,int* d)

{  *c=a+b; *d=a*b;}

int main(void)

{

int x=3,y=4,k,j;

fun(x,y,&z,&j);

printf("%d,%d\n",k,j);

return 0;

}

例4 传址调用(形参为数组名)

#include<stdio.h>

void fun(int b[],inti)

{  b[i]=0; }

int main(void)

{

int a[10]={0,1,2,3,4,5,6,7,8,9}, i;

fun(a,5);

for (i=0;i<10;i++)printf("%d",a[i]);

return 0;

}

7.指针与一维数组(字符数组)

用指针方式与用字符数组方式操作字符串的区别:

(1)存储方式不同。字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串首个字符的地址),决不是将字符串放到字符指针变量中。

(2)赋值方式不同。

对字符数组只能对各个元素赋值,不能用以下办法对字符数组赋值。

     char  str[20];

      str="Good luck!";    

而对字符指针变量,可以采用下面方法赋值:

     char  *str;

      str="Good luck!";

赋给str的不是字符,而是字符串第一个元素的地址。

(3)输入方式不同。

对字符数组可用如下方式赋值:

     char str[20];

     scanf("%s",str);  //ok

但对字符指针变量则不建议用此方式,因为会发生指针的异常指向,正确做法为:

char *str,a[20];

      str=a;  //使指针有明确的指向

scanf("%s",str);

(4)字符指针变量的值是可以改变的,而字符数组名的值是不可以改变的。

例1:#include <stdio.h>

int main(void)

{

char *str="Goodluck!";

puts(str);

str+=5;  //ok

puts(str);

return 0;

}

例2:

#include<stdio.h>

int main(void)

{

char str[20]="Goodluck!";

puts(str);

str+=5;   //error!

puts(str);

return 0;

}

8. 指针与二维数组(整型、字符型)

(1)二维数组的按行存储

若有 inta[2][3]={{1,2,3},{4,5,6}},*p=a; 则*(p+4)=a[1][1]=5

(2)二维数组元素的地址表示及访问方式

设int  a[2][3],*p;p=&a;

可见a是2×3的数组,含有6 个元素。可认为a有两个元素:a[0]和a[1];而a[0]与a[1]又分别是具有三个元素的一维数组。

a    a[0]所含元素为:  a[0][0],a[0][1],a[0][2];

     a[1]所含元素为:  a[1][0],a[1][1],a[1][2]

(可以记忆为:二维数组a含有二个行元素,每个行元素又含有3个列元素)

因此对于二维数组a,a[0]即&a[0][0],也就是第0行的首地址。a[1]就是&a[1][0],也就是第一行的首地址。

由地址运算规则,a[0]+0就是&a[0][0],a[0]+1就是&a[0][1],a[0]+2就是&a[0][2]。所以一般地:a[i]+j=&a[i][j].

在二维数组中,可以用指针表示数组元素的地址,如:a[i]+j=&a[i][j]也可写为*(a+i)+j=&a[i][j],从而可知,*(*(a+i)+j)就是a[i][j],即a[i][j]= *(*(a+i)+j)。

8.函数与指针

(1)指针作为函数参数(知识点6)

(2)函数的返回值为指针类型

定义方式为:类型  *函数名( );

例:#include <stdio.h>

int z;

int *fun(int x,int y)

{ z=x+y; return &z;}

int main(void)

{

int a=3,b=4;

int *c;

c=fun(a,b);

printf("%d\n",*c);

return 0;

}

(3)指向函数的指针变量

定义方式为: 类型  (*变量名)();

这里变量名前一个*号,说明该变量是指针变量,而后面有括号说明这个指针变量是指向函数的。如:int (*p1)( ); 说明p1是指针变量,这个指针变量是指向函数的。

9.指针数组与指向一维数组的指针变量

(1)指针数组:一个数组,它的元素都为指针类型

定义方式为:类型说明  *数组名[整型常量表达式]

如:char  *s[4];则定义了一个指针数组,即s[0],s[1],s[2],s[3]均用来存放地址值,主要用于处理多个字符串。

(2)指向一维数组的指针:一个指针,指向一个一维数组

定义形式是:类型说明  (*变量)[整型常量表达式]

如:int(*p)[4];定义p为指针变量,它指向的是一个具有四个元素的一维数组。

10.指向指针的指针

指向指针的指针也就是“二级指针”。

定义方式如下:类型说明  **指针变量名

即定义一个二级指针变量,类型说明是它指向的指针变量所指向的变量的数据类型。它所指向的指针变量称为一级指针变量。

赋值形式为:二级指针变量=&一级指针变量;

这类似于张三有李四的地址,而王五有张三的地址,这样王五通过张三找到李四。这样张三是一级指针,而王五是二级指针。

例如:

#include <stdio.h>

int main()

{char *name[]={ "Follow me","BASIC","Great Wall″,

"FORTRAN","Computer design"};

    char **p;int i;

    for(i=0;i<5;i++)

   {p=name+i;printf(″%s\n″,*p);}

return 0;

  }

10. 指针数组作main函数的形参

指针数组的一个重要应用是作为main函数的形参。在以往的程序中,main函数的第一行一般写成以下形式:void  main()然而,main函数可以有参数,例如:void main(int  argc, char  *argv[ ]) argcargv就是main函数的形参

main函数是由操作系统调用的。实际上实参是和命令一起给出的。也就是在一个命令行中包括命令名和需要传给main函数的参数。

命令行的一般形式为: 命令名   参数1 参数2……参数n

如果有一个名为file1的文件,它包含以下的main函数:

void main(int argc,char *argv[ ])

{ while(argc>1)

 {++argv;

printf(″%s\n″,argv);

     --argc; }}

DOS命令状态下输入的命令行为:

file1 China Beijing

则执行以上命令行将会输出以下信息:

China

Beijing

猜你喜欢

转载自blog.csdn.net/qq123hongli/article/details/38298655