news 2026/5/2 17:52:14

关于数组和指针的一些问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
关于数组和指针的一些问题
#include <stdio.h> #include <string.h> int main() { //指针和数组笔试题解析 int a[] = { 1,2,3,4 }; printf("%d\n", sizeof(a));//16 a==&a[0] //sizeof(数组名),计算的是整个数组的大小单位是字节 printf("%d\n", sizeof(a+0));//4/8 a+0==&a[0]+0 //这里a表示数组首元素地址,a并没有单独放在sizeof内部,也没有取地址, //所以a就是首元素地址,a+0还是首元素地址 printf("%d\n", sizeof(*a));//4 *a==*&a[0] //*a中的a是数组首元素的地址,*a就是对首元素的地址解引用,找到的就是首元素 //首元素的大小就是4个字节 printf("%d\n", sizeof(a+1));//4 a+1==&a[0]+1 //这里的a是数组的首元素地址,a+1是第二个元素的地址 printf("%d\n", sizeof(a[1]));//4 //计算的是第二个元素的大小 printf("%d\n", sizeof(&a));//4/8 //&a取出的是数组的地址,数组的地址,也就是个地址 printf("%d\n", sizeof(*&a));//16 //&a---->int(*)[4] //&a拿到的是数组名的地址,类型是int(*)[4],是一种数组指针 //*&a----->a //也就是可以理解成:&和*相互抵消了,所以只有a了,就代表整个数组的大小了 printf("%d\n", sizeof(&a+1));//4/8 //&a取出的是数组的地址 //&a---->int(*)[4] //&a+1是从数组a的地址向后跳过了一个(4个整形元素的)数组的大小 //&a+1 还是地址,是地址就是4/8字节 printf("%d\n", sizeof(&a[0]));//4/8 //&a[0]就是第一个元素的地址 //计算的是地址的大小 printf("%d\n", sizeof(&a[0]+1)); //&a[0]就是第二个元素的地址 //大小是4/8个字节 //&a[0]+1---->&a[1] // char ass[] = { 'a','b','c','d','e','f' }; printf("%d\n", sizeof(ass));//6 //sizeof(数组名) printf("%d\n", sizeof(ass+0));//4/8 //ass+0 是数组首元素地址 printf("%d\n", sizeof(*ass));//1 //*ass就是数组的首元素,大小是1字节 //*ass --> ass[0] //*(ass+0) --> ass[0] printf("%d\n", sizeof(ass[1]));//1 printf("%d\n", sizeof(&ass));//4/8 //&ass是数组的地址,地址就是4/8个字节 printf("%d\n", sizeof(&ass+1));///4/8 //&ass+1是数组后的地址,跳过了整个数组 printf("%d\n", sizeof(&ass[0]+1));//4/8,&ass[0]会发生整型提升 //&ass[0]+1是第二个元素的地址 printf("%d", strlen(ass));//随机值 ///我们的数组中结尾并没有'\0',所以无法具体测量长度 printf("%d", strlen(ass+0));//随机值,与上述相同的原因 //printf("%d", strlen(*ass));//--> strlen('a')--strlen(97);//野指针问题 //printf("%d", strlen(ass[1]));//-->strlen('b')-->strlen(98) //printf("%d", strlen(&ass));//&ass取出数组地址,依旧随机值 //printf("%d", strlen(&ass+1));//随机值-6 //printf("%d", strlen(&ass[0]+1));//随机值 char arr1[] = "abcdef"; printf("%d\n", sizeof(arr1));//7 //a b c d e f \0 printf("%d\n", sizeof(arr1+0));//4/8 printf("%d\n", sizeof(*arr1));//1 printf("%d\n", sizeof(arr1[1]));//1 printf("%d\n", sizeof(&arr1));//4/8 printf("%d\n", sizeof(&arr1+1));//4/8 printf("%d\n", sizeof(&arr1[0]+1));//4/8 //strlen 是求字符串长度的,关注的是字符串中的\0,计算的是\0之前出现的字符的个数 //strlen是库函数,只针对字符串 //sizeof只关注占用内存空间的大小,不在乎内存中放的是什么 //sizeof是操作符 printf("%d\n", strlen(arr1));//6 printf("%d\n", strlen(arr1 + 0));//6 //printf("%d\n", strlen(*arr1));//err //printf("%d\n", strlen(arr1[1]));//err //printf("%d\n", strlen(&arr1));//6 //printf("%d\n", strlen(&arr1 + 1));//随机值 //printf("%d\n", strlen(&arr1[0] + 1));//5 const char* p = "abcdef"; printf("%d\n", sizeof(p));//4/8 printf("%d\n", sizeof(p+1));//4/8 printf("%d\n", sizeof(*p));//1 printf("%d\n", sizeof(p[0]));//1 printf("%d\n", sizeof(&p));//4/8 printf("%d\n", sizeof(&p+1));//4/8 printf("%d\n", sizeof(&p[0]+1));//4/8 printf("%d\n", strlen(p));//6 printf("%d\n", strlen(p+1));//5 //printf("%d\n", strlen(*p));//err //printf("%d\n", strlen(p[0]));//err //printf("%d\n", strlen(&p));//随机值 //printf("%d\n", strlen(&p+1));//随机值-5 printf("%d\n", strlen(&p[0]+1));//5 //二维数组 int a[3][4] = { 0 }; printf("%d\n", sizeof(a));//48 printf("%d\n", sizeof(a[0][0]));//4 printf("%d\n", sizeof(a[0]));//16 //a[0]是第一行这个一维数组的数组名,单独放在sizeof颞部,a[0]表示第一个整个这个一维数组 //sizeof(a[0])计算的就是第一行的大小 printf("%d\n", sizeof(a[0]+1));//4 --a[0][0]+1 //a[0]并没有单独放在sizeof内部,也没取地址,a[0]就是首元素的地址 //就是第一行这个一维数组的第一个元素的地址,a[0]+1就是第一行第二个元素的地址 printf("%d\n", sizeof(*(a[0]+1));//4 //a[0] + 1就是第一行第二个元素的地址 //*(a[0] + 1)就是第一行第二个元素 printf("%d\n", sizeof(a+1));//4/8 //a虽然是二维数组的地址,但是并没有单独放在sizeof内部,也没取地址 //a表示首元素地址,二维数组的首元素是他的第一行,a就是第一行地址 //a+1就是跳过第一行,表示第二行的地址 printf("%d\n", sizeof(*(a+1));//16 //*(a+1)是对第二行地址的解引用拿到的是第二行的大小 //*(a+1)-->a[1] printf("%d\n", sizeof(&a[0]+1));//4/8 //&a[0]是第一行的数组名,拿出的是第一行的地址 //&a[0]+1得到的是第二行的地址 printf("%d\n", sizeof(*(a[0]+1));//16 printf("%d\n", sizeof(*a));//16 //a表示首元素的地址,就是第一行的地址 //*a就是第一行地址的解引用,拿到的就是第一行 printf("%d\n", sizeof(a[3]));//16 printf("%d\n", sizeof(a[0]));//16 一个道理 //数组名的意义 /* 1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小 2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址 3.除此之外所有的数组名都表示首元素的地址 */ return 0; }

