C语言中的指针

coolphxnuaa 2016-12-30

1、什么是指针?

指针就是地址。为了说清楚什么是指针,必须先弄清楚数据在内存中是如何存储的,又是如何读取的。

如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量的类型,分配一定长度的空间。

内存区的每一个字节都会有一个编号,这就是“地址”,它相当于旅馆中的房间号,在地址所标志的内存单元中存放的数据则相当于旅馆房间中居住的旅客。

一个变量的地址,称为该变量的指针。

2、指针变量

(1)、存放地址的变量就叫指针变量。

(2)、定义指针变量的一般形式为:类型名 *指针变量名;    例如:int * pointer_1;

(3)、指针变量前面的“*”表示该变量的类型为指针类型。

(4)、一个变量的指针的含义包括两个方面:一是以存储单元编号表示的地址;二是它指向的存储单元的数据类型。

(5)、如何表示指针类型。指向整型数据的指针类型表示为“int *”,读作:指向int的指针或int 指针。

2.1、如何引用指针变量

(1)、给指针变量赋值

int a =10;
int *p;//定义一个指针变量 p
p=&a;//把a的地址赋给指针变量p

指针变量p的值是变量a的地址,p指向a;

(2)、引用指针变量指向的变量

printf("%d\n",*p);//输出变量a的值

(3)、引用指针变量的值

printf("%o\n",p);//以八进制形式输出变量a的地址,即指针变量p的值

注意:(1)、& 取地址运算符。&a是变量a的地址。  (2)、*指针运算符。

3、通过指针引用数组

(1)、数组元素的指针

1、一个变量有地址,一个数组包含若干个元素,每个数组元素都在内存中占用着内存单元,它们都有相应的地址。指针变量既可以指向变量,当然也可以指向数组元素。所谓数组元素的指针其实就是数组元素的地址。

2、引用数组元素有两种方法:(1)、下标法;(2)、指针法。

3、注意:数组名不代表整个数组,只代表数组的首地址,

(2)、在引用数组元素时指针的运算

在指针指向数组元素时,我们可以进行如下运算:

int a[10];
int *p;
p =&a;//等价于p=&a[0]

1、p+1则指向a[1],即p指向了数组元素中的一个元素,则p+1则指向数组元素中的下一个元素,p-1则指向数组元素中的上一个元素。

2、如果p的初始值为&a[0],则p+i和a+i就是数组元素a[i]的地址。也就是说p+i和a+i指向a数组序号为i的元素。注意:这里说的a代表的是数组首元素的地址。

3、*(p+i)和*(a+i)是p+i和a+i所指向的数组元素,即a[i]。

(3)、通过指针引用数组元素

通过指针引用数组元素,有2种方法:

1、下标法:

 
#include <stdio.h>

int main(int argc,char **argv)
{
       int a[10];
        int i;
        printf("Please input 10 integer numbers: ");
        for(i=0;i<10;i++)
        {
             scanf("%d",&a[i]);
        }     
        for(i=0;i<10;i++)
        {
              printf("%d\n",a[i]);
        }      
        return 0;
}
 

2、指针法

(1)、通过数组名计算数组元素的地址,找出元素的值。

 
#include<stdio.h>

int main(int argc,char *argv[])
{
    int a[10];
    int i;
    printf("Please input 10 integer numbers: ");
    for(i=0;i<10;i++)
    {
         scanf("%d",&a[i]);
    }  
    for(i=0;i<10;i++)
    {
         printf("%d",*(a+i));
    }
     printf("\n");
    return 0;
}
 

(2)、用指针变量指向数组元素

 
#include<stdio.h>

int main(int argc,char *argv[])
{
    int a[10];
    int i;
    int *p;
    printf("Please input 10 integer numbers: ");
    for(i=0;i<10;i++)
    {
         scanf("%d",&a[i]);
    }  
    for(p=a;p<(a+10);p++)
    {
         printf("%d",*p);
    }
     printf("\n");
    return 0;
}
 

(4)、用数组名作函数参数

 
int main()
{
    void fun(int arr[],int n);//对fun函数的声明
    int array[10];//定义array数组
      .
      .
      .
     fun(array,10);//用数组名做函数的参数
    return 0;
}

//定义fun函数
void fun(int arr[],int n)
{
   ....
}
 

array是实参数组名,arr为形参数组名。当用数组名作形参时,如果形参数组中各元素的值发生变化,实参数组元素的���随之变化。为什么会这样呢?

在该函数被调用时,系统会在fun函数中建立一个指针变量arr,用来存放从主调函数传递过来的实参数组首元素的地址。

当arr接收了实参数组的首元素地址后,arr就指向实参数组首元素,也就是指向array[0]。因此,*arr就是array[0]。arr+1指向array[1],arr+2指向array[2],arr+3指向array[3]。也就是说:*(arr+1)、*(arr+2)、*(arr+3)分别是array[1]、array[2]、array[3]。

C语言调用函数时虚实结合的方法都是采用“值传递”方式,当用变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,有于数组名代表的是数组首元素地址,因此传递的值是地址,所以要求形参为指针变量。

(5)、通过指针引用多维数组 

指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。 

 

4、通过指针引用字符串

(1)、字符串的引用方式

(2)、字符指针作函数参数

(3)、使用字符指针变量和字符数组的比较

5、指向函数的指针

(1)、什么是函数指针?

如果在程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段存储空间的起始地址(又称入口地址)称为这个函数的指针。

可以定义一个指向函数的指针变量,用来存放某一函数的起始地址,这就意味着此指针变量指向该函数,例如:

int (*p)(int ,int);

定义p是一个指向函数的指针变量,它可以指向函数的类型为整形且有两个整型参数的函数。p的类型用int (*)(int int)表示。

在这里我们得了解一下指针函数与函数指针的区别。

指针函数与函数指针的区别
1、指针函数:是指带指针的函数,即本质是一个函数。函数返回类型是某一类型的指针
类型标识符  *函数名(参数表)
int *fun(x,y);
首先它是一个函数,只不过这个函数的返回值是一个地址值。
2、函数指针:函数指针是指向函数的指针变量,即本质是一个指针变量。

(2)、用函数指针变量调用函数

(3)、怎样定义和使用指向函数的指针变量

(4)、用指向函数的指针作函数参数

6、返回指针值的函数

7、指针数组和多重指针

(1)、什么是指针数组

(2)、指向指针数据的指针

(3)、指针数组作main函数的参数

1、int main()

int main(void)

 括号中是空的或有"void",表示main函数没有参数,调用main函数时不必给出实参。

2、int main(int argc,char *argv[])

其中argc和argv就是main函数的参数,它们是程序的“命令行参数”。

argc(argument count的缩写,意思是参数个数);

argv(argument vector的缩写,意思是参数向量),它是一个*char 指针数组,数组中每一个元素(其值为指针),指向命令行中的一个字符串。

-----------------------------------------------

8、动态内存分配与指向它的指针变量

(1)、什么是内存的动态分配

(2)、怎样建立内存的动态分配

(3)、void指针类型

9、有关指针的小结

相关推荐