【结丹系列】 C指针进阶

简介: 进阶C指针
笔试题一

✅程序的结果是什么?

#include<stdio.h>
int main()
{
  int a[5] = { 1, 2, 3, 4, 5 };
  int *ptr = (int *)(&a + 1);
  printf( "%d,%d", *(a + 1), *(ptr - 1));
  return 0;
}

image-20220728162402928

详解:&a取出的是整个数组的地址 ,&a+1表示增加了一整个数组的大小,单位是字节

数组名a为首元素的地址&a[0],则*(a+1)即 a[1] 的值

故答案为2 5

笔试题二
#include<stdio,h>
int main()
{
  int a[4] = { 1, 2, 3, 4 };
  int *ptr1 = (int *)(&a + 1);
  int *ptr2 = (int *)((int)a + 1);
  printf( "%x,%x", ptr1[-1], *ptr2);
  return 0;
}

image-20220728174459683

详解:

&a取出的是整个数组的地址 ,&a+1表示增加了一整个数组的大小,单位是字节

ptr1[-1] = ptr1 -1 , 由图可知 ,(int *)(&a + 1) 在内存中指向的是 04 00 00 00

使用%x打印即 00 00 00 04, 故 ptr1[-1] = 4

由上图可知,(int*)((int)a+1) 在内存中指向的是 00 00 00 02

在小端存储模式下用十六进制表示,即 02 00 00 00

使用%x打印即 2 00 00 00, 故*ptr2 = 2 00 00 00

笔试题三
#include <stdio.h>
int main()
{
  int a[3][2] = { (0, 1), (2, 3), (4, 5) };
  int *p;
  p = a[0];
  printf( "%d", p[0]);
  return 0;
}

详解:

int a[3][2] = { (0, 1), (2, 3), (4, 5) };
//          =  {1,3,5}
//  1  3   a[0] 即第一行的数组名 ,p= a[0]则p[0] = a[0][0] = 1
//  5  0
//  0  0
笔试题四
#include<stdio.h>
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]);
  return 0;
}

image-20220730110813882

详解:

&p[4] [2] - &a[4] [2] 指针相减得到元素个数,为4个,又低地址-高地址,%d打印结果为 -4

使用%p打印时,打印-4地址

原码10000000 00000000 00000000 0000 0100

反码11111111 11111111 11111111 11111011

补码11111111 11111111 11111111 11111100

即FF FF FF FC

image-20220730105332096

笔试题五
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", *(ptr1 - 1), *(ptr2 - 1));
  return 0;
}

image-20220730214205052

详解:

&aa取出的是整个数组的地址 ,&aa+1表示增加了一整个数组的大小,单位是字节

aa 表示的是首元素的地址

笔试题六
#include <stdio.h>
int main()
{
  char *a[] = {"work","at","alibaba"};
  char**pa = a;
  pa++;
  printf("%s\n", *pa);
  return 0;
}

image-20220730220550896

详解: char* a[] 为一个存放字符串地址的数组,其中a 表示字符串”work“首元素的地址, 赋值给了pa

pa++时,向前移动一个char的大小,即指向字符串”at'' 的首元素的地址,故 pa = "at";

笔试题七
int main()
{
  char *c[] = {"ENTER","NEW","POINT","FIRST"};
  char**cp[] = {c+3,c+2,c+1,c};
  char***cpp = cp;
  printf("%s\n", **++cpp);
  printf("%s\n", *--*++cpp+3);
  printf("%s\n", *cpp[-2]+3);
  printf("%s\n", cpp[-1][-1]+1);
  return 0;
}

详解:如下示
#include<stdio.h>
#include<stdlib.h>
int main()
{
    char* c[] = {"ANTER","NEW","POINT","FIRST"};
    char** cp[] = {c + 3,c + 2,c + 1,c};
    char*** cpp = cp;
    printf("%s\n",**++cpp);//POINT 
    //cpp+1指向c+2,两次解引用后找到POINT
    
    printf("%s\n", *--*++cpp + 3);//ER
    //++cpp:cpp指向c+1
    //*(++cpp):得到c指针数组的第二个元素的指针的内容
    //--(*(++cpp)):第二个元素指针-1,得到第一个元素指针的内容
    //*(--(*(++cpp))):解引用得到ENTER
    //*(--(*(++cpp)))+3:指向E,输出ER
    
    printf("%s\n",*cpp[-2]+3);//ST
    //注意cpp到目前为止还是指向c+1,cpp[-2]指向的地址内容变化,cpp的指向并未变化
    //*cpp[-2]==*(*(cpp+(-2))) 所以*cpp[-2]指向,c+3,得到的是FIRST
    //*cpp[-2]+3指向S
    
    printf("%s\n",cpp[-1][-1]+1);//EW
    //注意cpp到目前为止还是指向c+1
    //cpp[-1][-1]+1 == *(*(cpp-1)-1)+1
    //*(cpp-1)指向c+2;
    //*(*(cpp-1)-1)指向c[2]的内容;
    //*(*(cpp-1)-1)+1指向NEW中的N
    return 0;
}

image-20220730224224874

相关文章
|
5月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
5月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
5月前
|
C语言
指针进阶(回调函数)(C语言)
指针进阶(回调函数)(C语言)
|
5月前
|
存储 C语言 C++
指针进阶(函数指针)(C语言)
指针进阶(函数指针)(C语言)
|
5月前
|
编译器 C语言
指针进阶(数组指针 )(C语言)
指针进阶(数组指针 )(C语言)
|
5月前
|
搜索推荐
指针进阶(2)
指针进阶(2)
47 4
|
5月前
指针进阶(3)
指针进阶(3)
41 1
|
5月前
|
C++
指针进阶(1)
指针进阶(1)
43 1
|
5月前
|
存储 安全 编译器
C++进阶之路:何为引用、内联函数、auto与指针空值nullptr关键字
C++进阶之路:何为引用、内联函数、auto与指针空值nullptr关键字
42 2
|
5月前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
49 0