黑马程序员——黑苹果的视频笔记(9)——指针(C语言)


------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------






1地址

每个存储单元都有唯一的 地址。
指针就是地址。

2指针概念
指针就是地址。
内存单元的指针和内存单元的内容不一样。

3、变量的存取方式

直接存取:变量的赋值和取值
间接存取:通过指针(地址)间接操作完成。

4指针变量

4.1指针变量:用一个变量来存放指针

指针是一个地址,是一个常量。针变变量是存放一个地址,是一个变量。

4.2指针变量其一般形式为: 类型说明符 *变量名;

4.3指针变量的初始化和引用


定义的同时进行初始化和先定义后初始化

int a = 5;
int *p = &a;
先定义后初始化
int a;
int *p;
p=&a;

把指针初始化为NULL
int *p=NULL;
int *q=0;

5多个指针变量可以指向同一个地址
int a = 5;
int *p = &a;
int *p1 = &a;
int *p2 = p1;
5.2、指针的指向是可以改变的

5.3、指针没有初始化里面是一个垃圾值,这时候我们这是一个野指针,
所以指针必须初始化才可以访问其所指向存储区域

5.4使用“*”获取指针对应存储区域的内容

& :取地址运算符;

* :指针运算符;


1在定义变量的时候 * 是一个类型说明符,说明定义的这个变量是一个指针变量

2在不是定义变量的时候 *是一个操作符,访问指针所指向存储空间

3)*指针变量名,可以获取值,也可以设定值

4)*p 取值的原理
从p中存放的地址开始,连续取的 sizeof(指针变量类型) 个字节,组成一个数,返回给计算 机

6指针应用


1)在函数中间接访问调用者中的变量


void change(int*num)
{
    *num = 10;
}
2)函数返回多个值
void sumAndMinusAndJiAndShang(int num1,int num2,int *sum,int *minus,int *ji,int *shang)
{
    *sum = num1 + num2;
    *minus = num1 - num2;
    *ji = num1 * num2;
    *shang = num1 / num2;
}

7二级指针

如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针
变量。也称为“二级指针”

指针变量a-》指针变量b-》变量的值

<pre name="code" class="objc">int a=5;
int* p=&a;
int **m=&p; //*(*m)
printf("&a = %p\n",&a);
printf("p = %p\n",p);
printf("&p = %p\n",&p);

printf("m = %p\n",m);
printf("*m = %p\n",*m);//有点意思了
printf("%d\n",**m);

 


8 多级指针
int ***m1; 取值***m1
int *****m2; 取值*****m2


9指针区分类型
printf ("sizeof (int*) = %zd\n", sizeof (int*));
printf ("sizeof (char*) = %zd\n", sizeof (char*));
printf ("sizeof (float*) = %zd\n", sizeof (float*));
printf ("sizeof (double*) = %zd\n", sizeof (double*));
printf ("sizeof (void*) = %zd\n", sizeof (void*));

以上的访问结果都为8

10数组指针

10.1数组元素的指针就是数组元素的地址

可以用一个 指针变量 向一个数组元素
int a[100]={1,2,3,4,5,6,,3,5,3,,2,54,6,3,3,4};
int * p =&a[0];


10.2数组名a不代表整个数组,只代表数组首元素的地址。
“p=a;”的作用是“把a数组的首元素的地址赋给指针变量p”,而不是“把数组a各元素的值赋给 p”

使用指针引用数组元素


如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素。


如果p的初值为&a[0],则p+i和a+i就是数组元素a[i]的地址,或者说,它们指向a数组 序号为i的元素


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


10.4)如果指针p1和p2都指向同一数组


结论: 引用一个数组元素,可用下面两种方法:
(1)下标法,如a[i]形式 (2)指针法,如*(a+i)或*(p+i)
(3)a是常量(a++错误),p是变量(p++正确)


11逆序数组

用指针将数组a中n个整数按相反顺序存放


