C进阶:指针的练习(1)

简介: C进阶:指针的练习(1)

 

常见数组笔试题分析

一维数组

知识点回顾

1.数组名是数组1首元素的地址。

2.有两个例外:(1)sizeof(数组名)中这里的数组名是整个数组,计算的也是整个数组大小

                        (2)&数组名:这里的数组名表示整个数组的地址(但以首元素地址存在)

#include <stdio.h>
 
int main()
{
  int a[] = {1,2,3,4};
  //a代表整个数组的大小,每个元素的大小为sizeof(int),所以这里是4*4=16
  printf("%d\n", sizeof(a));
  //a并未单独存在,所以这里a是首元素地址,a+0还是首元素地址,大小为(4/8)分两种平台
  //32位为4,64位为8
  printf("%d\n", sizeof(a + 0));
  //*a是首元素,大小为int类型,因此为4
  printf("%d\n", sizeof(*a));
  //a+1是数组第二个元素地址,大小为(4/8)
  printf("%d\n", sizeof(a + 1));
  //第二个元素大小为4
  printf("%d\n", sizeof(a[1]));
  //整个数组的地址,但是以首元素地址呈现,因此为4
  printf("%d\n", sizeof(&a));
  //*与&相抵消,等效于a,因此是16
  printf("%d\n", sizeof(*&a));
  //&a+1跳过了一整个数组,虽然越界了,但是这里它的类型仍为int*,所以大小为(4/8)
  printf("%d\n", sizeof(&a + 1));
  //首元素地址大小,(4/8)
  printf("%d\n", sizeof(&a[0]));
  //第二个元素地址,(4/8)
  printf("%d\n", sizeof(&a[0] + 1));
  return 0;
}

字符数组

知识点回顾:

1.strlen函数求字符串长,统计的是在字符串中'\0'之前的字符个数,如果没碰见'\0'就会一直向后面找。

2.strlen函数的参数部分需要传一个地址,当传递比如说是一个字符时,就是将该字符的Ascii码值传入,函数就从这个Ascii值开始统计,造成非法访问

#include <stdio.h>
 
int main()
{
  char arr[] = { 'a','b','c','d','e','f' };
  //计算的是整个数组大小,为6*1
  printf("%d\n", sizeof(arr));
  //代表首元素地址
  printf("%d\n", sizeof(arr + 0));
  //*arr是首元素,解引用后大小为1
  printf("%d\n", sizeof(*arr));
  //数组第二个元素,所以是2
  printf("%d\n", sizeof(arr[1]));
  //是数组地址,为(4/8)
  printf("%d\n", sizeof(&arr));
  //跳过整个数组的地址,但还是地址,为(4/8)
  printf("%d\n", sizeof(&arr + 1));
  //第二个元素的地址(4/8)
  printf("%d\n", sizeof(&arr[0] + 1));
  return 0;
}
#include <stdio.h>
#include <string.h>
 
int main()
{
  char arr[] = { 'a','b','c','d','e','f' };
  //arr是数组地址,strlen会一直向后找到'/0'再停止,此处未知'/0'在何处,所以是随机值
  printf("%d\n", strlen(arr));
  //arr + 0是首元素地址,其余同上,为随机值
  printf("%d\n", strlen(arr + 0));
  //*arr是首元素,此处传过去了'a'的Ascii码值,造成了非法访问
  printf("%d\n", strlen(*arr));
  //arr[1]是数组第二个元素,同上,造成了非法访问
  printf("%d\n", strlen(arr[1]));
  //随机值
  printf("%d\n", strlen(&arr));
  //随机值
  printf("%d\n", strlen(&arr + 1));
  //随机值
  printf("%d\n", strlen(&arr[0] + 1));
  return 0;
}
#include <stdio.h>
#include <string.h>
 
int main()
{
  char arr[] = "abcdef";
  //从首元素开始计算,遍历到第七个元素才找到'\0',不算上'\0',因此为6
  printf("%d\n", strlen(arr));
  //这块还是从首元素开始,同上,为6
  printf("%d\n", strlen(arr + 0));
  //*arr是首元素,造成非法访问,err
  printf("%d\n", strlen(*arr));
  //数组第二个元素,同上,err
  printf("%d\n", strlen(arr[1]));
  //&arr代表数组地址(在这里是首元素地址),同上,为6
  printf("%d\n", strlen(&arr));
  //跳过一整个数组后的地址,由于不知道后面'\0'在哪,所以为随机值
  printf("%d\n", strlen(&arr + 1));
  //从第二个元素向后遍历,为5
  printf("%d\n", strlen(&arr[0] + 1));
  return 0;
}
#include <stdio.h>
#include <string.h>
 
