首页 > 其他分享 >指针的大小判别;

指针的大小判别;

时间:2024-03-25 13:30:22浏览次数:26  
标签:arr 判别 元素 地址 数组 printf 大小 sizeof 指针

目录

代码1:

代码2:

代码3:

代码4:

代码5:

代码6:


代码1:

#include<stdio.h>
int main()
{
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//16  a是数组名;计算的是整个数组大小;
	printf("%d\n", sizeof(a + 0));//4   a+0是首元素地址;
	printf("%d\n", sizeof(*a));//4  a是数组首元素地址,解引用后是首元素;
	printf("%d\n", sizeof(a + 1));//4 a+1 是第二个元素的地址;
	printf("%d\n", sizeof(a[1]));//4
	printf("%d\n", sizeof(&a));//4  a是整个数组的地址,只要是地址,大小就是4或8;
	printf("%d\n", sizeof(*&a));//16 解引用可以访问的大小,*这里访问的是数组:int [4];==sizeof(a)先取后解;
	printf("%d\n", sizeof(&a + 1));//4
	printf("%d\n", sizeof(&a[0]));//4
	printf("%d\n", sizeof(&a[0] + 1));//4
	return 0;
}

代码1分析:

sizeof(a)这里a代表整个数组,求的是整个数组的大小:16;sizeof(a+0),这里a代表首元素地址,求的是首元素地址的大小:4;sizeof(*a),这里a代表首元素地址,对它进行解引用,求的是首元素的大小:4;sizeof(a+1),这里a代表首元素地址,求的是第二个元素地址的大小:4;sizeof(a[1]),这里a[1]代表第二个元素,求的是第二个元素的大小:4;sizeof(&a),这里a代表整个数组,求的是整个数组地址的大小:4;sizeof(*&a),这里有两种理解:第一种取地址解引用相当于 a,sizeof(a)求的是整个数组的大小:16;第二种&a是整个数组的地址,*解引用访问的是整个数组的大小:16;sizeof(&a+1)这里a代表整个数组,求的是跨越一个数组后的地址大小:4;sizeof(&a[0])这里a代表整个数组,a[0]代表第一个元素,&a[0]代表第一个元素的地址,求的是第一个元素地址的大小:4;sizeof(&a[0])这里&a[0]代表数组第一个元素的地址,+1代表第二个元素的地址,求的是第二个元素地址的大小:4;

运行结果:

代码2:

#include<stdio.h>
#include<string.h>
int main()//要分的清arr是整个数组还是指针,arr只有在sizeof 和 & 后面才是整个数组;
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//sizeof (arr)这时arr是整个数组,6  arr的类型 arr [6]
	printf("%d\n", sizeof(arr + 0));//;//第一个元素的地址 4  类型 char*
	printf("%d\n", sizeof(*arr));//对arr解引用,这是arr是第一个元素的地址  1  类型char
	printf("%d\n", sizeof(arr[1]));// 第二个元素的大小 1 类型 char
	printf("%d\n", sizeof(&arr));//整个数组的地址 4  类型char*[6]
	printf("%d\n", sizeof(&arr + 1));//数组最后一个元素的后一个元素的地址  4 类型char*[6]
	printf("%d\n", sizeof(&arr[0] + 1));//第二个元素地址 4 类型char*
	return 0;//注意: sizeof里面的内容不会计算,只关注类型;
}

代码2分析:

sizeof(arr),这里arr代表整个数组,求的是整个数组的大小,结果为6;sizeof(arr),这里arr代表整个数组,求的是整个数组的大小,结果为6;sizeof(arr+0),这里arr代表数组第一个元素的地址,求的是第一个元素地址的大小,结果为4;sizeof(*arr),这里arr代表首个元素的地址,对其解引用求的是数组第一个元素的大小,结果为1;sizeof(arr[1]),这里arr代表整个数组,arr[1]是数组低二个元素,求的是整个数组第二个元素的大小,结果为1;sizeof(&arr),这里arr代表整个数组,求的是整个数组的地址,结果为4;sizeof(&arr+1),这里arr代表整个数组,求的是跨越整个数组的地址的大小,结果为4;sizeof(&arr[0]+1),这里arr代表整个数组,arr[0]是第一个元素,求的是数组第二个元素地址的大小,结果为4;

