许昌专业做网站公司,wordpress调用代码怎么用,网页qq登录保护怎么开启,微信公众号登录入口下载目录
代码展示#xff1a;
示例1#xff1a;指向数组结束位置之后的地址
示例2#xff1a;结构体大小对指针运算的影响
示例3#xff1a;访问数组元素的不同方式
示例4#xff1a;逗号表达式在数组初始化中的应用
示例5#xff1a;计算多维数组元素间的地址差值
示…
目录
代码展示
示例1指向数组结束位置之后的地址
示例2结构体大小对指针运算的影响
示例3访问数组元素的不同方式
示例4逗号表达式在数组初始化中的应用
示例5计算多维数组元素间的地址差值
示例6和7指针与二维数组及字符串数组的操作
示例8复杂指针表达式与字符串输出 指针是一个强大且灵活的工具它们允许我们以低级视角直接操作内存。本文将通过一系列实例深入解析指针如何与数组、结构体以及字符串相互作用并演示一些复杂的指针表达式。
代码展示
// 指针操作与数组、结构体相关示例// 示例1指针指向数组结束位置之后的地址
int main() {int a[5] { 1, 2, 3, 4, 5 };int* ptr (int*)((a 1)); // 指针ptr指向数组a最后一个元素之后的位置printf(%d,%d\n, *(a 1), *(ptr - 1)); // 输出数组第二个元素和最后一个元素的值return 0;
}// 解释
// 在C/C中a获取数组a的起始地址。由于数组在内存中是连续存储的加1后相当于指向数组结尾后的一个位置。
// *(a 1) 访问数组a的第二个元素索引为1。
// *(ptr - 1) 回溯到数组a的最后一个元素的地址并获取其值。// 示例2结构体Test大小为20字节时不同类型的指针运算结果
struct Test {int Num; // 通常占用4个字节char* pcName; // 指针类型在32位系统上占用4个字节short sDate; // short 类型占用2个字节char cha[2]; // 字符数组 cha 占用2个字节short sBa[4]; // 短整型数组 sBa 占用8个字节
}*p (struct Test*)0x10000;int main() {printf(%p\n, (p 0x1)); // 结果0x100014 -- 结构体指针1相当于增加一个结构体大小20字节printf(%p\n, (unsigned long)p 0x1); // 结果0x100001 -- 转换成无符号长整数后直接数字加1printf(%p\n, (unsigned int*)p 0x1); // 结果0x100004 -- 转换成无符号整数指针后指针加1相当于增加4/8字节return 0;
}// 示例3访问数组元素的不同方式
int main()
{int a[4] { 1,2,3,4 };int* ptr1 (int*)(a 1);//4 -- (ptr1[-1] *(ptr1-1)int* ptr2 (int*)((int)a 1);//0x200000 -- 0x00 000005 - 5 1 6 - 0x00 00 00 06printf(0x%x\n0x%x, ptr1[-1], *ptr2);return 0;
}// 示例4逗号表达式在初始化多维数组中的应用
int main() {int a[3][2] { (0,1),(2,3),(4,5) }; // 使用逗号表达式分别初始化每一行的元素int* p a[0];printf(%d, p[0]); // 输出1return 0;
}// 示例5计算多维数组元素之间的地址差值
int main()
{int a[5][5];//int(*)[5] -- 首元素int(*p)[4];//int(*)[4] p a; //将a的地址赋值给p//指针-指针取中间元素的个数printf(%p,%d\n, p[4][2] - a[4][2], p[4][2] - a[4][2]); //p[4][2] *(*(p4)2)return 0;
}// 示例6指向二维数组的指针操作
int main() {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, 5return 0;
}// 示例7指向字符数组的指针递增和字符串输出
int main() {char* a[] { Work,at,alibaba };char** pa a;pa;printf(%s\n, *pa); // 输出at// 示例8复杂指针表达式与字符串输出char* c[] { ENTER,NEW,POINT,FIRST };char** cp[] { c 3,c 2,c 1,c };char*** cpp cp;printf(%s\n, **cpp); // 输出POINTprintf(%s\n, *-- * cpp 3); // 输出ERprintf(%s\n, *cpp[-2] 3); // 输出stprintf(%s\n, cpp[-1][-1] 1); // 输出EWreturn 0;
}
示例1指向数组结束位置之后的地址
int main() {int a[5] { 1, 2, 3, 4, 5 };int* ptr (int*)((a 1)); // 指针ptr指向数组a最后一个元素之后的位置printf(%d,%d\n, *(a 1), *(ptr - 1)); // 输出数组第二个和最后一个元素的值
}
在这个示例中我们首先创建了一个包含5个整数的数组a。然后我们将一个指向整型的指针ptr初始化为数组a的结束位置之后的一个地址。由于数组是连续存储的因此*(ptr - 1)能够访问数组的最后一个元素。同时*(a 1)访问数组的第二个元素。
示例2结构体大小对指针运算的影响
struct Test {// ...
}*p (struct Test*)0x10000;int main() {printf(%p\n, (p 0x1)); // 结果反映了结构体大小// ...
}
此示例展示了结构体类型指针在进行算术运算时加1实际上意味着增加结构体所占用的字节数。在本例中根据Test结构体的定义其大小为20字节因此(p 0x1)的结果会增加相应的字节数。
示例3访问数组元素的不同方式
int main() {int a[4] { 1,2,3,4 };int* ptr1 (int*)(a 1);int* ptr2 (int*)((int)a 1);printf(0x%x,0x%x\n, ptr1[-1], *ptr2);
}
这里我们展示了两种不同的方法来计算数组结束后的地址并回溯至数组最后一个元素。这有助于理解指针如何基于数组首地址和类型大小进行移动。
示例4逗号表达式在数组初始化中的应用
int main() {int a[3][2] { (0,1),(2,3),(4,5) };// ...
}
通过逗号表达式可以分别初始化多维数组的每一行元素。例如在这个2D数组初始化中每个括号内的逗号表达式都用于设置该行的两个元素。
示例5计算多维数组元素间的地址差值
int main() {int a[5][5];// ...printf(%p,%d\n, p[4][2] - a[4][2], p[4][2] - a[4][2]);
}
示例6和7指针与二维数组及字符串数组的操作
在这两个示例中我们进一步探讨了指针如何遍历和访问二维数组及字符串数组的元素。通过对指针进行递增或利用复杂的指针表达式我们可以实现对数组深层次元素的灵活访问和操作。
// 示例6指向二维数组的指针操作
int main() {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, 5return 0;
}// 示例7指向字符数组的指针递增和字符串输出
int main() {char* a[] { Work,at,alibaba };char** pa a;pa;printf(%s\n, *pa); // 输出at
示例8复杂指针表达式与字符串输出
在最后一个示例中我们进一步展示了如何利用多级指针和复杂的指针表达式来访问和操作字符数组即字符串。例如
//cpp-1和cpp--(一个会改变cpp的位置但是cpp-1不会改变cpp当前的指向只是返回了一个对应的值)
int main()
{char* c[] { ENTER,NEW,POINT,FIRST };char** cp[] { c 3,c 2,c 1,c };char*** cpp cp;printf(%s\n, **cpp);//POINT -- c2printf(%s\n, *-- * cpp 3);//ER -- c2 c1printf(%s\n, *cpp[-2] 3);//st -- **(cpp-2)2printf(%s\n, cpp[-1][-1] 1);//EW -- *(*(cpp-1)-1 )1return 0;
}
在这个例子中我们首先创建了一个包含多个字符串的字符指针数组c。然后定义了二级指针数组cp其元素是c数组中的不同起始位置。最后通过三级指针cpp指向cp数组。
第一条语句将三级指针cpp递增后解引用两次得到的是cp[1]所指向的字符串即POINT。第二条语句先递增cpp并解引用一次然后对结果进行自减操作再解引用接着加上偏移量3得到的是POINT字符串从第四个字符开始的部分即ER。第三条语句直接使用cpp[-2]获取到cp数组中倒数第二个元素并在其基础上加3因此输出为NEW字符串从第三个字符开始的部分即st。最后一条语句通过cpp[-1][-1]获取到cp数组中最后一个元素所指向的字符串FIRST的最后一个字符F然后加1输出为EW。 通过这些复杂的指针表达式示例我们可以看到指针在C/C中能够实现灵活且深入的数据访问和操作但同时也要求开发者对其有深刻的理解以避免潜在的错误和陷阱。在实际编程中正确合理地使用指针可以大大提高代码效率同时也能让程序逻辑更为清晰和紧凑。