解题思路:将a[0]与a[n-1]对换,......将a[4]与a[5]对换。 注意:a[i] = *(a+i);

int a[10]={1,2,3,4,5,6,7,8,9,10}; int *p = a;
int i=0,j=9,temp;
    while (i<j) {
    temp = *(p+i);
        *(p+i) = *(p+j);
        *(p+j)=temp;
        i++,j--;
      }




for (int i=0; i<10; i++) {
    
    for (int i=0; i<10; i++) {
        
        printf("%d\t",*(p+i));
    }
    printf("\n");


12一维指针数组
    
12.1一个数组的元素值为指针则是指针数组。


12.2类型说明符 *数组名[数组长度]
    其中类型说明符为指针值所指向的变量的类型。
    
12.3    int *pa[3]
    表示pa是一个指针数组,它有三个数组元素,每个元素值都是一个指针,指向整型变 量。
 
    int *pa[2]={a[0],a[1]};
    int a[8]={1,2,3,4,5,6};
    
    printf("a[0] =%p\n",a[0]); //打印二维数组的第一行首地址
    printf("pa[0]=%p\n",pa[0]);//打印pa数组的第1个元素值
    //获取pa数组第1个元素中存放的地址对应的值(第一行第一个元素值)
    printf("*pa[0]=%d\n",*pa[0]);
    printf("*pa[1]=%d\n",*pa[1]);//打印第二行第一个值
    printf("*(*(pa+1))=%d\n",*(*(pa+1)));
    //等同于 *pa[1],把pa[1]用指针来表示了
    printf("**(pa+1) =%d\n",**(pa+1));
    //等同于上面,省略了外层括号
    

  12.4  指针变量之间运算
    
 两指针变量相减所得之差是两个指针所指数组元素之间相差的元素个数。
    
    int a[8]={1,2,3,4,5,6};
    int *p=&a[1];
    
    int *p1=&a[4];

    printf("p1-p=%d",p1-p);
     
指针之间可以相减,但不可以相加(相加无意义)
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    



1地址

每个存储单元都有唯一的 地址。
指针就是地址。

2指针概念
指针就是地址。
内存单元的指针和内存单元的内容不一样。

3、变量的存取方式

直接存取:变量的赋值和取值
间接存取:通过指针(地址)间接操作完成。

4指针变量

4.1指针变量:用一个变量来存放指针

指针是一个地址,是一个常量。针变变量是存放一个地址,是一个变量。

4.2指针变量其一般形式为: 类型说明符 *变量名;

4.3指针变量的初始化和引用


定义的同时进行初始化和先定义后初始化

int a = 5;
int *p = &a;
先定义后初始化
int a;
int *p;
p=&a;

把指针初始化为NULL
int *p=NULL;
int *q=0;

5多个指针变量可以指向同一个地址
int a = 5;
int *p = &a;
int *p1 = &a;
int *p2 = p1;
5.2、指针的指向是可以改变的

5.3、指针没有初始化里面是一个垃圾值,这时候我们这是一个野指针,
所以指针必须初始化才可以访问其所指向存储区域

5.4使用“*”获取指针对应存储区域的内容

& :取地址运算符;

* :指针运算符;


1在定义变量的时候 * 是一个类型说明符,说明定义的这个变量是一个指针变量

2在不是定义变量的时候 *是一个操作符,访问指针所指向存储空间

3)*指针变量名,可以获取值,也可以设定值

4)*p 取值的原理
从p中存放的地址开始,连续取的 sizeof(指针变量类型) 个字节,组成一个数,返回给计算 机

6指针应用


1)在函数中间接访问调用者中的变量


void change(int*num)
{
    *num = 10;
}
2)函数返回多个值
void sumAndMinusAndJiAndShang(int num1,int num2,int *sum,int *minus,int *ji,int *shang)
{
    *sum = num1 + num2;
    *minus = num1 - num2;
    *ji = num1 * num2;
    *shang = num1 / num2;
}