运行结果:

代码3:

#include<stdio.h>
#include<string.h>
int main()//要分的清arr是整个数组还是指针,arr只有在sizeof 和 & 后面才是整个数组;
{
   char arr[] = { 'a','b','c','d','e','f' };//strlen 统计的是字符串中在\0之前的元素个数,如果没有\0就会一直找;
	                                         // strlen 需要的是一个地址;从提供地址往后访问;
	printf("%d\n", strlen(arr));//随机 arr是表示首元素地址;
	printf("%d\n", strlen(arr + 0));//随机 arr表示首元素地址;
	//printf("%d\n", strlen(*arr));//随机 *arr表示第一个元素;ascii是97;当从97开始访问时,非法访问; error
	//printf("%d\n", strlen(arr[1]));// 随机 表示第二个元素; error
	printf("%d\n", strlen(&arr));// 随机//首元素的地址;类型char(*)[6],传过去就被强制转换成所需类型了;
	                             //数组地址和数组首元素地址值一样,但类型不一样;
	printf("%d\n", strlen(&arr + 1));//随机//第二个数组的首元素地址;
	printf("%d\n", strlen(&arr[0] + 1));//随机 //第二个元素的地址;
	return 0;//注意: sizeof里面的内容不会计算,只关注类型;
}

代码3分析:

strlen函数里面输入一个地址,从这个地址往后,一直到 \0 ,结果是 \0 之前的元素个数;strlen(arr)这里arr是首元素地址,但不知道\0的位置,所以结果是随机值;strlen(arr+0)这里arr是首元素地址,arr+0还是首元素地址,但不知道\0的位置,所以结果是随机值;strlen(*arr)这里arr是首元素地址,*arr是首元素,strlen要求输入地址,所以是error;strlen(arr[1])这里arr[1]是第二个元素,strlen要求输入地址,所以是error;strlen(&arr)这里arr是整个数组,&arr是整个数组的地址,类型是char(*)[],进入以后,地址类型就被转换成所需要的地址类型,但不知道\0的位置,所以结果是随机值;strlen(&arr+1)这里arr是整个数组,&arr+1是跨越整个数组的地址,但不知道\0的位置,所以结果是随机值;strlen(&arr[0]+1)这里arr是整个数组,&arr[0]+1是数组第二个元素的地址,但不知道\0的位置,所以结果是随机值,不过这个值应与strlen(&arr)差1;

运行结果:

代码4:

#include<stdio.h>
#include<string.h>
int main()//要分的清arr是整个数组还是指针,arr只有在sizeof 和 & 后面才是整个数组;
{
   char arr[] = "abcdef";//元素包括\0  {a,b,c,d,e,f,\0}
	printf("%d\n", sizeof(arr));//7    sizeof判断出后面的类型就行;
	printf("%d\n", sizeof(arr + 0));//4
	printf("%d\n", sizeof(*arr));//1 *arr=arr[0]
	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));//4
	printf("%d\n", sizeof(&arr + 1));//4
	printf("%d\n", sizeof(&arr[0] + 1));//4
	printf("%d\n", strlen(arr));//6    strlen后面要加一个地址;
	printf("%d\n", strlen(arr + 0));//6
	printf("%d\n", strlen(*arr));//err
	printf("%d\n", strlen(arr[1]));//err
	printf("%d\n", strlen(&arr));//6
	printf("%d\n", strlen(&arr + 1));//随机值;
	printf("%d\n", strlen(&arr[0] + 1));//5
	return 0;//注意: sizeof里面的内容不会计算,只关注类型;
}

代码4分析:

