目录
[void Func(char str_arg[2])的2的含义](#void Func(char str_arg[2])的2的含义)
1.字符串数组和常量字符串
题目
cppchar acX[] = "abc"; char acY[] = { 'a','b','c' }; char* szX = "abc"; char* szY = "abc";
下面叙述错误的是( )
A.acX与acY的内容可以修改
B.szX与szY指向同一个地址
C.acX占用的内存空间比acY占用的大
D.szX的内容修改后,szY的内容也会被更改
解答
char acX[] = "abc"等价为'a','b','c','\0'(字符串结尾隐藏\0) ,而char acY[] = { 'a','b','c' };由单个字符排列,结尾没有\0,因此acX占用的内存空间比acY占用的大,C正确,不选,且acX和acY没有用const修饰,因此A正确,不选
szX和szY指向的都是同一个常量字符串"abc"(直接由""引用的字符串的集合)
★常量字符串的特点★
1.具有常量属性,不可以修改
2.常量字符串只存储一份
例如以下代码在x86下测试:
cpp
#include <stdio.h>
int main()
{
char* szX = "abc";
char* szY = "abc";
printf("szX的地址:%p\nszY的地址:%p", szX, szY);
return 0;
}
运行结果:打印的结果是一样的

因此B正确,D错误,因此选D
代码存在的潜在的风险
常量字符串不能修改,但按这样定义char* szX = "abc"会有潜在的风险
例如在下面多加一行*szX='m',VS能正常编译,但运行时会报错

常量字符串不可以修改 ,因此在定义指针时,不能修改指针所指向的内容,需要用const修饰
修改后:
cpp
const char* szX = "abc";
const char* szY = "abc";
其实*szX='m'在较为严格的编译器上是不能通过编译的,例如Linux的gcc编译器:

2.strcat和strcpy的混合考察
题目
下面C程序的输出结果是( )
cpp#include <stdio.h> #include <string.h> int main() { char* p1 = "123", * p2 = "ABC", str[50] = "xyz"; strcpy(str + 2, strcat(p1, p2)); printf("%s\n", str); }
A. xyz123ABC
B. z123ABC
C. xy123ABC
D. 运行出错
解答
知识回顾
分析
问题出在:
1.strcat(p1, p2),p1指向的字符串没有足够的空间追加p2指向的字符串(这不是主要原因)
2.常量字符串不可修改,因此运行出错,选D
3.大小端问题
题目
有下面 C 代码片段:
cppunsigned int a = 0x1234; unsigned char b = *(unsigned char *)&a;
则在 32 位大端模式机器上变量 b 等于( )
A. 0x00
B. 0x12
C. 0x34
D. 0x1234
解答
有关大小端的知识点参见61.【C语言】数据在内存中的存储文章
0x1234以int类型大端形式存储: 00 00 12 34 --> unsigned int*指针强制类型转换为unsigned char*再解引用即取一个字节即00,选A
4.指针数组
题目
下面 C 代码的运行结果是( )
cpp#include <stdio.h> void f(char** q) { *q += 2; } int main() { char* a[] = { "123", "abc", "456" }, ** p; p = a; f(p); printf("%s", *p); return 0; }
A. 123
B. abc
C. 456
D. 3
解答
读代码发现,a为指针数组,可以在VS的内存窗口上输入a,显示:

画图为: 调用函数f(p)后,形参q也指向a[0]

一开始*q==0x00B97BDC,之后*q+=2后,*q==0x00B97BDE,修改了一级指针

则答案为D
5.sizeof和strlen
题目
32位机器上,下面程序的输出结果为( )
cpp#include <stdio.h> #include <string.h> void Func(char str_arg[2]) { int m = sizeof(str_arg); int n = strlen(str_arg); printf("%d\n", m); printf("%d\n", n); } int main() { char str[] = "Hello"; Func(str); return 0; }
A. 5 5
B. 5 4
C. 4 5
D. 4 4
解答
知识回顾
sizoef和strlen的对比:
str_arg数据类型为char*,32位下占4字节,而sizeof求类型所占的字节数,因此第一个打印4
strlen求有效字符串的长度,而str_arg指向的字符串为"Hello"加上隐藏的\0一共5个字符,因此第二个打印4
void Func(char str_arg[2])的2的含义
表示这个数组接受的长度是2,但不影响strlen的打印结果,原因:数组传参的时退化成指针,即数组作为函数参数传递时,其大小信息会被忽略