C语言指针经典面试题——第一弹

简介: 笔记
#include<stdio.h>
int main()
{
  int a[] = { 1,2,3,4 };
  printf("%d\n", sizeof(a));
  //结果是16,这里算的是整个数组
  printf("%d\n", sizeof(a + 0));
  //结果是4或8,这里算的是第一个地址的大小
  printf("%d\n", sizeof(*a));
  //结果是4,这里算的是首元素大小
  printf("%d\n", sizeof(a + 1));
  //结果是4或8,这里算的是第二个地址的大小
  printf("%d\n", sizeof(a[1]));
  //结果是4,这里算的是第二个元素的大小
  printf("%d\n", sizeof(&a));
  //结果是4或8,这里算的是整个数组的地址大小
  printf("%d\n", sizeof(*&a));
  //结果是16,这里先是取出整个数组地址,然后对整个数组解引用,也就是算出的是整个数组的大小
  printf("%d\n", sizeof(&a + 1));
  //结果是4或8,这里跳过了整个数组,计算数组后面的地址大小,所以是4或8,&a的类型是int(*)[4]
  printf("%d\n", sizeof(&a[0]));
  //结果是4或8,这里算的是第一个元素的地址大小
  printf("%d\n", sizeof(&a[0] + 1));
  //结果是4或8,这里算的是第二个元素的地址大小
  return 0;
}

注意:这里&a的类型是int(*)[4],数组指针,1.png

&a+1是跳过整个数组

sizeof()和char型一维数组


  char arr[] = { 'a','b','c','d','e','f' };
  printf("%d\n", sizeof(arr));
  //6,这里计算的是整个数组
  printf("%d\n", sizeof(arr + 0));
  //4或8,这里计算的是第一个元素的地址
  printf("%d\n", sizeof(*arr));
  //1,这里计算的是第一个元素的大小
  printf("%d\n", sizeof(arr[1]));
  //1,哲理计算的是第二个元素的大小
  printf("%d\n", sizeof(&arr));
  //4或8,这里计算的是整个数组的地址大小
  printf("%d\n", sizeof(&arr + 1));
  //还是4或8,这里计算的是跳过整个数组之后,整个地址的大小
  printf("%d\n", sizeof(&arr[0] + 1));
  //还是4或8,这里计算的是第二个元素的地址大小

strlen和char型一维数组


  char arr[] = { 'a','b','c','d','e','f' };
  printf("%d\n", strlen(arr));
  //随机值,这里计算的是整个数组,即从第一个元素开始往后计算直到找到\0位置,随机值是因为这个数组里面没有\0
  printf("%d\n", strlen(arr + 0));
  //随机值,这里strlen是从第一个元素开始往后数,随机值的值跟上面的值一样
  printf("%d\n", strlen(*arr));
  //报错,这里传的是第一个元素,第一个元素是一个值,strlen()括号里面的必须是char *类型的指针变量,而这里面的元素是char类型不是char *类型,若把'a'传过去,则相当于把97当作指针穿了过去
  printf("%d\n", strlen(arr[1]));
  //报错,传的是第二个元素,跟上面的值一样
  printf("%d\n", strlen(&arr));
  //随机值,跟前面一样,传的是整个地址,整个地址是从第一个元素的地址开始的,随意会产生随机值,由于是从第一个元素开始,所以产生的结果会跟第一个一样
  printf("%d\n", strlen(&arr + 1));
  //随机值,这里是跳过了整个数组,然后开始计算,遇到\0便停止,跟第一个随机值相差6
  printf("%d\n", strlen(&arr[0] + 1));
  //随机值,从第二个元素的地址开始计算,遇到\0停止,跟第一个随机值相差1

sizeof()和字符串数组


  char arr[] = "abcdef";
  printf("%d\n", sizeof(arr));
  //7,有\0
  printf("%d\n", sizeof(arr + 0));
  //4或8,计算的是地址大小,从第一个元素的地址开始计算
  printf("%d\n", sizeof(*arr));
  //1,计算的是是第一个元素的大小
  printf("%d\n", sizeof(arr[1]));
  //1,计算的是第二个元素的大小
  printf("%d\n", sizeof(&arr));
  //4或8,计算的是整个地址
  printf("%d\n", sizeof(&arr + 1));
  //4或8,跳过这个数组后,计算后面的地址大小
  printf("%d\n", sizeof(&arr[0] + 1));
  //4或8,跳过第一个元素后,计算后面的地址大小,而不是数组里面的内容大小

sizeof和字符串数组


  char arr[] = "abcdef";
  printf("%d\n", sizeof(arr));
  //7,有\0
  printf("%d\n", sizeof(arr + 0));
  //4或8,计算的是地址大小,从第一个元素的地址开始计算
  printf("%d\n", sizeof(*arr));
  //1,计算的是是第一个元素的大小
  printf("%d\n", sizeof(arr[1]));
  //1,计算的是第二个元素的大小
  printf("%d\n", sizeof(&arr));
  //4或8,计算的是整个地址
  printf("%d\n", sizeof(&arr + 1));
  //4或8,跳过这个数组后,计算后面的地址大小
  printf("%d\n", sizeof(&arr[0] + 1));
  //4或8,跳过第一个元素后,计算后面的地址大小,而不是数组里面的内容大小

