第五章 指针

六、指针和数组元素之间的关系

6.1 数组元素与指针的基本关系

变量存放在内存中,有地址编号,咱们定义的数组,是多个相同类型的变量的集合,每个变量都占内存空间,都有地址编号

指针变量当然可以存放数组元素的地址。

6.2 数组元素的引用方法

方法 1: 数组名[下标]

int a[10];

a[2]=100;

方法 2:指针名加下标

int a[10];

int *p;

p=a;

p[2]=100;//因为p和a等价

补充:c语言规定:数组的名字就是数组的首地址,即第0个元素的地址,是个常量。

注意:p和a的不同,p是指针变量,而a是个常量。所以可以用等号给p赋值,但不能给a赋值。

方法 3:通过指针运算加取值的方法来引用数组的元素

int a[10];

int *p;

p=a;

*(p+2)=100://也是可以的,相当于 a[2]=100解释:p是第0个元素的地址,p+2是 a[2]这个元素的地址。对第二个元素的地址取值,即 a[2]

#include<stdio.h>

int main()
{
    int a[5]={1,2,3,4,5};
    int *p;
    p=a;

    printf("a[2]=%d\n",a[2]);
    printf("p[2]=%d\n",p[2]);

    printf("*(p+2)=%d\n",*(p+2));
    printf("*(a+2)=%d\n",*(a+2));

    printf("p=%p\n",p);
    printf("p+2=%p\n",p+2);
    printf("&a[0]=%p\n",&a[0]);
    printf("&a[2]=%p\n",&a[2]);
    return 0;
}

七、指针的运算

7.1 指针可以加一个整数

往下指几个它指向的变量,结果还是个地址

前提:指针指向数组的时候,加一个整数才有意义

int a[10];
int *p;
p=a;
p+2

 

假如p保存的地址编号是2000的话,p+2代表的地址编号是2008

7.2 两个相同类型指针可以比较大小

前提:只有两个相同类型的指针指向同一个数组的元素的时候,比较大小才有意义

指向前面元素的指针 小于 指向后面 元素的指针

7.3 两个相同类型的指针可以做减法

前提:必须是两个相同类型的指针指向同一个数组的元素的时候,做减法才有意义做减法的结果是,两个指针指向的中间有多少个元素

7.4 两个相同类型的指针可以相互赋值

注意:只有相同类型的指针才可以相互赋值(void *类型的除外)

int *p;

int *q;

int a;

p=&a;//p 保存a的地址,p指向了变量a

q=p; //用p给q赋值,q也保存了a的地址,指向 a

注意:如果类型不相同的指针要想相互赋值,必须进行强制类型转换

注意:c语言规定数组的名字,就是数组的首地址,就是数组第0个元素的地址

int *p;

int a[10];

p=a; p=&a[0];这两种赋值方法是等价的

八、指针数组

1、指针和数组的关系

1:指针可以保存数组元素的地址

2:可以定义一个数组,数组中有若干个相同类型指针变量,这个数组被称为指针数组

指针数组的概念:

指针数组本身是个数组,是个指针数组,是若干个相同类型的指针变量构成的集合

2、指针数组的定义方法:

类型说明符 *数组名[元素个数];

int * p[10];//定义了一个整型的指针数组 p,有 10 个元素 p[0]~p[9]每个元素都是 int *类型的变量

int a;

p[1]=&a;

int b[10];

p[2]=&b[3];

p[2]、*(p+2)是等价的,都是指针数组中的第2 个元素。

3、指针数组的分类

字符指针数组 char *p[10]、短整型指针数组、整型的指针数组、长整型的指针数组float 型的指针数组、double 型的指针数组

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

九、指针的指针—二级指针

指针的指针,即指针的地址

#include <stdio.h>

int main()
{
    int a=100;
    int *p;
    p=&a;
    int **q;
    q=&p;
    printf("a=%d,%d,%d\n",a,*p,**q);
    return 0;
}

十、字符串和指针

字符串的概念:

字符串就是以\’0’结尾的若干的字符的集合

字符串的存储形式:数组、字符串指针、堆

1、char string[100]= “I love C!”

定义了一个字符数组 string,用来存放多个字符,并且用”I love C!”给 string数组初始化,字符串“I 1ove C!”存放在 string中

2、char *str= “I love C!”

定义了一个指针变量str,只能存放字符地址编号,

所以说 I love C! 这个字符串中的字符不能存放在 str指针变量中。str只是存放了字符I的地址编号,“I love C!”存放在文字常量区

3、char *str =(char*)malloc(10*sizeof(char));//动态申请了 10 个字节的存储空间,首地址给 str 赋值。

strcpy(str,"I love C")://将字符串“I love C”拷贝到 str 指向的内存里

字符数组:

在内存(栈、静态全局区)中开辟了一段空间存放字符串

字符串指针:

在文字常量区开辟了一段空间存放字符串,将字符串的首地址付给str

堆:

使用 malloc函数在堆区申请空间,将字符串拷贝到堆区

可修改性

1.栈和全局区内存中的内容是可修改的

char str[100]="l love C!”;

str[0]='y';//正确可以修改的

2.文字常量区里的内容是不可修改的

char *str="l love C!”;

*str ='y';//错误,|存放在文字常量区,不可修改

3.堆区的内容是可以修改的

char *str =(char*)malloc(10*sizeof(char));

strcpy(str,"l love C");

*str='y;//正确,可以,因为堆区内容是可修改的

注意:

str指针指向的内存能不能被修改,要看str指向哪里。

str指向文字常量区的时候,内存里的内容不可修改

str指向栈、堆、静态全局区的时候,内存的内容是可以修改

十一、数组指针

概念:本身是个指针,指向一个数组,加1跳一个数组,即指向下一个数组。数组指针的作用就是可以保存二维数组的首地址

数组指针的用法

可以将二维数组的首地址传递到另一个函数里面,此时函数的形参就需要定义为数组指针

#include <stdio.h>


void fun(int (*p)[5],int x,int y)
{
    p[0][1]=101;
}

void test()
{
    int i,j;
    int a[3][5];
    fun(a,3,5);
    for(i=0;i<3;i++)
    {
        for(j=0;j<5;j++)
        {
            printf("%d,",a[i][j]);
        }
        printf("\n");
    }
}
int main()
{
    test();
    return 0;
}

 

十二、指针和函数的关系

12.1 指针作为函数的参数

给一个函数传一个整型、字符型、浮点型的数据,也可以给函数传一个地址

函数传参的方式:复制传参、地址传参、全局传参

复制传参:

将实参的值传递给形参,不管形参怎么改变,跟实参都没有关系

#include <stdio.h>

void change(int a,int b)
{
    int temp;
    temp=a;;
    a=b;
    b=temp;
    printf("交换后:a=%d,b=%d\n",a,b);
}

int main()
{
    int a=10,b=20;
    printf("交换前:a=%d,b=%d\n",a,b);
    change(a,b);
    return 0;
}

 

地址传参:

将实参的地址传递给形参,形参对保存的地址的内容进行任何操作,实参的值也会跟着改变

#include <stdio.h>

void change(int *a,int *b)
{
    int temp;
    temp=*a;
    *a=*b;
    *b=temp;
    printf("交换后:a=%d,b=%d\n",*a,*b);
}

int main()
{
    int a=10,b=20;
    printf("交换前:a=%d,b=%d\n",a,b);
    change(&a,&b);
    return 0;
}

  • 19
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值