指针 ,数组:(看完保证醍醐灌顶),2023最新理解,一次搞定所有指针,学不会骂我

注意:指针变量和普通的变量没有任何的区别

 

一维指针:

指针大小:

这个是不确定的,要根据编译器来决定,是4字节或者8字节

在32位模式中:位4字节(与类型无关,所有指针数据变量的宽度也是四字节,与指向的数据类型是无关的,比如说char* ,int* ,double*)一个字节=8位(8bit)

C语言理解指针加一

指针访问:

char buf[]={1,2,3,4,5,6,7,8,9};
char *addr1=&buf[3];
printf("%d",*addr1);//or  printf("%d",addr1[0]);
//这两个输出是一样的                   不要把这个看成数组,而是把addr1当作一个门牌号去偏移
//数组也是,数组仅仅是申请空间的一个手段

 

操作符:

&(取地址操作符):

用法1:

用法2:

 

用法3:

 

* (取值操作符)(解引用)

 

 

直接传数据不改变原变量,传地址可以改变原变量

1.直接传数据

 

2.传地址

 

指针与数组:

数组在内存中的排列时线性的,也就是地址连一块;

所以可以通过指针指向数组的首地址进行操作;

 

 

这里面每a每次都增加了4,这个就是一个int的宽度,char就是1,double就是8,所以这里加减的大小就是其去掉一个*以后的数据宽度  

 

当使用函数时想要传数组,其实就是传递数组的首地址

也就是指针变量可以当作数组使用

 

这里就是在指针上+,加的是按照类型来加的

#include<stdio.h>
int main()
{
    //char* s="Aello";//这里面s是个指针,他在栈上,但是他没有空间,他只是指到了只读数据段上
    //字符串、常量、都在只读数据段
    char s[]="Aello";//这个是定义了一个空间,并不是定义了一把钥匙,定义的是在栈里的一个局部变量,虽然后面的字符串仍然在只读区里,但是行代码实际上做了两件事。1.分配空间2.将"Aello"这个空间拷贝到分配的那个空间里
    s[0]='H';//这个s[0]实际上访问的是栈段,栈段是可读可写的
    printf("%s",s);//注释掉的那个是无法打印出来的,因为那个定义在只读段里面,无法修改
    //%s看的结果也是栈上的结果
	return 0;
}

 

指针强转:

#include<stdio.h>
int main()
{
    int a=1025;
    // 1025 = 00000000 00000000 00000100 00000001
    int *p;
    p=&a;
    printf("size of integer is %d bytes\n",sizeof(int));
    printf("Address = %d ,value = %d\n ",p,*p);// ****  1025
    printf("Address = %d ,value = %d\n ",p+1,*(p+1);// ****+4  *****
    char* p0;
    p0=(char*)p;
    //在强转之前,p是4个字节,机器会看4个字节,但是在强转之后,字符型只有一个字节,所以机器只看一个字节,也就是最后的 00000001
    printf("size of char is %d bytes \n",sizeof(char));
    printf("Address = %d ,value = %d\n ",p0,*p0);// ****  1
    printf("Address = %d ,value = %d\n ",p0+1,*(p0+1);//  ****+1  4->00000100
	return 0;
}

数组作为函数参数:

#include<stdio.h>
int SumOfElements(int A[])//int* A//这里没办法把数组的大小也传过去,只能传一个首地址
{
	int i,sum=0;
    int size = sizeof(A)/sizeof(A[o]);//
    printf("SOE sizeof A = %d,sizeof A[0]=%d",sizeof(A),sizeof(A[0]));//  4  4
    for(i=0;i<size;i++)
    {
        sum+=A[i];
    }
    return sum;
}
int main()
{
    int A[]={1,2,3,4,5};
    int total = SumOfElements(A);
    printf("Sum of elements = %d\n"total);//  1
    printf("Main sizeof A = %d,sizeof A[o]=%d",sizeof(A),sizeof(A[0]));// 20  4
	return 0;
}

very important:

 

二维数组是一维数组的数组,即解引用一次还是得到地址

 

因为B是数组名,所B是B[0]的地址,即B=&B[0],因此*B=B[0],而B[0]是一维数组的数组名,所以B[0]是B0的地址  

b+1 指向b[1] [0] *b+1 b [0] [1]

 

 

 //运行结果是两个8

多维指针与数组:

 

 

如何在函数中传值:

void funa(int *a)// or void funa(int a[])
{
	```	
} 
void funb(int (*b)[3])//or void funa(int a[][3])  int** a是不对的
{
	```	
}
void Func(int c[][2][2])//or  void Func(int (*c)[2][2])    int*** a都是不对的              
{
	``` 
}
int main()
{
    int a[]={1,2};
    int b[2][3]={{2,3,4},
             {5,6,7}};
    int x[2][4];//这样就不能传到funb函数里面
    int c[3][2][2]={{{2,5},{7,9}},
                    {{3,4},{6,1}},
                    {{8,0},{11,13}}};
    funa(a);//a returns int*
    funb(b);//b returns int (*p)[3]的一个一维数组,这个一维数组包含三个整型元素

}

 

二维指针:

一维指针存放变量地址,二维指针存放一维指针地址。

二级指针的简单用法。。。。,说白了,二级指针保存的是一级指针的地址,它的类型是指针变量,而一级指针保存的是指向数据所在的内存单元的地址,虽然都是地址,但是类型是不一样的

变量就是小姐姐的照片,你再怎么修改照片,小姐姐不会变。但照片依然有作用。指针就是小姐姐本人,你把她脸上涂个黑点,她在任何地方露脸,脸上都会有黑点,这就是本源被修改了。例如a=照片;*p=小姐姐;p=&a;&取地址,就是根据照片找到小姐姐,以后就可以根据p找到她了(就像你找到了小姐姐的家,以后随时都能到马上就到她家门口),也就是可以直接在她脸上涂黑点。此后,她在任何作用域,都是有黑点的小姐姐。

深入 char * ,char ** ,char a[ ] ,char *a[] 内核

[指针数组](https://so.csdn.net/so/search?q=指针数组&spm=1001.2101.3001.7020)与数组指针详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值