测试题:
0. 你有听说过二级指针和三级指针吗?它们是什么?
答:二级指针:指向指针的指针 三级指针:指向指针的指针的指针
答案:二级指针其实就是指向指针的指针,而三级指针当然就是指向指针的指针的指针啦。
1. 请按下图写出每个变量的定义过程。
3. 如果有 int a[10];,请问 &a 和 &a[0] 表达式的类型有何不同?
答:&a代表整个数组的地址, &a[0]代表数组第一个元素的地址,结果都是一样的
答案:a 是一个数组,在 &a 这个表达式中,数组类型做左值,&a 表示取整个数组的首地址,类型是 int (*)[10];&a[0] 则表示数组 a 的第一个元素的首地址,虽然两个地址的数值相同,但后者的类型是 int *。
4. 假如定义了一个指针数组 pArray 如下,请定义一个指向它的数组指针 p,让下边程序可以顺利执行。
程序实现如下:
答:char *(*p)[4] = pArray (也可以,但会告警)
#include <stdio.h>
int main()
{
char *pArray[4] = {
"Hello",
"How are you?",
"Fine,thank you.And you?",
"I'm fine too"
};
char *(*p)[4] = pArray;
int i;
for(i=0;i<4;i++)
{
printf("%s\n",(*p)[i]);
}
return 0;
}
答案:char *(*p)[4] = &pArray;
5. 定义以下变量:
char a[4][3][2] = {
{
{'a', 'b'}, {'c', 'd'}, {'e', 'f'}
},
{
{'g', 'h'}, {'i', 'j'}, {'k', 'l'}
},
{
{'m', 'n'}, {'o', 'p'}, {'q', 'r'}
},
{
{'s', 't'}, {'u', 'v'}, {'w', 'x'}
}
};
char (*pa)[2] = &a[1][0];
char (*ppa)[3][2] = &a[1];
想要通过指针 pa 和 ppa 访问数组 a 中的 'x' 元素,请问表达式应该怎么写?
答:*(*(pa+8) +1) *(*(*(ppa+2)+3)+1)(错误)
答案:*(*(pa+8)+1) 和 *(*(*(ppa+2)+2)+1))。 &*#cI9;
解析:
如上图所示,*pa 被定义为一个一维数组,其跨度为 2 个字节,所以 *(pa + 8) 指向的是 {'w', 'x'} 这个数组,所以 *(*(pa + 8) + 1) 取出 'x' 元素;*ppa 被定义为一个二维数组,其跨度为 6 个字节,所以 *(ppa + 2) 指向的是 {{'s', 't'}, {'u', 'v'}, {'w', 'x'}} 这个二维数组,所以 *(*(*(ppa + 2) + 2) + 1) 取出 'x' 元素。
动动手答案:
要求:
- 返回的二维数组必须尽可能地节省空间(利用C语言的变长数组来实现)
- 不能使用现成的函数帮忙(你只能 #include <stdio.h>)
程序实现如下:
分割后的结果存放在 result 二维数组中,这个二维数组的尺寸是根据用户输入的单词长度而定的(再次提醒:不能使用 malloc 等没学过的知识噢~)
不论是一个空格还是多个空格,你的程序都能够正确识别出单词来:
答:没想出来代码构造(错误)
答案:
#include <stdio.h>
int main()
{
char str[1024];
char *p = str; // 用于间接寻址
char *pos[1024] = {0}; // 记录每个单词的地址
int len = 0;
int cChar = 0, cWord = 0; // cChar 统计字符数, cWord 统计单词数
int max = 0, i = 0, j;
printf("请输入一个英文句子:");
// 接收输入,顺带统计用户实际输入了多少个字符
while ((str[len++] = getchar()) != '\n' && len + 1 < 1024)
;
str[len-1] = '\0'; // str[len]存放的是'\n',将其替换为'\0'
if (*p != ' ')
{
pos[i++] = p; // 记录第一个单词的地址
cWord++;
}
while (len--)
{
if (*p++ == ' ')
{
// 判断最大字符数
max = cChar > max ? cChar : max;
cChar = 0;
// 到底了,退出循环
if (*p == '\0')
{
break;
}
// 单词数加一
if (*p != ' ')
{
pos[i++] = p;
cWord++;
}
}
else // 没有else会把空格统计进去
{
cChar++;
}
}
max = --cChar > max ? cChar : max; // 最后会算多一个'\0',所以减去
// 申请可变长数组,max+1,否则'\0'放不下
char result[cWord][max+1];
// 将分割好的单词放进二维数组里
for (i = 0; i < cWord; i++)
{
for (j = 0; *(pos[i]+j) != ' ' && *(pos[i]+j) != '\0'; j++)
{
result[i][j] = *(pos[i]+j);
}
result[i][j] = '\0';
}
// 打印结果
printf("分割结果已存放到result[%d][%d]的二维数组中...\n", cWord, max+1);
printf("现在依次打印每个单词:\n");
for (i = 0; i < cWord; i++)
{
printf("%s\n", result[i]);
}
return 0;
}
1. 修改代码,使得程序允许用户指定分隔符。
程序实现如下:
答:没想出来代码构造(错误)
答案:
#include <stdio.h>
int main()
{
char str[1024];
char *p = str; // 用于间接寻址
char *pos[1024] = {0}; // 记录每个单词的地址
int len = 0;
int cChar = 0, cWord = 0; // cChar 统计字符数, cWord 统计单词数
int max = 0, i = 0, j;
char delim = ' ';
printf("请输入一个英文句子:");
// 接收输入,顺带统计用户实际输入了多少个字符
while ((str[len++] = getchar()) != '\n' && len + 1 < 1024)
;
str[len-1] = '\0'; // str[len]存放的是'\n',将其替换为'\0'
printf("请输入分割符:");
scanf("%c", &delim);
if (*p != delim)
{
pos[i++] = p; // 记录第一个单词的地址
cWord++;
}
while (len--)
{
if (*p++ == delim)
{
// 判断最大字符数
max = cChar > max ? cChar : max;
cChar = 0;
// 到底了,退出循环
if (*p == '\0')
{
break;
}
// 单词数加一
if (*p != delim)
{
pos[i++] = p;
cWord++;
}
}
else // 没有else会把空格统计进去
{
cChar++;
}
}
max = --cChar > max ? cChar : max; // 最后会算多一个'\0',所以减去
// 申请可变长数组,max+1,否则'\0'放不下
char result[cWord][max+1];
// 将分割好的单词放进二维数组里
for (i = 0; i < cWord; i++)
{
for (j = 0; *(pos[i]+j) != delim && *(pos[i]+j) != '\0'; j++)
{
result[i][j] = *(pos[i]+j);
}
result[i][j] = '\0';
}
// 打印结果
printf("分割结果已存放到result[%d][%d]的二维数组中...\n", cWord, max+1);
printf("现在依次打印每个单词:\n");
for (i = 0; i < cWord; i++)
{
printf("%s\n", result[i]);
}
return 0;
}
*BFh.w$~k`^3O)SG%&;o6>[-s
^!dyn$MX}SmW-.lCONL%~=E)z<