strlen和字符串


  char arr[] = "abcdef";
  printf("%d\n", strlen(arr));
  //6,遇到\0停止打印
  printf("%d\n", strlen(arr + 0));
  //6,遇到\0停止打印
  printf("%d\n", strlen(*arr));
  //报错,传的不是char *类型
  printf("%d\n", strlen(arr[1]));
  //报错,穿的不是char*类型
  printf("%d\n", strlen(&arr));
  //6,传的是整个数组地址,从第一个元素的地址开始
  printf("%d\n", strlen(&arr + 1));
  //随机值,跨过整个数组之后,开始计算遇到\0停止
  printf("%d\n", strlen(&arr[0] + 1));
  //5,从第二个元素开始计算,遇到\0停止

字符指针和sizeof()


  char* p = "abcdef";
  printf("%d\n", sizeof(p));
  //4或8,这里的p是指针,p里面村的是第一个元素的地址,
  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,&p是二级指针
  printf("%d\n", sizeof(&p + 1));
  //4或8,跨过了整个数组
  printf("%d\n", sizeof(&p[0] + 1));
  //4或8,从第二个元素开始计算地址的大小

字符指针和strlen()


  char* p = "abcdef";
  printf("%d\n", strlen(p));
  //6,p是首元素地址
  printf("%d\n", strlen(p + 1));
  //5,从第二个元素开始计算
  printf("%d\n", strlen(*p));
  //报错,因为穿的是一个值,不是char *类型的
  printf("%d\n", strlen(p[0]));
  //报错,传的是一个值,不是char *类型的
  printf("%d\n", strlen(&p));
  //随机值,p是一个一级指针,&p就是一个二级指针,也就是说这里的strlen是从p的地址开始向后数的遇到\0停止
  printf("%d\n", strlen(&p + 1));
  //随机值,跨过了整个数组,然后开始计算遇到\0位置
  printf("%d\n", strlen(&p[0] + 1));
  //随机值,从第一个元素开始计算遇到\0为止,这个和上面的相差的数字也是随机值,不是一个确定的数,因为他们遇到\0的情况不相同
  //倒数第二个和倒数第一个相差的值,是一个随机值,因为&p是从p的地址开始数,当没到&p[0]+1时,可能会出现\0也有可能不会出现\0,而&p[0]+1,时从第二个元素的地址开始数,什么时候遇到\0则说不准

4.png3.png

&p+1和&p[0]+1结果相差为随机值的原因,有可能在p[0]+1往右移动且没到达&p+1的时候遇到\0,也有可能会和&p+1遇到同一个\0,由于这里的\0具有不确定性,所以他们俩者相差的就是一个随机值。

二维数组和sizeof()


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]第一行元素的大小
printf("%d\n", sizeof(a[0] + 1));
//4/8,这里的a[0]不再单独放在()内部,有+1的操作,所以这里的a[0]表示首元素的地址,+1就表示第二个元素地址的大小,所以这里的是地址
printf("%d\n", sizeof(*(a[0] + 1)));
//4,这个是第一行,第二个元素的大小
printf("%d\n", sizeof(a + 1));
//4/8,a有+1的操作,所以a表示首元素地址,即第一行,a+1就是第二行的地址,由于算的是地址所以是4/8
printf("%d\n", sizeof(*(a + 1)));
//16,第二行元素的大小
printf("%d\n", sizeof(&a[0] + 1));
//4/8,第二行的地址
printf("%d\n", sizeof(*(&a[0] + 1)));
//16,第二行的数组大小
printf("%d\n", sizeof(*a));
//16,a表示首元素地址,*a就是解引用,所以是16
printf("%d\n", sizeof(a[3]));
//16,这里并没有越界,因为他没有去访问第四行

总结


数组名的意义:


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

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

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


相关文章
|
17小时前
|
编译器 程序员 C语言
从C语言到C++⑨(第三章_C&C++内存管理)详解new和delete+面试题笔试题(下)
从C语言到C++⑨(第三章_C&C++内存管理)详解new和delete+面试题笔试题
5 0
|
17小时前
|
编译器 C语言 C++
从C语言到C++⑨(第三章_C&C++内存管理)详解new和delete+面试题笔试题(中)
从C语言到C++⑨(第三章_C&C++内存管理)详解new和delete+面试题笔试题
4 0
|
17小时前
|
存储 编译器 程序员
从C语言到C++④(第二章_类和对象_上篇)->类->封装->this指针(下)
从C语言到C++④(第二章_类和对象_上篇)->类->封装->this指针
4 0
|
1天前
|
存储 编译器 C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(下)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
7 0
|
1天前
|
C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(中)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
8 0
|
1天前
|
存储 数据库 C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(上)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
8 0
|
1天前
|
C语言
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror(下)
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror
5 0
|
1天前
|
安全 C语言
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror(中)
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror
10 0
|
1天前
|
C语言
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror(上)
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror
9 0
|
1天前
|
C语言
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)(中)
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)
11 0