7二级指针

如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针
变量。也称为“二级指针”

指针变量a-》指针变量b-》变量的值

<pre name="code" class="objc">int a=5;
int* p=&a;
int **m=&p; //*(*m)
printf("&a = %p\n",&a);
printf("p = %p\n",p);
printf("&p = %p\n",&p);

printf("m = %p\n",m);
printf("*m = %p\n",*m);//有点意思了
printf("%d\n",**m);

 
 

8 多级指针
int ***m1; 取值***m1
int *****m2; 取值*****m2


9指针区分类型
printf ("sizeof (int*) = %zd\n", sizeof (int*));
printf ("sizeof (char*) = %zd\n", sizeof (char*));
printf ("sizeof (float*) = %zd\n", sizeof (float*));
printf ("sizeof (double*) = %zd\n", sizeof (double*));
printf ("sizeof (void*) = %zd\n", sizeof (void*));

以上的访问结果都为8

10数组指针

10.1数组元素的指针就是数组元素的地址

可以用一个 指针变量 向一个数组元素
int a[100]={1,2,3,4,5,6,,3,5,3,,2,54,6,3,3,4};
int * p =&a[0];


10.2数组名a不代表整个数组,只代表数组首元素的地址。
“p=a;”的作用是“把a数组的首元素的地址赋给指针变量p”,而不是“把数组a各元素的值赋给 p”

使用指针引用数组元素


如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素。


如果p的初值为&a[0],则p+i和a+i就是数组元素a[i]的地址,或者说,它们指向a数组 序号为i的元素


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


10.4)如果指针p1和p2都指向同一数组


结论: 引用一个数组元素,可用下面两种方法:
(1)下标法,如a[i]形式 (2)指针法,如*(a+i)或*(p+i)
(3)a是常量(a++错误),p是变量(p++正确)


11逆序数组

用指针将数组a中n个整数按相反顺序存放


解题思路:将a[0]与a[n-1]对换,......将a[4]与a[5]对换。 注意:a[i] = *(a+i);

int a[10]={1,2,3,4,5,6,7,8,9,10}; int *p = a;
int i=0,j=9,temp;
    while (i<j) {
    temp = *(p+i);
        *(p+i) = *(p+j);
        *(p+j)=temp;
        i++,j--;
      }




for (int i=0; i<10; i++) {
    
    for (int i=0; i<10; i++) {
        
        printf("%d\t",*(p+i));
    }
    printf("\n");


12一维指针数组
    
12.1一个数组的元素值为指针则是指针数组。


12.2类型说明符 *数组名[数组长度]
    其中类型说明符为指针值所指向的变量的类型。
    
12.3    int *pa[3]
    表示pa是一个指针数组,它有三个数组元素,每个元素值都是一个指针,指向整型变 量。
 
    int *pa[2]={a[0],a[1]};
    int a[8]={1,2,3,4,5,6};
    
    printf("a[0] =%p\n",a[0]); //打印二维数组的第一行首地址
    printf("pa[0]=%p\n",pa[0]);//打印pa数组的第1个元素值
    //获取pa数组第1个元素中存放的地址对应的值(第一行第一个元素值)
    printf("*pa[0]=%d\n",*pa[0]);
    printf("*pa[1]=%d\n",*pa[1]);//打印第二行第一个值
    printf("*(*(pa+1))=%d\n",*(*(pa+1)));
    //等同于 *pa[1],把pa[1]用指针来表示了
    printf("**(pa+1) =%d\n",**(pa+1));
    //等同于上面,省略了外层括号
    

  12.4  指针变量之间运算
    
 两指针变量相减所得之差是两个指针所指数组元素之间相差的元素个数。
    
    int a[8]={1,2,3,4,5,6};
    int *p=&a[1];
    
    int *p1=&a[4];

    printf("p1-p=%d",p1-p);
     
指针之间可以相减,但不可以相加(相加无意义)
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值