arr数组的元素包括:a,b,c,d,e,f,\0;sizeof(arr),这里arr代表整个数组,求的是整个数组的大小,结果是:7;sizeof(arr+0),这里arr代表首元素地址,求的是首元素地址的大小,结果是:4;sizeof(*arr),这里arr代表首元素地址,解引用求的是首元素的大小,结果是:1;sizeof(arr[1]),这里arr[1]代表首元素,求的是首元素的大小,结果是:1;sizeof(&arr),这里arr代表整个数组,求的是整个数组地址的大小,结果是:4;sizeof(&arr+1),这里arr代表整个数组,求的是跨越整个数组的地址的大小,结果是:4;sizeof(&arr[0]+1),这里&arr[0]+1代表第二个数组元素地址,求的是数组第二个元素的地址的大小,结果是:4;

strlen(arr),这里arr代表数组首元素地址,与\0之间的元素个数是6;strlen(arr+0),这里arr+0代表数组首元素地址,与\0之间的元素个数是6;strlen(*arr),这里arr代表数组首元素地址,*arr代表首元素,不是地址,所以是error;strlen(arr[1]),这里arr[1]代表数组第二个元素,不是地址,所以是error;strlen(&arr),这里arr整个数组,&arr代表整个数组地址,也是数组首元素地址,与\0之间的元素个数是6;strlen(&arr+1),这里arr是整个数组,&arr+1代表跨越数组的地址,从这个地址往后找\0,不知道\0的位置,与\0之间的元素个数随机值;strlen(&arr[0]+1),这里&arr[0]+1是数组第二个元素地址,从这个地址往后找\0,与\0之间的元素个数为5;

运行结果:

代码5:

#include<stdio.h>
#include<string.h>
int main()//要分的清arr是整个数组还是指针,arr只有在sizeof 和 & 后面才是整个数组;
{
     char* p = "abcdef";//是把首字符 a 的地址放到 p里面了
	printf("%d\n", sizeof(p));// 4 p是a的地址,p是char* 指针类型;
	printf("%d\n", sizeof(p + 1));// 4 b的地址 char*指针类型;
	printf("%d\n", sizeof(*p));// 1 解引用 指向的是 字符a
	printf("%d\n", sizeof(p[0]));// 1  a==*(p+0)==*p //指针[i]==*(指针+i)
	//char** p  =&p;
	printf("%d\n", sizeof(&p));//4  p是char**型 &p指向p变量所存储的第一个字节;
	printf("%d\n", sizeof(&p + 1));//4 &p+1指向p变量后面的变量所存储的第一个字节,&p+1相当于跳过一个char*的对象;
	printf("%d\n", sizeof(&p[0] + 1));// 4 //p[0]==*(p+0)==*p==a,&p[0] + 1相当于跳过一个p[0]的元素;指向b;
	printf("%d\n", strlen(p));// 6
	printf("%d\n", strlen(p + 1));//5 p+1跳过一个char类型的数据;
	//printf("%d\n", strlen(*p));//err
	//printf("%d\n", strlen(p[0]));//err
	printf("%d\n", strlen(&p));//随机 char** x==&p &p实在p里面找\0 
	printf("%d\n", strlen(&p + 1));//随机 &p+1实在p里面找\0,p里面后面前面的元素都不知道;&p+1后面的元素也不知道;
	printf("%d\n", strlen(&p[0] + 1));// &p[0] + 1 p[0]==*p==a,&a+1=&b 5
	return 0;//注意: sizeof里面的内容不会计算,只关注类型;
}

代码5分析:

字符串的返回值是首元素地址;sizeof(p)这里p是首元素a的地址,结果:4;sizeof(p+1)这里p是首元素a的地址,p+1是第二个元素b的地址,结果:4;sizeof(*p)这里p是首元素a的地址,*p是第二个元素b,结果:1;sizeof(p[0])这里p是首元素a的地址,p[0]==*(p+0)==*p,是第一个元素,结果:1;sizeof(&p)这里p是首元素a的地址,&p是a元素地址的地址,指向p变量所存储的第一个字节,结果:4;sizeof(&p+1)这里p是首元素a的地址,&p是a元素地址的地址,&p+1指向p变量后面的第一个变量所存储的第一个字节,结果:4;sizeof(&p[0]+1),p[0]==*(p+0)==*p==a,&a是a的地址,&a+1是b的地址,结果:4;