#include <stdio.h> void test1() { int a[5] = { 1,2,3,4,5 }; int* ptr = (int*)(&a + 1);//&a是数组的地址-->int(*)[5] //&a+1跳过了整个数组, printf("%d %d\n", *(a + 1), *(ptr - 1));//2 5 } struct Test {//这里告知结构体的大小是20个字节 int Num; char* pcName; short sDate; char cha[2]; short sBa[4]; }*p = (struct Test*)0x100000; //假设p的值为0x100000。test2中表达式的值分别是多少, //已知,结构体Tset类型的变量大小是20个字节 //x86环境 void test2() { printf("%p\n", p + 0x1);//16进制表示20-->14 //0x100000+20-->0x100014 printf("%p\n", (unsigned long)p + 0x1); //(unsigned long)p-->1048576+0x1-->1048576+1->1048577-->0x100001 printf("%p\n", (unsigned int*)p + 0x1); //0x100000+4-->0x100004 } void test3() { int a[4] = { 1,2,3,4 }; int* ptr1 = (int*)(&a + 1); int* ptr2 = (int*)((int)a + 1);//%x,打印16进制 //假设a=0x00012ff40 //a+1-->0x0012ff44 //(int)a+1-->0x12ff41,处于1-2之间 printf("%x,%x", ptr1[-1], *ptr2);//4 2000000 //低-----------------------------------高 //10 (00 00 00 02) 00 00 00 03 00 00 00 04 00 00 00 //ptr2-->00 00 00 02 //小端 //ptr1[-1]-->*(ptr1+(-1))-->*(ptr1-1) } void test4() { int a[3][2] = { (0,1),(2,3),(4,5) };//实际-->{ 1, 3, 5 ,0 , 0, 0} int* p; p = a[0]; printf("%d", p[0]);//1 p[0]-->*(p+0) } //void test5() {//x86 // int a[5][5]; // int (*p)[4]; // p = a; // //-4 // //补码:11111111111111111111111111111100 // //16进制:FF FF FF FC // printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);// -4 // /* // p[4][2]-->*((p+4)+2) |&p[4][2] // [][][][][][][][][][][][][][][][][][][][][][][][][] // 0 1 2 3 4 |&a[4][2] // |p |p+1 |p+2 |p+3 |p+4 // */ // } void test6() { int aa[2][5] = { 1,2,3,4,5,6,7,8,9,10 }; int* ptr1 = (int*)(&aa + 1); int* ptr2 = (int*)(*(aa + 1)); printf("%d %d\n", *(ptr1 - 1), *(ptr2 - 1));//10 5 } void test7() { const char* a[] = { "work","at","alibaba" }; const char** pa = a; pa++; printf("%s\n", *pa);//at } void test8() { const char* c[] = { "ENTER","NEW","POINT","FIRST" }; const char** cp[] = { c + 3,c + 2,c + 1,c }; const char*** cpp = cp; printf("%s\n", **++cpp);//POINT printf("%s\n", *-- * ++cpp + 3);//ER printf("%s\n", *cpp[-2] + 3);//ST printf("%s\n", cpp[-1][-1] + 1);//EW } int main() { /*test1(); test2(); test3(); test4(); test5(); test6(); test7();*/ test8(); return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/25 4:00:51

