sizeof strlen 对于指针的使用

文章详细阐述了C语言中数组名的含义,特别是它在sizeof运算符和strlen函数中的不同表现。数组名通常表示首元素地址,但在某些情况下代表整个数组。sizeof用于计算内存占用,而strlen用于计算字符串长度。文章通过多个示例展示了这些概念在实践中的应用,包括字符数组和二维数组的情况。
摘要由CSDN通过智能技术生成

数组名是什么?

一般来说,我们把数组名称之为数组首元素的地址。

但凡事都例外 在以下两种情况下数组名代表整个数组

1 sizeof(arr)表示整个数组所占空间的大小

  1. &arr 代表整个数组的地址

做几道练习题来表示一下

sizeof对数组 的 数组名 指针的应用

int main()
//{
//    //int a[] = { 1,2,3,4 };
//    //          0 1 2 3
//    //int (*p)[4] = &a;
//
//    //printf("%d\n", sizeof(a));//a表示整个数组   数组有四个int类型  一个int占4个字节总控16个
//    //printf("%d\n", sizeof(a + 0));//a +0  a表示首元素地址 
//                                    地址在内存空间中所占内存根据编译器的不同分为4或8个字节
//    //printf("%d\n", sizeof(*a)); //*a是指对数组首元素地址进行解引用,从而得到其内容类型为int故为4
//    //printf("%d\n", sizeof(a + 1));//int*地址加一跳过四个字节但仍为指针故也是4或8个字节
//    //printf("%d\n", sizeof(a[1]));//表示数组第二个元素  4个字节
//    //printf("%d\n", sizeof(&a));//表示整个数组的地址   4或8个字节
//    //printf("%d\n", sizeof(*&a));//拿到的是整个数组的内容   为16个字节
//    //printf("%d\n", sizeof(&a + 1));整个数组地址+1   仍为地址 4/8
//    //printf("%d\n", sizeof(&a[0]));首元素地址   仍未地址4/8
//    //printf("%d\n", sizeof(&a[0] + 1));第二个元素地址  4/8
//字符数组
//    //char arr[] = { 'a','b','c','d','e','f' };//[a b c d e f]
//
//    //printf("%d\n", strlen(arr));//字符数组无'\0'不知道从哪停止故为随机值
//    //printf("%d\n", strlen(arr + 0));//同理  随机值
//    printf("%d\n", strlen(*arr));首元素  不是strlen能访问的地址出错误
//    printf("%d\n", strlen(arr[1]));同理第二个元素
//    //printf("%d\n", strlen(&arr));整个数组的地址在某种意义上和arr作用相同随机值
//    //printf("%d\n", strlen(&arr + 1));//跳过整个数组 随机值
//    //printf("%d\n", strlen(&arr[0] + 1));//第二个元素的地址  随机值

//sizeof是一个操作符//sizeof 计算的是对象所占内存的大小-单位是字节

,size_t//不在乎内存中存放的是什么,只在乎内存大小

//strlen 库函数//求字符串长度,从给定的地址向后访问字符,统计\0之前出现的字符个数//

