C-指针笔试题

简介: C-指针笔试题

一维数组

#include<stdio.h>
int main()
{
  char arr[] = "abcdef";
  printf("%d\n", sizeof(arr));//7  sizeof(arr)计算的是数组的大小,单位是字节
  printf("%d\n", sizeof(arr + 0));//4/8  计算的是数组首元素地址的大小。arr+0是首元素地址。
  printf("%d\n", sizeof(*arr));//1  *arr是首元素,sizeof(*arr)计算的是首元素的大小。
  printf("%d\n", sizeof(arr[1]));//1  sizeof(arr[1])计算的是第二个元素的大小。
  printf("%d\n", sizeof(&arr));//4/8  &arr虽然是数组的地址,但也是地址,所以是4/8个字节。
  printf("%d\n", sizeof(&arr + 1));//4/8  &arr+1是跳过整个数组后的地址,但也是个地址。
  printf("%d\n", sizeof(&arr[0] + 1));//4/8  &arr[0]是第一个元素的地址,&arr[0]+是第二个元素的地址。类型为char*,char*的地址+1之后指向的就是第二个元素,但也是个地址。
  return 0;
}

分割线---------------------------------------------------------------------------------------

#include<stdio.h>
int main()
{
  char arr[] = "abcdef";
  printf("%d\n", strlen(arr));//6
  printf("%d\n", strlen(arr + 0));//6  与上面那种写法等价
  //printf("%d\n", strlen(*arr));//err  非法访问内存,
  //printf("%d\n", strlen(arr[1]));//err  非法访问内存
  printf("%d\n", strlen(&arr));//6  但是会报警告  &arr - 数组的地址 - 数组指针(数组的地址就应该放到数组指针里面去) - char (*p)[7] =&arr
  printf("%d\n", strlen(&arr + 1));//随机值  跳过的是整个数组
  printf("%d\n", strlen(&arr[0] + 1));//取出第一个元素的地址之后加一就变成了第一个元素的地址
  //补充一点,strlen函数的参数类型是const char* str
  return 0;
}

分割线---------------------------------------------------------------------------------------

#include<stdio.h>
int main()
{
  char* p = "abcdef";
  printf("%d\n", sizeof(p));//4/8  把常量字符串首字符的地址放到sizeof中去,p里存放的是常量字符串首字符的地址,这里是计算指针变量p的大小
  printf("%d\n", sizeof(p + 1));//p+1得到的是字符b的地址,地址的大小就是4/8个字节
  printf("%d\n", sizeof(*p));//1  *p就是字符串的第一个字符'a'
  printf("%d\n", sizeof(p[0]));//1  p[0]也是字符串的第一个字符'a'  arr[i] == *(arr+i)
  printf("%d\n", sizeof(&p));//4/8
  printf("%d\n", sizeof(&p + 1));//4/8  &p+1拿到的是p这个变量的地址
  printf("%d\n", sizeof(&p[0] + 1));//4/8  这里拿到的是'b'的地址
  return 0;
}

分割线---------------------------------------------------------------------------------------


#include<stdio.h>
int main()
{
  char* p = "abcdef";
  printf("%d\n", strlen(p));//6
  printf("%d\n", strlen(p + 1));//5
  //printf("%d\n", strlen(*p));//error
  //printf("%d\n", strlen(p[0]));//error
  printf("%d\n", strlen(&p));//随机值 运行但会出警告
  printf("%d\n", strlen(&p + 1));//随机值
  printf("%d\n", strlen(&p[0] + 1));//5  取出第二个元素的地址
  return 0;
}

二维数组

