C和指针_1

  1. 学习指针的目的:
    为了访问内存空间中的内容。
    自己申请的空间全是经过格式化的,等于说你所能访问到的合法空间,全是经过类型有效格式化后的。
  2. 指针分为指针常量和指针变量
    指针常量表示指针本身的内容不可变(指向不可变),因此,定义指针常量时必须同时初始化一个地址值
    指针变量表示指针可以指向别处,因为指针本身是一个变量。

3.指针的本质就是一个(带类型)的地址值。和普通的地址值是不同的。

#include <stdio.h>
int main()
{
    int a = 10;
    int *p = &a;
    printf("%d\n",p);//6356648
    printf("%p\n",p);//0060FEA8
    printf("%#x\n",p);//0060FEA8
    printf("%d\n",*p);//10打印的是
    //printf("%d\n",*(0x0060FEA8)); //error  带类型的地址和普通地址不同
    printf("%d\n",*(int*)0x0060FEA8);//10类型带给了这个普通地址访问空间的能力。因为你通过类型告诉了编译器,这个地址能访问多大的空间。
    return 0;
}
//此处的第十二行的错误是:0x0060FEA8这个地址只是一个普通的地址,不带类型的地址是无法访问其值的,访问的就是非法空间
  1. 指针跟数组关联使用
    一个指向数组的指针,和该数组的数组名,到低有何异同?
    数组的数组名就是数组的首地址,指向该数组的指针可以是一个变量,移动指针的位置,可以更改数组内部元素的值。
    数组名就是数组首元素的地址。
#include <stdio.h>
int main()
{
    int a[5] = {1,7,3,8,15};
    int * p ;
    p = a;
    printf("a -> %p p -> %p \n", a, p);//此处打印的都是a的地址
    printf("a[0] = %d *a = %d  *p = %d \n",a[0],*a,*p);//*p、*a还有a[0]都是数组第一个元素的值
    printf("*(p+2) = %d     (*p+2) + 2 = %d\n",*(p+2),(*p+2) + 2);//*(p+2)是移动p指针,指向a[2]元素,而(*p+2) + 2则是给第一个元素+2后再+2
    printf("将a[3]的8改变为28\n");
    *(p+3) = 28;
    printf("a[3] = %d  *(p+3) = %d\n",a[3],*(p+3));此处对移动指针p,对*(p+3)即a[3]进行修改
}
/*输出结果是:
a -> 0060FE98 p -> 0060FE98 
a[0] = 1 *a = 1  *p = 1 
*(p+2) = 3     (*p+2) + 2 = 5
将a[3]的8改变为28
a[3] = 28  *(p+3) = 28
*/
  1. 传值分割显示
#include <stdio.h>
long func()
{
    int a=5;
    char b = 6;//C里面 char字符类型本质就是整型。是短短整型。
               //char和int 可以相互无条件转换。
    //&a   int* +1   走4个字节
    *((char *) &a + 1) = b;//此处是取a的地址,然后将其转为char *类型,然后将b这个数值存储在a后面
    //那个地址上(此处是加上一个字节,因为是char*类型)就是(char *) &a + 1,再加上*号表示的是取那里的值,将b赋值进去的操作
    return a;
}
int main()
{
    int value = func();
    char a = *((char*)&value);//此处是取value的地址,然后转为char*类型,取出其中a的值
    char b = *((char*)&value + 1);//此处是取value的地址,转为char*类型,地址移动一个char*空间大小,指向char*类型后面的那个地址,取出里面的值赋给b
    printf("%d,%d\n",a,b);
}

传值分割显示

  1. 你所想的指向的数组中的基本(非最小)元素是什么类型的 ,就定义什么类型指针
    int a[4][5][6] ;
    int (*p)[5][6];
    //需要特别注意的是,指向的数组中的基本单位是什么类型。
  2. 二维数组里面,数组名的操作
int  main()
{
    int a[2][3] = {
        {1,2,3},
        {4,5,6}
    };
    printf("sizeof a %d\n",sizeof(a));//输出24,6个int类型数据,4*6
    printf("a = %p, a+1 = %p a[]+\n",a, a+1 );//a = 0060FE98, a+1 = 0060FEA4         输出a的地址和a地址+sizeof(int)*3
    printf("a[0]= %p, a[0]+1 = %p \n",a[0],a[0]+1);//a[0]= 0060FE98, a[0]+1 = 0060FE9C          输出a[0]地址,a[0]+1的地址
    printf("*a = %p, *a+1 = %d *(*a+1) = %d\n",*a,*a+1,*(*a+1));//a[0]= 0060FE98, a[0]+1 = 0060FE9C       输出的就是a的地址和a的地址+sizeof(int)
    printf("a[0][0] = %d\n",a[0][0]);//输出a[0][0]元素的值
    printf("*a[1] = %d  *a[0]+1 = %d\n",*a[1], *a[0]+1);//*a[1] = 4  *a[0]+1 = 2       输出的是数组a[1]首元素   和a[0]首元素+1

    printf("**a = %d\n", **a);//输出的是a[0][0]的值
    printf("*(*a+2) +5= %d\n", *(*a+1)+5);//先把a指向第一行a[0]数组,然后访问a[0]数组的第二个元素2,再给2加上5
    printf("a[1][2]= %d\n",a[1][2]);//输出a[1][2]的元素的值
    printf("*(*(a+1))+4 = %d\n",*(*(a+1))+4);//输出的是a[1][1] + 4
    printf("*(*(a+1)+2) = %d\n",*(*(a+1)+2));//输出的是a[1][2]上面的值*/
    }

重点:

#include<stdio.h>

int main()
{
	int(*p)[4][3] = NULL;//p是一个三维指针   0
	printf("%d\n", *p);//0  *p  是一个二维指针  0
	printf("%d\n",**p);  //**p  降到一维
    printf("%d\n",***p);	//不会打印,***p是对一维指针取值,
	//*在下面三行代码中表示的是升维操作
	int a = 0;
	int *p1 = &a;//一级指针
	int **p2 = &p1;//二级指针 
*************************************************************************
//&对指针变量来说永远是取值
 //&对数组名相关的,有时是取地址,有时是升唯
*************************************************************************

	//下面的代码中&的作用是进行升维操作,代码有误,重在理解升维的概念和&的不同的作用
	----------------------------------------------------------------------------------
	&a[0][0] == a[0];
	&a[0] == a;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值