指针、指针数组、数组指针。结构体指针。

指针(pointer)简介

     指针是一个值为内存地址的变量     

例如

      

                  int year;

                year = 2016;       

        定义一个整型变量,系统就给这个整个变量分配了一个内存空间,这个内存空间的名字叫做year,空间里的值为2016,内存在计算机中的地址为0028FF44(计算机中的内存地址一般用16进制表示)。

                 int* ptr_year;       //ptr_year为一个变量,可以把int*看作是一种数据类型,一种指向地址的数据类型

                  ptr_year=&year   // "&"为取地址符,相当于把变量year的地址取出来赋给ptr_year这个变量,赋值时一定要用&取地址符,而不能使用常量进行直接赋值

           上图即为原理流程图

基本用法:

             数据类型* 指针变量名;

 例如:

            int* ptr_year;

            char* ptr_name;

            float* ptr_score;

间接运算符 * 在声明指针变量时和在对地址操作时的作用是不同的

           int num;                                 

          num = 1;                                //定义一个整型变量,并赋初值为5

         int* ptr_num;                         //这个星号表示的是ptr_num是一个指针变量

         ptr_num = #                  //定义一个指针变量,指向num             num的值为1

 

          *ptr_num = 1111;                    //把20赋值给*ptr_num地址所对应空间,  num的值变为1111

                                

                 单独一个*加上一个指针表示的是对这个指针所对应的的空间进行操作

注意:

指针的变量的命名规则和其他变量的命名规则一样

指针不能与现有变量同名

指针可存放c语言中的任何基本数据类型,数组和其他所有高级数据结构的地址

若指针已声明为指向某种类型数据的地址   ,则它不能用于存储其他类型数据的地址

应为指针指定一个地址后,才能在语句中使用指针

 

在头文件<stdio.h>中,NULL被定义为常量

 int* pr_num = NULL;   //表示指针的初值为空,表示指针不指向任何地址

指针变量必须初始化,否则不知道指向哪个地址。

数组元素的指针

1、简介

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

可以用一个指针变量指向一个数组元素,例如

int  a[10] = { 1, 2 ,3,4,5,6,7,8,9,10 };         //定义了一个包含有十个整型数据的数组

int* p;                                                     //定义了p为指向整型变量的指针变量

p = &a[0];                                            //把a[0]元素的地址赋值给指针变量p

在c语言中规定,数组名即为数组的首地址,所以以下写法等效

p = &a[0] ; <==> p = a;

注意:数组名不代表整个数组,只代表数组里的第一个元素的地址。

2、通过指针引用数组元素

引用数组元素可以用下面两种方法

(1)下标法

如a[i]形式

(2)指针法

如 *(a+i)或*(p+i)。其中a是数组名,p是指向数组首地址的指针变量,p = a。

数组指针与指针数组

数组指针(也称行指针)
定义 int (*p)[n];
()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长。也就是说执行p+1时,p要跨过n个整型数据的长度。

如要将二维数组赋给一指针,应这样赋值:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
 p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
 p++;       //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]

所以数组指针也称指向一维数组的指针,亦称行指针。

指针数组
定义 int *p[n];
[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。这里执行p+1是错误的,这样赋值也是错误的:p=a;因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
for(i=0;i<3;i++)
p[i]=a[i];
这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
所以要分别赋值。

结构体指针

1、简介

所谓的结构体指针就是指向该结构体变量的指针,一个结构体变量的起始地址就是这个结构体变量的指针。如果把一个结构体变量的起始地址存放在一个指针变量中,那么这个指针变量就指向该结构体变量。

指向结构体对象的指针变量既可以指向结构体变量,也可以指向结构体数组中的元素。指针变量的基类型必须与结构体变量的类型相同。

例如: struct Student * p;                 //p可以指向struct Student 类型的变量或数组元素

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在小组
    float score;  //成绩
} stu1 = { "Tom", 12, 18, 'A', 136.5 };
//结构体指针
struct stu *pstu = &stu1;

也可以在定义结构体的同时定义结构体指针:

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在小组
    float score;  //成绩
} stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;

注意,结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址,必须在前面加&,所以给 pstu 赋值只能写作:

struct stu *pstu = &stu1;

而不能写作:

struct stu *pstu = stu1;

还应该注意,结构体和结构体变量是两个不同的概念:结构体是一种数据类型,是一种创建变量的模板,编译器不会为它分配内存空间,就像 int、float、char 这些关键字本身不占用内存一样;结构体变量才包含实实在在的数据,才需要内存来存储。下面的写法是错误的,不可能去取一个结构体名的地址,也不能将它赋值给其他变量

struct stu *pstu = &stu;
struct stu *pstu = stu;

2、通过指针引用结构体变量

通过结构体指针可以获取结构体成员,一般形式为:

(*pointer).memberName

或者:

pointer->memberName

第一种写法中,.的优先级高于*(*pointer)两边的括号不能少。如果去掉括号写作*pointer.memberName,那么就等效于*(pointer.memberName),这样意义就完全不对了。

第二种写法中,->是一个新的运算符,习惯称它为“箭头”,有了它,可以通过结构体指针直接取得结构体成员;这也是->在C语言中的唯一用途。

上面的两种写法是等效的,我们通常采用后面的写法,这样更加直观。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值