//char arr[] = { 'a','b','c','d','e','f' };//[a b c d e f]
//    printf("%llu\n", sizeof(arr));//一个字符类型所占空间大小为1个字节arr表示整个数组6
//    //printf("%llu\n", sizeof(arr + 0));//arr为数组首元素地址占4/8个字节
//    //printf("%llu\n", sizeof(*arr));//首元素地址解引用   第一个元素  占一个字节
//    //printf("%llu\n", sizeof(arr[1]));//第二个元素 1
//    //printf("%llu\n", sizeof(&arr));//整个数组地址   4/8个字节
//    //printf("%llu\n", sizeof(&arr + 1));//跳过整个数组的地址   4/8个字节
//    //printf("%llu\n", sizeof(&arr[0] + 1));//第二个元素的地址  4/8字节
//
//int main()
//{
//
//    //char arr[] = "abcdef";
//    [a b c d e f \0]
//    //printf("%d\n", strlen(arr));//求字符串的长度以'\0'结尾 6
//    //printf("%d\n", strlen(arr + 0));//仍从首元素地址开始计算  6
//    printf("%d\n", strlen(*arr));//首元素地址解引用 首元素 'a'所占内存空间地址 不能被我们使用
//    printf("%d\n", strlen(arr[1]));//同理
//    //printf("%d\n", strlen(&arr));//整个字符串的地址 随机值
//    //printf("%d\n", strlen(&arr + 1));//随机值
//    //printf("%d\n", strlen(&arr[0] + 1));从第二个元素地址开始计算  6-1=5
//
//    //printf("%d\n", sizeof(arr));//7   包括’\0‘所占空间
//    //printf("%d\n", sizeof(arr + 0));//4/8 arr+0是数组首元素的地址
//    //printf("%d\n", sizeof(*arr));//1 - *arr 数组的首元素
//    //printf("%d\n", sizeof(arr[1]));//1 arr[1]数组的第二个元素
//    //printf("%d\n", sizeof(&arr));//4/8 数组的地址,但是数组的地址依然是地址,是地址大小就是4/8
//    //printf("%d\n", sizeof(&arr + 1));//4/8 是\0后边的这个地址
//    //printf("%d\n", sizeof(&arr[0] + 1));//4/8 是数组第二个元素的地址
//
//    //char* p = "abcdef";//常量字符串不能被更改  在常量区开辟一块空间
//   //将字符串的第一个元素a地址付给指针变量p
//    //printf("%d\n", strlen(p));//6
//    //printf("%d\n", strlen(p + 1));//5 从b的位置开始向后数字符
//    printf("%d\n", strlen(*p));  //err
//    printf("%d\n", strlen(p[0]));//err//相当于 a 
//    //printf("%d\n", strlen(&p));//随机值
//    //printf("%d\n", strlen(&p + 1));//随机值
//    //printf("%d\n", strlen(&p[0] + 1));//5  从b的位置开始向后数字符
//
//    //printf("%d\n", sizeof(p));//4/8  p是指针变量,计算的是指针变量的大小
//    //printf("%d\n", sizeof(p + 1));//4/8 p+1是'b'的地址
//    //printf("%d\n", sizeof(*p)); //1  - *p 其实就是'a'
//    //printf("%d\n", sizeof(p[0]));//1 - p[0]-> *(p+0)-> *p
//    //printf("%d\n", sizeof(&p));//4/8 &p 是指针变量p在内存中的地址
//    //printf("%d\n", sizeof(&p + 1));//4/8 - &p+1是跳过p之后的地址
//    //printf("%d\n", sizeof(&p[0] + 1));//4/8 &p[0]是‘a’的地址,&p[0]+1就是b的地址
//
//
//    //二维数组
//    int a[3][4] = { 0 };
//
//    printf("%d\n", sizeof(a));//计算的是整个数组的大小,单位是字节3*4*4 = 48
//    printf("%d\n", sizeof(a[0][0]));//4 第1行第一个元素的大小
//    printf("%d\n", sizeof(a[0]));//16 - a[0]是第一行的数组名,sizeof(a[0])就是第一行的数组名单独放在sizeof内部,计算的是第一行的大小
//    printf("%d\n", sizeof(a[0] + 1));//4/8 a[0]作为第一行的数组名,并没有单独放在sizeof内部,也没有被取地址
//    //所以a[0]就是数组首元素的地址,就是第一行第一个元素的地址,a[0]+1就是第一行第二个元素的地址
//
//    printf("%d\n", sizeof(*(a[0] + 1)));//4 - *(a[0] + 1))表示的是第一行第二个元素
//    printf("%d\n", sizeof(a + 1));//4/8 - a表示首元素的地址,a是二维数组,首元素的地址就是第一行的地址
//    //所以a表示的是二维数组第一行的地址,a+1就是第二行的地址
//    printf("%d\n", sizeof(*(a + 1)));//16 对第二行的地址解引用访问到就是第二行
//    //*(a+1) -> a[1]
//    //sizeof(a[1])
//    printf("%d\n", sizeof(&a[0] + 1));//4/8 - a[0]是第一行的数组名,&a[0]取出的就是第一行的地址
//    //&a[0] + 1 就是第二行的地址
//
//    printf("%d\n", sizeof(*(&a[0] + 1)));//16 - 对第二行的地址解引用访问到就是第二行
//    printf("%d\n", sizeof(*a));//16 - a就是首元素的地址,就是第一行的地址,*a就是第一行
//    //*a - > *(a+0) -> a[0]
//    printf("%d\n", sizeof(a[3]));//16 int [4]
//    //int a = 10;
//    //printf("%d\n", sizeof(a));//4
//    //printf("%d\n", sizeof(int));//4
//    //重点要记住二维数组首元素地址是第一行的地址在使用时于一维数组名arr有相同用法
//    return 0;
//}
//
//int main()
//{
//    int a[5] = { 1, 2, 3, 4, 5 };
//    int* ptr = (int*)(&a + 1);//整个数组地址+1指针指向五之后的地址减一就是五所在地址解引用就是5
//    printf("%d,%d", *(a + 1), *(ptr - 1));//首元素地址加一为第二个元素地址解引用为2
//    return 0;
//}
//程序的结果是什么

