天天看点

C语言:指针习题前言题目

目录

  • 前言
  • 题目
    • 题目1
    • 题目2
    • 题目3

前言

在学习完C语言的初阶以及进阶以后,我们需要一些习题来检验自己的学习成果,下面将以一些笔试题和面试题来分析。

在题目的分析中如有错误,欢迎指正。

题目

题目1

int main() {
	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函数输入地址,找到0为止
	printf("%d\n", strlen(arr));//随机值b
	printf("%d\n", strlen(arr + 0));//随机值b
	printf("%d\n", strlen(*arr));//错误
	printf("%d\n", strlen(arr[1]));//错误
	printf("%d\n", strlen(&arr));//随机值b
	printf("%d\n", strlen(&arr + 1));//随机值b-6
	printf("%d\n", strlen(&arr[0] + 1));//随机值b-1
	return 0;
}
           
sizeof是一个操作符,strlen是C语言库函数,接受的是一个地址

在前面我们知道数组名代表首元素地址,但是有例外,例如sizeof和数组直接使用时,这时候数组名代表整个数组。

经过我们分析可以知道

  1. arr直接使用代表整个数组,sizeof(arr)的值是6;
  2. arr+0是一个地址,所以sizeof(arr+0)的值是4或8,具体答案取决32或64平台
  3. *arr是首元素a的引用,所以sizeof(*arr)的值是1;
  4. arr[0]也是首元素a,与上面相同,它的值也是1;
  5. &arr是一个地址,所以它的值是4或者8;
  6. &arr+1是一个地址,所以它的值是4或者8;
  7. &arr[0]+1也是一个地址,所以它的地址是4或者8;

具体答案是不是我们分析的那样,用VS2019编译器进行验证

C语言:指针习题前言题目

接下来分析strlen函数

我们知道strlen接受字符串地址,然后往后找到/0结束

但是我们在题目中初始化时没有给’\0’,这样就会造成他会一直往后走找到结束标志’\0’。

  1. arr是首元素地址,但是我们不知道结束的0在哪,所以长度未知,设为len
  2. arr+0也是首元素地址,未知结束标志在哪,长度未知,并且和上一个长度相同,也是len
  3. *arr是什么?它是首元素a,数值97,不是一个地址,所以会报错
  4. arr[1]是元素b,不是一个地址,也会报错
  5. &arr是一个地址,是整个元素地址,但是和首元素地址相同,所以它的值也是len
  6. &arr+1是一个地址,但是它不是第二个元素的地址,而是跳过了整个数组的地址,指向f后面一个元素地址,跳过了6个元素,所以它的值len-6
  7. &arr[0]+1是一个地址,这个才是指向了第二个元素地址,值是len-1
C语言:指针习题前言题目

让我们通过VS2019编译器进行验证

C语言:指针习题前言题目

由于3,4两行代码会报错从而导致程序终止运行,我们将它屏蔽掉,最右边是运行结果,这与我们的分析是一致的。

题目2

int main() {
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//7
	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
	printf("%d\n", strlen(arr));//6
	printf("%d\n", strlen(arr + 0));//6
	//printf("%d\n", strlen(*arr));//错误
	//printf("%d\n", strlen(arr[1]));//错误
	printf("%d\n", strlen(&arr));//6
	printf("%d\n", strlen(&arr + 1));//随机
	printf("%d\n", strlen(&arr[0] + 1));//5
}

           

这题和上面题只是多了一个结束的0,在结果上略有不同。

C语言:指针习题前言题目

所以它包含7个元素,这和上面的多了一个’\0’

所以sizeof(arr)的值是7

strlen函数我们知道了结束的标志在哪里,所以可以轻松判断字符串长度

而&arr+1跳过了整个字符串,下一个’\0’是未知的,所以是随机值

题目3

int main() {
	char* p = "abcdef";
	printf("%d\n", sizeof(p));//4/8
	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
	printf("%d\n", sizeof(&p + 1));//4/8
	printf("%d\n", sizeof(&p[0] + 1));//4/8
	printf("%d\n", strlen(p));//6
	printf("%d\n", strlen(p + 1));//5
	//printf("%d\n", strlen(*p));
	//printf("%d\n", strlen(p[0]));
	printf("%d\n", strlen(&p));//随机值a
	printf("%d\n", strlen(&p + 1));//随机值b
	printf("%d\n", strlen(&p[0] + 1));//5
}
           
C语言:指针习题前言题目

我们需要知道的是,这是一个常量字符串,一个cha* 的指针不可能包含整个字符串,它指向的是首元素a。也就是说*p==a,p是首元素的地址。

我们知道sizeof(地址)的值是4或者8

p,p+1,&p,&p+1,&p[0]+1它们都是地址

*p和p[0]代表首元素a,所以所占空间是1

当首元素的地址传进strlen函数时,直到往后找到’\0’,由此我们可以判断strlen§==6,strlen(p+1)==5;

这里需要注意的是,我们这里&p和上面一个题的&arr是两个概念,&p是地址的地址,指针p的地址,与原来字符串数组关系不大了。

继续阅读