注明:本笔记的题目部分来源于B站的 UP主:嵌入式技术公开课,观看地址为:
C语言笔试题,C++笔试题,嵌入式笔试题,面试题,难点疑点解析(持续更新)_哔哩哔哩_bilibili
(笔记是理解题目后自行编写的,希望对读者有帮助~~~~,当然,推荐各位去观看b站的视频,up主讲得很好,我只是在这里记录我对题目的理解,若有不对的地方,请多见谅~~~)
1、简单分析下这个函数并指出这个函数的功能。
void call_each(void (**a)(void),int size)
{
while(--size > 0){
void(*p)(void)= *a++;
if (p)
(*p)();
}
}
解析:
(1) **a == *a[] --> a是数组,数组中每个元素的类型是void(*)(void),即 a是数组,是函数指针数组。为什么?我们可以类比main函数的参数写法,如下:
int main(int argc,char *argv[])
int main(int argc,char **argv)argv是一个数组,数组的每个元素为char * 类型。
(2) void(*p)(void)= *a++; a++,a先用后加,即:*a++ --> *a.
(3) (*p)() : 通过函数指针p来调用指向的函数。所以,总的来说就是,该函数传入的参数是 函数指针数组 和 数组的长度,函数的功能就是用while循环调用数组的每一个函数。
2、一个易错的知识点(对我而言,对于各位大佬来说可能觉得我有点傻.........)
在使用strcpy函数拷贝字符串的时候,我以前通常会:
const char *str="hello world";
char *dest=NULL; 或者 char *dest;
strcpy(dest,str);
但是这样写的话,运行起来会有很大的问题,首先 strcpy 函数的参入的两个参数都是 char *类型,这毋庸置疑。但问题出现在哪呢?问题出现在 dest 指针指向的内容有问题。首先,我们得理解strcpy 函数底层的逻辑是如何实现的。如下:(只是简单的实现,并不完善)
void myStrCpy(char *targetStr, const char *sourceStr)
{
while (*sourceStr != '\0')
{
*targetStr++ = *sourceStr++;
}
}
其实就是通过指针的偏移来实现拷贝字符串。无论是 char *dest=NULL; 或者是 char *dest;dest指针指向的内容是不能修改(或者是未知的),用指针偏移其拷贝字符串时肯定会有问题的。那怎么修改呢?
其实很简单,有两种方法:
1、把 char *dest 改为char dest[100]; 这样其实编译器就已经为dest数组分配好了合法空间了,在传参的时候,dest数组退化为dest指针类型(是指针,不是数组,数组名是不能够进行算术运算的)。
2、在声明 char *dest 的时候用 malloc函数为其分配空间,即:
char *dest=(char *)malloc(strlen(str+1));
(为什么要 +1?因为 strlen 函数遇到 '\0' 停止,到不包含 '\0',拷贝字符串要包含 '\0',故要 +1 ,或者用 sizeof 也行,sizeof 不用+1)
3、以下代码printf 输出是什么?
void main (void)
{
int a[]={4,5,6,7,8};
int *p = a;
*p++;
printf(" %d %d \n" , *p,*(++p));
}
A.6 6
B.5 6
C.4 5
D.4 6
答案是:A
为什么是 A,不应该是 B 吗?哈哈哈,对,我一开始也是中招了。这道题我们得理解到,printf函数的执行循序是从右往左的,也就是先执行 *(++p) ,然后 再到 *p,那结果·自然是 A 了。为了巩固 printf 函数的知识点,下面一题也是有关 printf 函数的。
4、下面程序输出的结果是?
int main()
{
int i = 43;
printf("%d\n", printf("%d\n", printf("%d\n",i)));
return 0;
}
A、1234 B、4213 C、4321 D、2143
解析:
答案是 C ,我们上面说过了,printf函数的执行循序是从右往左的,然后这里再加一个知识点就是, printf 函数的返回值是输出字符的个数。结合这两个知识点,不难得出,答案是 C
5、下面程序会输出啥?
#include <stdio. h>
#include <stdlib. h>
void main()
{
int b[12]={1,2,3,4,5,6,7,8,9,10,11,12};
int(*p)[4];
p= (int(*)[4])b;
printf("%d\n", **(++p));
}
解析:
答案是 5 ,p= (int(*)[4])b; 这里是做了强制类型转换,将一维数组转为了二维数组(还能这样?我也懵逼,记录一下在这里吧!)然后 二维数组的p指向的是首行地址(第0行),++p 就是 下一行的地址,**(++p) 就是第一行的首元素。
6、以下代码结果是?
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;
}
A:00000000,0
B:FFFFFFFC,-4
C:FFFFFFF0,-16
D:以上没有正确答案
解析:
答案是 B 。首先,我们的理解 p = a; 到底做了什么?p是一个二维数组指针,这毋庸置疑。int(*p)[4] 中括号的 4,表示的是每行有4个元素。也就是说把 二维数组 a 的每行5个元素转换为 每行 4个元素,也就是说 p 指向的二维数组现在有5行,每行 4个元素。那 &p[4][2]是取出第19个元素的值,&a[4][2] 取出第23个元素的值,二者相差了 4个元素的距离。地址相减,是元素的距离之差。为什么?请看下面的博主的介绍吧,我这里就不多说了。而 -4 用 %p 打印出来又是什么呢?与 %X又有什么不同呢?
(地址相减)
C语言中,为什么指针表达式的值+1.对应的地址值却+4?/为什么两个数组元素的地址相减之差不为地址之差?_指针地址加4-CSDN博客
(%p 打印与%X打印有什么不同)