//由于还没学习结构体,这里告知结构体的大小是20个字节
//struct Test
//{
//    int Num;
//    char* pcName;
//    short sDate;
//    char cha[2];
//    short sBa[4];
//}* p;
//
假设p 的值为0x100000。 如下表表达式的值分别为多少?
已知,结构体Test类型的变量大小是20个字节
//int main()
//{
//    p = (struct Test*)0x100000;
//
//    printf("%p\n", p + 0x1);//结构体指针加一跳过20个字节  16进制则为0x100014
//    printf("%p\n", (unsigned long)p + 0x1);//无符号长整形  就是直接加1  
//    printf("%p\n", (unsigned int*)p + 0x1);//无符号整形指针加4 
//
//    return 0;
//}

//int main()
//{
//    int a[4] = { 1, 2, 3, 4 };
//    int* ptr1 = (int*)(&a + 1);//整个数组地址加一指向4后面的地址强制类型转换成int*
//    int* ptr2 = (int*)((int)a + 1);//将首元素地址强制转换为int再加一为2在小段字节序存储中是00020000
//    printf("%x,%x", ptr1[-1], *ptr2); 4   200000
//    return 0;
//}



//#include <stdio.h>
//int main()
//{
//    int a[3][2] = { (0, 1), (2, 3), (4, 5) };//逗号表达式实际存储的是1,3,5
//    int* p;
//    p = a[0];
//    printf("%d", p[0]);//a[0][0] 1
//    return 0;
//}

//int main()
//{
//    int a[5][5];
//    int(*p)[4];
//    p = a;
//    printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
//    //指针-指针 两个指针指向同一个范围   等于两个指针之间元素的个数   为-4 一个打印整数一个打印地址
//    return 0;
//}
//int main()
//{
//    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//
//    int* ptr1 = (int*)(&aa + 1);//去中的是整个数组的地址+1指向10之后的地址强制类型转换成int*简易解引用就是10
//    int* ptr2 = (int*)(*(aa + 1));//第一行地址加一第二行 5
//
//    printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1)); 10,5
//    return 0;
//}
//

//#include <stdio.h>
//int main()
//{
//    char* a[] = { "work","at","alibaba" };
//    char** pa = a;a中存放的是 w a a 的地址
//    pa++;
//    printf("%s\n", *pa);at
//    return 0;
//}


//int main()
//{
//    /*char* c[] = { "ENTER","NEW","POINT","FIRST" };
//    char** cp[] = { c + 3,c + 2,c + 1,c };//F P N E
//    char*** cpp = cp;//指向F
//
//    printf("%s\n", **++cpp);cpp指向p  point
//    printf("%s\n", *-- * ++cpp + 3);//到n后--到e  加三er
//    printf("%s\n", *cpp[-2] + 3);//指向f  加三就是st
//    printf("%s\n", cpp[-1][-1] + 1);//*(*(cpp-1)-1)+1;指向n  加一就是ew
//
//    char arr[] = "abcdef";
//
//    printf("%s\n", arr);
//
//    return 0;
//}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值