指针一站式服务 (内含指针,地址,数组,解引用,sizeof,strlen的使用)

简介: 指针一站式服务 (内含指针,地址,数组,解引用,sizeof,strlen的使用)
#include<stdio.h>
//所有数组名都是首元素地址,除了以下两种情况:
// 1.&数组名---数组名表示整个数组大小,但仍是地址,地址大小是4/8个字节!!!
// 2.sizeof(数组名)---整个数组大小
 //小技巧:像sizeof(&arr+1)等,是情况1,&arr是整个数组的大小,
 //                                     +1跳过整个数组的地址,进入到下一个数组的起始地址
 //         *p->p[0],均表示解引用第一个元素的大小或长度
 //         &数组名 sizeof看到是大小,地址的大小是4,,,,strlen是长度,需要看&里面是什么
 //        sizeof球队是大小,int char型等都有大小,地址的大小固定是4
 //        strlen求的是长度,遇到\0就停止,         地址的长度就是里面数组的长度,遇到\0停止
//int main()
//{
//    int a[] = { 1,2,3,4 };
//    printf("%d\n", sizeof(a));//打印结果为16,整个数组,每个元素是int,是4,,4*4=16(情况2)
//    printf("%d\n", sizeof(a+0));//4/8---0是第一个元素的地址,sizeof(a+0)计算的是地址的大小
//    printf("%d\n", sizeof(*a));//4---*a解引用第一个元素为1,int 1为4
//    printf("%d\n", sizeof(a+1));//4/8---a+1是第二个元素地址大小
//    printf("%d\n", sizeof(a[1]));//4---计算第二个元素大小
//
//    //&a--int(*p)[4]=&a
//    printf("%d\n", sizeof(&a));//4/8----打印的是a的地址大小,地址大小是4
//    printf("%d\n", sizeof(*&a));//16---&a取出的是数组的地址,数组的大小为16,也可看成是*&相互抵消
//    printf("%d\n", sizeof(&a+1));//4/8---&a取出a的地址,+1是跳过a整个数组之后(4后面的地址)
//    //下一空间的地址,地址大小4!!
//    printf("%d\n", sizeof(&a[0]));//4/8---取出第一个元素的地址
//    printf("%d\n", sizeof(&a[0]+1));//4/8--第一个元素+1,为第二个元素,第二个元素的地址,大小为4
//    return 0;
//}
//字符数组
int main()
{
    char arr[] = { 'a','b','c','d','e','f' };//没有\0,对sizeof没影响,
    //对strlen有影响,因为strlen找到\0才会停下来,地址中的0x00的0也是\0的意思
    printf("%d\n", sizeof(arr));//6---单独放,计算数组总大小,每个1字节
    printf("%d\n", sizeof(arr+0));//4/8---s数组名,表示首元素地址!!!地址是4!!!
    printf("%d\n", sizeof(*arr));//1--解引用地址,还是一个字符大小,一个元素
    printf("%d\n", sizeof(arr[1]));//1--数组第二个元素大小
    printf("%d\n", sizeof(&arr));//4-8---&arr,取出的是整个地址的大小
    printf("%d\n", sizeof(&arr+1));//4-8---取整个数组地址然后跳过整个数组进入下一个数组
    //的首地址,但仍是地址的大小
    printf("%d\n", sizeof(&arr[0]+1));//4/8---第一个元素+1,是第二个元素
    //strlen求字符串长度,,并且只看地址的长度,必须找到\0才能停下来,,所以只可能是随机值或代码错误
    //所以只可能是随机值或代码错误(此时表示strlen+数字地址,数字不能做地址,所以代码错误)
    printf("%d\n", strlen(arr));//随机值---数组名是首元素地址
    printf("%d\n", strlen(arr+0));//随机值
    printf("%d\n", strlen(*arr));//代码错误---解引用(97),arr代表的是97,具体数字作地址不正确
    printf("%d\n", strlen(arr[1]));//代码错误---arr[98]也是确定值
    printf("%d\n", strlen(&arr));//随机值---取出的是整个数组的地址
    printf("%d\n", strlen(&arr+1));//随机值---整个该个数组的地址+6=下一个数组,长度未知
    printf("%d\n", strlen(&arr[0]+1));//随机值---从第二个元素开始
    printf("*****************************************\n");
    char arr[] = "abcdef";//等价于abcdef\0
    printf("%d\n", sizeof(arr));//7---整个数组大小,7个元素,每个元素是char型
    printf("%d\n", sizeof(arr + 0));//4/8--数组名是首元素地址,+0还是首元素地址,地址4个字节
    printf("%d\n", sizeof(*arr));//1---数组名首元素地址,地址解引用,第一个元素,a,是1个字节
    printf("%d\n", sizeof(arr[1]));//1---第二个元素大小是1
    printf("%d\n", sizeof(&arr));//4/8---取出的是整个数组的地址,是地址就是4
    printf("%d\n", sizeof(&arr + 1));//4/8---取整个数组地址,+1跳过整个数组,
    //但是跳过之后仍是地址,是地址就是4
    printf("%d\n", sizeof(&arr[0] + 1));//4/8---&arr[0]是第一个元素,取地址,+1是第二个元素地址
    //是地址就是4
    printf("%d\n", strlen(arr));//6---strlen求字符串长度,遇到\0停止不计算是6
    printf("%d\n", strlen(arr + 0));//6---数组名是首元素地址,地址的长度是取决于数组长度
    //即数组里面什么时候遇到\0
    printf("%d\n", strlen(*arr));//代码错误---解引用(97),arr代表的是97,具体数字作地址不正确
    printf("%d\n", strlen(arr[1]));//代码错误---arr[98]也是确定值,具体数组做地址错误
    printf("%d\n", strlen(&arr));//6---取出的是整个数组的地址,长度是6
    printf("%d\n", strlen(&arr + 1));//随机值---整个该个数组的地址+6=下一个数组,情况未知
    printf("%d\n", strlen(&arr[0] + 1));//5,从第二个元素开始
    printf("*****************************************\n");
    char*p= "abcdef";//""等价于abcdef\0   p里面存放的是a的地址,p本身也有地址
    printf("%d\n", sizeof(p));//4/8---指针变量地址大小,指针大小都是4!!!
    printf("%d\n", sizeof(p + 1));//4/8--第二个指针变量地址大小,指针大小都是4!!!
    printf("%d\n", sizeof(*p));//1---指针首元素地址,解引用,第一个元素,a,是1个字节
    printf("%d\n", sizeof(p[0]));//1---p[0]->*(p+0),解引用指针首元素地址,变为a,是1
    printf("%d\n", sizeof(&p));//4/8---p的地址也是地址,地址大小都是4
    printf("%d\n", sizeof(&p + 1));//4/8---&p是地址,+1跳过p的地址,成为p之后的地址,但地址大小是4
    printf("%d\n", sizeof(&p[0] + 1));//4/8---&p[0]是第一个元素a,+1是第二个元素b的地址
    printf("%d\n", strlen(p));//6---从p的地址访问p,并拿出来a~f,直到\0,有6个,长度6
    printf("%d\n", strlen(p + 1));//5---从p的地址访问p,并拿出来b~f,直到\0,有5个
    printf("%d\n", strlen(*p));//代码错误---解引用(97),arr代表的是97,具体数字作地址不正确
    printf("%d\n", strlen(p[1]));//代码错误---arr[98]也是确定值
    printf("%d\n", strlen(&p));//随机值---取出的p的地址里面的内容是什么,未知,
    printf("%d\n", strlen(&p + 1));//随机值---整个该个数组的地址+6=下一个数组,情况未知
    printf("%d\n", strlen(&p[0] + 1));//5,从第二个元素的地址开始,b~f
    int  a[3][4] = { 0 };//地址大小是4个字节
    printf("%d\n", sizeof(a));//48---sizeof(数组名)表示整个数组大小,3*4*4
    printf("%d\n", sizeof(a[0][0]));//4/8--第一行第一列的元素所占空间大小
    printf("%d\n", sizeof(a[0]));//16---数组名[]->第一行所有的数组,计算的是4个元素所占空间大小
    printf("%d\n", sizeof(a[0]+1));//4/8---没单独放,则只是第一个元素地址,+1是第二个元素地址
    printf("%d\n", sizeof(*(a[0]+1)));//4/8---,a[0],没单独放,所以只是第一行第一个元素地址
    //a[0]+1是第一行第二个元素,解引用之后看int型,是4
    printf("%d\n", sizeof(a+1));//4---a是二维数组的数组名,并没有取地址,也没有单独放置sizeof内部
    //所以a表示二维数组首元素地址,及第一行的地址,a+1是二维数组第二行的地址
    printf("%d\n", sizeof(*(a + 1)));//16--计算第二行大小,等价于arr[1],4*4=16
    printf("%d\n", sizeof(&a[0] + 1));//4---数组名取地址取出的是整个数组的地址,
    //arr[0]是第一行的地址,+1是第二行的地址,地址都是4
    printf("%d\n", sizeof(*( & a[0] + 1)));//16---解引用第二行
    printf("%d\n", sizeof(*a));//16---对第一行解引用
    printf("%d\n", sizeof(a[3]));//16---arr[3]是第四行,看的是类型,不真实计算,用上一行代码!!
    return 0;
}
int main()
{
    short s = 5;
    int a = 4;
    printf("%d\n", sizeof(s = a + 6));//2        s说的算,s是short型,就得是short型
    printf("%d\n", s);//5
    return 0;
}
相关文章
|
10天前
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
25 3
|
10天前
使用指针访问数组元素
【10月更文挑战第31天】使用指针访问数组元素。
19 2
|
18天前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
24 1
|
1月前
链表指针的传参,传值和传地址
本文讨论了链表操作中指针传参的问题,特别是指针的传值与传地址的区别,并提供了修正代码,以确保链表插入操作能正确地修改指针指向的地址。
16 1
链表指针的传参,传值和传地址
|
28天前
|
存储
如何使用指针数组来实现动态二维数组
指针数组可以用来实现动态二维数组。首先,定义一个指向指针的指针变量,并使用 `malloc` 为它分配内存,然后为每个子数组分配内存。通过这种方式,可以灵活地创建和管理不同大小的二维数组。
|
28天前
|
存储
如何通过指针数组来实现二维数组?
介绍了二维数组和指针数组的概念及其区别,详细讲解了如何使用指针数组模拟二维数组,包括定义与分配内存、访问和赋值元素、以及正确释放内存的步骤,适用于需要动态处理二维数据的场景。
|
28天前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
1月前
魔法指针 之 二级指针 指针数组
魔法指针 之 二级指针 指针数组
17 1
|
1月前
|
C++
析构造函数就是为了释放内存,就是在局部指针消失前释放内存,拷贝构造函数就是以构造函数为模块,在堆里面新开一块,同一个变量在堆里面的地址
本文讨论了C++中构造函数和析构函数的作用,特别是它们在管理动态内存分配和释放中的重要性,以及如何正确地实现拷贝构造函数以避免内存泄漏。
36 2
|
1月前
|
存储
一篇文章了解区分指针数组,数组指针,函数指针,链表。
一篇文章了解区分指针数组,数组指针,函数指针,链表。
17 0