//二维数组
#include<stdio.h>
int main()
{
  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()内,计算的是第一行的大小
  printf("%d\n", sizeof(a[0] + 1));//4/8  a[0]是第一行的数组名,数组名此时是首元素的地址,这里的a[0]其实就是第一行第一个元素的地址
  //所以a[0]+1就是第一行第二个元素的地址,其实就是第一行第一个元素的地址a[0]+1表示第一行第二个元素的地址,地址大小为4/8个字节
  printf("%d\n", sizeof(*(a[0] + 1)));//4  计算的是第一行第二个元素的大小
  printf("%d\n", sizeof(a + 1));//4/8  a是二维数组的数组名,没有sizeof(数组名),也没有&(数组名),所以a是首元素地址,
  //,而把二维数组看成一维数组时,而二维数组首元素是他的第一行一维数组。a就是第一行(首元素)的地址,则a+1是第二行一维数组的地址。
  printf("%d\n", sizeof(*(a + 1)));//16  a+1上面提到是第二行一维数组的地址,解引用就是计算的第二行一维数组的元素
  printf("%d\n", sizeof(&a[0] + 1));//4/8  &a[]+1是第二行的地址
  printf("%d\n", sizeof(*(&a[0] + 1)));//16
  printf("%d\n", sizeof(*a));//16  a是首元素地址,*a就是第一行,sizeof(*a)就是计算第一行一维数组的地址
  printf("%d\n", sizeof(a[3]));//16  sizeof()中括号内的表达h事不会计算,a[3]不会真的去访问第四行,这里只要a[3],即把第四行的数组名往这里一放
  //其就是有它所对应的类型,第四行一维数组的类型是a[3],所以这里a[3]和a[0]是一个道理,虽然没有第四行,但没关系,sizeof不会真的访问
  //sizeof内部的表达式是不参与任何计算的,只是根据它的类型计算它的大小。
  return 0;
}


分割线---------------------------------------------------------------------------------------


总结(数组名的意义)

数组名的意义:


1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。

2.&数组名,这里的数组名表示整个数组,取出的是整个数组的大小。

3.除此之外所有的数组名都表示首元素的地址。

指针笔试题

T1

T2

//T2
#include<stdio.h>
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);//00100014
  printf("%p\n", (unsigned long)p + 0x1);//00100001
  printf("%p\n", (unsigned int*)p + 0x1);//00100004
  //x86环境下的结果
  //指针+-整数,加几减几取决于指针类型
  return 0;
}

T3

//T3
//注意是在x86环境下,x64环境会报错
#include<stdio.h>
int main()
{
  int a[4] = { 1,2,3,4 };
  int *ptr1 = (int*)(&a + 1);
  int *ptr2 = (int*)((int)a + 1);//这里(int)a是把首元素地址转换为了数字,然后加1,又(int*)转换回了地址,
  //相当于地址向后移动一个字节
  printf("%x %x", ptr1[-1], *ptr2);//4 2000000
  //%x意思是16进制输出(以16进制输出变量地址)C语言中是用在标准输出和
  //输入函数里的格式控制符。把整数值按16进制输出,不带前导0x
  return 0;
}

3.png


T4

//T4

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


4.png


T5

//T5
//X86环境下
#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;
}

5.1.png

5.2.png


T6

//T6
//X86
#include<stdio.h>
int main()
{
  int a[2][5] = { 1,2,3,4,5,6,7,8,9,10 };
  int* ptr1 = (int*)(&a + 1);//10
  int* ptr2 = (int*)(*(a + 1)); //5   //*(a+1)==a[1]  第二行首元素地址  故这里的强制类型转换是多余的
  printf("%d %d\n", *(ptr1 - 1), *(ptr2 - 1));
  return 0;
}

注意:a+1是第二行一维数组地址,对a+1解引用,即*(a+1)得到的是该数组首元素的地址。这里*(a+1)相当于a[1],而a[1]就是第二行的首元素地址。a+1是一个数组指针,数组指针解引用得到该数组首元素的地址。


T7

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

7.png


BOSS

//最好画图,帮助理解
#include<stdio.h>
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;
}

8.1.png

8.2.png

最后,指针笔试题到这里至此结束,另外在学习指针的时候一定要勤动手,多画图。

目录
相关文章
|
7月前
|
C语言
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
|
7月前
|
C语言
指针和数组笔试题解析(最详细解析,没有之一)
指针和数组笔试题解析(最详细解析,没有之一)
55 0
|
7月前
|
存储 编译器 C语言
经典指针与数组笔试题——C语言
经典指针与数组笔试题——C语言
|
6月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
7月前
|
存储 编译器 C语言
C语言初阶⑦(指针初阶)知识点+笔试题(上)
C语言初阶⑦(指针初阶)知识点+笔试题
44 0
|
6月前
|
存储 C++
有关【指针运算】的经典笔试题
有关【指针运算】的经典笔试题
34 4
指针与数组笔试题解析
指针与数组笔试题解析
|
7月前
|
C语言
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)(上)
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)
46 0
|
7月前
指针笔试题模拟
指针笔试题模拟
32 0
|
7月前
进阶指针笔试题
进阶指针笔试题
35 0