int main()
{
  char* p = "abcdef";
  //p是一个指针变量,(4/8)
  printf("%d\n", sizeof(p));
  //p+1是'b'的地址,(4/8)
  printf("%d\n", sizeof(p + 1));
  //*p是首元素,大小为1
  printf("%d\n", sizeof(*p));
  //p[0]->*(p+0),还是首元素,为一
  printf("%d\n", sizeof(p[0]));
  //&p表示一级指针的地址,类型为char**,大小为(4/8)
  printf("%d\n", sizeof(&p));
  //越过一个指针变量p的下一个地址,为(4/8)
  printf("%d\n", sizeof(&p + 1));
  //&p[0] + 1是'b'的地址,为(4/8)
  printf("%d\n", sizeof(&p[0] + 1));
  return 0;
}
#include <stdio.h>
#include <string.h>
 
int main()
{
  char* p = "abcdef";
  //p表示a的地址,从此向后开始计数,为6
  printf("%d\n", strlen(p));
  //p+1表示b的地址,从此向后开始计数,为5
  printf("%d\n", strlen(p + 1));
  //*p表示首元素,非法寻址,err
  printf("%d\n", strlen(*p));
  //同上,err
  printf("%d\n", strlen(p[0]));
  //&p表示一级指针p的地址,与原字符串无关系,因此是随机值
  printf("%d\n", strlen(&p));
  //同上,随机值
  printf("%d\n", strlen(&p + 1));
  //表示b的地址,所以为5
  printf("%d\n", strlen(&p[0] + 1));
  return 0;
}

二维数组

#include<stdio.h>
 
int main()
{
  int a[3][4] = { 0 };
  //整个数组的大小,为3*4*4=48;
  printf("%d\n", sizeof(a));
  //数组第一行第一列的元素,大小为4
  printf("%d\n", sizeof(a[0][0]));
  //将一行看为二维数组的一个元素,a[0]就是第一行这个一维数组的数组名,因此为4*4=16
  printf("%d\n", sizeof(a[0]));
  //a[0]作为第一行数组名,没有单独放在sizeof内部,所以这里计算的可能是地址而不是数组
  //a[0]可以看作首元素地址即a[0][0],+1表示第一行第二个元素的地址,大小为(4/8)
  printf("%d\n", sizeof(a[0] + 1));
  //解引用后计算的是第一行第二个元素的地址,为4
  printf("%d\n", sizeof(*(a[0] + 1)));
  //该数组的首元素类型为int(*)[4],a+1就是访问第二行的地址,为(4/8)
  printf("%d\n", sizeof(a + 1));
  //解引用,表示的是第二行的元素,大小为16
  printf("%d\n", sizeof(*(a + 1)));
  //&a[0]+1表示第二行的地址,为(4/8)
  printf("%d\n", sizeof(&a[0] + 1));
  //解引用后表示第二行,大小为16
  printf("%d\n", sizeof(*(&a[0] + 1)));
  //*a表示第一行元素,为16
  printf("%d\n", sizeof(*a));
  //这里a[3]虽然越界了,但sizeof这个关键字只运算,仅看内部类型,a[3]的类型为int[4],因此大小为16
  printf("%d\n", sizeof(a[3]));
  return 0;
}

好了,关于数组的题目就介绍到这里,下一篇将详细地讲一下指针笔试题,感谢各位未来大厂员工的支持!!!

相关文章
|
5天前
|
存储
指针进阶详解(下)
指针进阶详解(下)
22 0
|
5天前
|
C语言
【C语言】指针进阶之sizeof和strlen函数的对比
【C语言】指针进阶之sizeof和strlen函数的对比
|
5天前
|
C语言
C语言---指针进阶
C语言---指针进阶
22 0
|
5天前
C进阶:指针的进阶(4)
C进阶:指针的进阶(4)
|
5天前
|
存储 C语言 C++
C语言指针进阶-1
C语言指针进阶-1
28 1
|
5天前
指针应用基础练习
指针应用基础练习
7 0
|
5天前
|
存储 人工智能
指针的应用练习(数组与指针的关系)
指针的应用练习(数组与指针的关系)
15 0
|
5天前
|
搜索推荐 C语言
详解指针进阶2
详解指针进阶2
|
5天前
|
存储 编译器 C语言
指针进阶详解(上)
指针进阶详解(上)
87 0
指针进阶详解(上)

热门文章

最新文章