strlen(p),p是a的地址,与\0之间的元素个数是6;strlen(p+1),p+1是b的地址,与\0之间的元素个数是5;strlen(*p),p是a的地址,*p是第一个元素a,不是地址,结果是:error;strlen(p[0]),p[0]==*(p+0)==a,不是地址,结果是:error;strlen(&p),&p指向的是p地址的第一个字节,\0的位置不知道,是随机值;strlen(&p+1),&p+1指向的是p地址往后4个字节后的第一个字节,\0的位置不知道,是随机值;strlen(&p[0]+1),p[0]==*(p+0)==*p==a,&p[0]+1指向的是b,与\0之间的元素个数:5;

运行结果:

代码6:

#include<stdio.h>
#include<string.h>
int main()//要分的清arr是整个数组还是指针,arr只有在sizeof 和 & 后面才是整个数组;
{

int a[3][4] = { 0 };//二维数组可以把一行看作一个元素;一维数组的数组;访问的时间必须加j;
	//a要么是整个数组,要么是第一行的地址;
	printf("%d\n", sizeof(a));//48 a是整个数组;
	printf("%d\n", sizeof(a[0][0]));//4  0行0列 一个元素;
	printf("%d\n", sizeof(a[0]));// 16 第一行数组的数组名,计算的整个数组的大小;
	printf("%d\n", sizeof(a[0] + 1));//4 第一行第二个元素的地址;
	printf("%d\n", sizeof(*(a[0] + 1)));//4 第二行数组的第一个元素的内容;

	printf("%d\n", sizeof(a + 1));//4 a+1 首元素地址,第二行地址;int(*)[4]
	printf("%d\n", sizeof(*(a + 1)));//16 *(a+1)==a[1],(a+1)是数组指针,解引用访问是数组; 是第二行的地址;
	printf("%d\n", sizeof(&a[0] + 1));//4 a[0]==*(a+0) &a[0]==a 是第一行数组的数组名,取地址是整个数组的地址,+1是第二行数组的地址,即a[2]
	printf("%d\n", sizeof(*(&a[0] + 1)));//16 第二行地址解引用访问的是第二行数组;
	printf("%d\n", sizeof(*a));//16 a是数组首元素的地址,即第一行的地址,解引用访问数组 *a==a[0]
	printf("%d\n", sizeof(a[3]));//a[3]=*(a+3) 类型是int(*)[4] 不会真正访问,只会判断类型;

	return 0;//注意: sizeof里面的内容不会计算,只关注类型;
}

代码6分析:

sizeof(a),这里a是整个数组,求的是整个数组的大小,结果是:48;sizeof(a[0][0]),这里a[0][0]是数组第一个元素,求的是数组的第一个元素的大小,结果是:4;sizeof(a[0]),a[0]==*(a+0)==*(a),这里a是数组第一个元素地址,但这里二维数组的第一个元素是第一行数组,a[0]也可以当作第一行数组的数组名,放在sizeof后面代表整个数组,求的是第一行数组的大小,结果是:16;sizeof(a[0]+1),a[0]==*(a+0)==*(a),这里a是数组第一个元素,但这里二维数组的第一个元素是第一行数组,a+1,是第二行数组的首元素地址,结果是:4;sizeof(*(a[0]+1)),a[0]==*(a+0)==*(a),这里a是数组第一个元素地址,但这里二维数组的第一个元素是第一行数组,a[0]+1,是第二行数组的首元素地址,解引用,是第二行数组的首元素,结果是:4;sizeof(a+1),这里a是第一行数组的地址,a+1是第二行数组的地址,结果是:4;sizeof(*(a+1)),a+1是第二行数组的地址,对其解引用得到的是第二行数组,结果是:16;sizeof(&a[0]+1)),a[0]==*(a+0)==*a,得到的是第一行数组,&a[0]得到第一行数组地址,+1得到第二行数组地址结果是:4;sizeof(*(&a[0]+1)+1),对第二行进行访问,结果是:16;sizeof(*a),*a==a[0],求的是第一行数组的大小,结果是:16;sizeof(a[3]),a[3]==*(a+3),a+3的类型是int(*)[4],解引用后的类型是int[4],结果是:16,sizeof不会真的访问,只是计算类型的大小;