移动端AI图像生成的性能突围:从算力瓶颈到流畅体验

移动端AI图像生成的性能突围&#xff1a;从算力瓶颈到流畅体验 【免费下载链接】denoising-diffusion-pytorch Implementation of Denoising Diffusion Probabilistic Model in Pytorch 项目地址: https://gitcode.com/gh_mirrors/de/denoising-diffusion-pytorch 你是否…

作者头像 李华
网站建设 2026/5/2 7:46:12

兜兜英语:前缀cata- 向下、完全、分解、灾祸

1. catastrophe /kəˈtstrəfi/ &#x1f50d; 含义&#xff1a;大灾难、浩劫&#xff08;cata- 灾祸 strophe 转折 → 命运急转直下的灾祸&#xff09;&#x1f631; Emoji 记忆&#xff1a;&#x1f32a;️&#x1f4a5;&#xff08;地震、爆炸等灾难场景&#xff09;&…

作者头像 李华
网站建设 2026/5/1 4:26:26

LobeChat能否实现AI小说创作?情节生成与风格模仿研究

LobeChat 能否实现 AI 小说创作&#xff1f;情节生成与风格模仿的实践探索 在当代文学创作中&#xff0c;一个越来越频繁被提及的问题是&#xff1a;AI 是否能真正“写小说”&#xff1f;不是简单地拼接句子或生成套路化桥段&#xff0c;而是具备连贯的情节推进能力、稳定的人物…

作者头像 李华
网站建设 2026/4/21 21:11:58

5、Linux 用户与组管理全解析

Linux 用户与组管理全解析 1. 系统配置文件 1.1 /etc/login.defs 该文件包含了用户和组创建工具(如 useradd 和 usergroup )使用的系统范围的值。其中定义了用户和组 ID 的可能范围, UID_MIN 是用户 ID 的最小值, UID_MAX 是最大值。还包含各种密码选项,例如 …

作者头像 李华
网站建设 2026/4/28 20:54:01

AI驱动的动态价值投资策略适应

AI驱动的动态价值投资策略适应 关键词:AI、动态价值投资策略、机器学习、市场适应、量化分析 摘要:本文聚焦于AI驱动的动态价值投资策略适应这一前沿话题。首先介绍了该研究的背景,包括目的、预期读者、文档结构和相关术语。接着阐述了核心概念,如AI与价值投资的联系,并通…

作者头像 李华