运行结果:

标签:arr,判别,元素,地址,数组,printf,大小,sizeof,指针
From: https://blog.csdn.net/qq_54029068/article/details/136990410

相关文章

  • C++智能指针
    为什么需要智能指针对于普通指针,在程序结束前我们需要将每个指针都进行free,以免造成内存泄漏。但是手动释放指针是麻烦的,并且一旦漏掉就会造成内存泄漏。因此在C++11中引入智能指针避免此种情况的发生。智能指针包括std::shared_ptr/std::unique_ptr/std::weak_ptr,需要使用头文......
  • C++开发基础——指针与引用
    一,关于指针1.指针的基础概念指针是可存储地址的变量,存储在指针中的地址可以是变量或者其他数据的地址。指针不仅仅是指向某地址,指针还关注指向该地址的数据类型。例如:long*num_ptr{};这里的num_ptr指针今后只能存储long类型的变量地址,尝试用它存储非long类型的变量地址......
  • 字母大小写转换
    #include<stdio.h>//字母大小写转换intmain(){ charch=0; while(scanf("%c",&ch)==1) { if(ch>='a'&&ch<='z') printf("%c\n",ch-32); if(ch>='A'&&ch<=......
  • 指针的学习
    .指针:一个变量的地址指针变量:存放指针(变量地址)的变量& 取变量的地址单目运算符*取指针所指向变量的内容int*i_point,i; i=10; i_point=&i; printf("%x\n",&i);//变量对其取地址结果62fe14 printf("%x\n",&i_point);//对指针变量取地址,指针变量也需要空间存......
  • 指向结构体类型数据的指针
    一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设一个指针变量.用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。指针变量也可以用来指向结构体数组中的元素。1指向结构体变量的指针下面通过一个简单例子来说明指向结构体变量的指针变量的......
  • 基础算法--双指针练习总结
    Acwing部分练习:799.最长连续不重复子序列暴力未AC(53points):#include<iostream>usingnamespacestd;constintN=1e5+5;intn,a[N];boolcheck(intl,intr){for(inti=l;i<=r;i++){for(intj=i;j<=r;j++){if(i!=j&&a[i]==a[j]){......
  • 智能指针详解
    文章目录前言unique_ptrshared_ptrweak_ptr前言智能指针本质上来讲是一个存储指向堆内存指针的类,目的就是帮助我们管理内存,一旦使用了智能指针就就尽量使用new产生的指针,因为智能指针只维护同类型指针的引用计数,混用很容易造成内存重复释放的问题unique_ptrstd:......
  • 批处理脚本来将 Windows 10 的虚拟内存设置为自动管理所有驱动器的分页文件大小
    批处理脚本来将Windows10的虚拟内存设置为自动管理所有驱动器的分页文件大小:CopyCode@echooffREM将所有驱动器的分页文件大小设置为自动管理REM禁用虚拟内存wmiccomputersystemwherename="%computername%"setAutomaticManagedPagefile=Falsewmicpagefilesetw......
  • ☆【前后缀】【双指针】Leetcode 42. 接雨水
    【前后缀】【双指针】Leetcode42.接雨水解法1前后缀分解解法2双指针---------------......
  • Vue3 - Element Plus 下拉选择器 el-select 覆盖修改 placeholder样式,解决覆盖不生效
    前言如果需要Vue2版本,请访问这篇文章。本文实现了在vue3+element-plus网站开发中,完美覆盖el-select选择器样式,强力修改select下拉选择框placeholder样式,同时也支持修改文字、大小、边框、等,支持任意样式的覆盖修改!网上的教程几乎都不生效,使用本教程的方法......