从 GATE 考试的角度来看,字符串是一个重要的主题。我们将讨论字符串的关键点以及基于此的不同类型的问题。
有两种方法可以将字符串存储为字符数组(char p[20])或指向字符串的指针(char* s = “字符串”),两者都可以作为数组访问。假设 p 为字符数组,s 为指向字符串 的指针,关键点如下:
- 运算符sizeof(p) 将给出分配给字符数组的内存。但是,sizeof(s) 将给出与 p 指向的字符串无关的指针大小。
- 每个字符串都附加了一个空字符(‘\0’),它描述了字符串。
- 可以使用 strlen()函数计算字符串的长度。但是,该函数的长度中不包含空字符“\0”。例如, strlen(s) 将返回 6。
- 字符串的单个字符可以打印为:
printf(“%c”, s[0]); printf(“%c”, p[1]);
- 完整的字符串可以打印为:
printf(“%s”, s); printf(“%s”, p);
- 由于 p 是字符数组,因此可以修改其各个元素 (p[i] = ‘c’)。但是,使用 s (指向字符串的指针),无法修改字符串 的各个元素。
- 由于 s 是一个指针,它也可以指向任何其他字符串(s =”string2”)。但是,使用 p 是不可能的。
让我们根据讨论的概念讨论一些问题:
Que – 1.下面的 C 程序片段打印了什么?
char c[] = "GEEK2018";
char *p =c;
printf("%c,%c", *p,*(p+p[3]-p[1]));
(一) G, 1
(B) G, K
(C) 极客2018
(D) 以上都不是
解决方案:如问题所示,p 指向字符数组 c[],可以表示为:
由于 p 是字符类型的指针,*p 将打印 ‘G’
使用指针算法,
*(p+p[3]-p[1]) = *(p+75-69)(使用 K 和 E 的 ascii 值)= *(p+6) = 1(我们知道 p 保存地址基本字符串手段的第0 poision字符串,让与2000年承担的字符串开始的地址,因此p + 6表示p的(我们在2000年增加6这意味着2006年,并在2006年的“1”存储,这就是为什么答案地址是 1)。
因此,输出将为 G, 1。
Que – 2.以下哪个 C 代码片段是无效的?
(A) char* p = “string1”; printf(“%c”, *++p);
(B) char q[] = “string1”; printf(“%c”, *++q);
(C) char* r = “string1”; printf(“%c”, r[1]);
(D) 以上都不是
解决方案:选项(A)是有效的,因为 p 是指向“string1”的字符’s’ 的指针。使用 ++p,p 将指向“string1”中的字符’t’。因此, *++p 将打印 ‘t’。
选项(B)无效,因为 q 是字符数组的基地址,++q(增加基地址)无效。
选项 (C) 是有效的,因为 r 是指向“string1”字符’s’ 的指针。所以,
r[1] = *(r+1) = ‘t’ and it will print ‘t’.
Que – 3.考虑以下 C 程序段:(GATE CS 2004)
char p[20];
char *s = "string";
int length = strlen(s);
int i;
for (i = 0; i < length; i++)
p[i] = s[length — i];
printf("%s",p);
程序的输出是:
(A) 点火
(B) 点火
(C)字符串
(D) 不打印输出
解决方案:在给定的代码中, p[20] 被声明为一个字符数组,而 s 是一个指向字符串的指针。长度将被初始化为 6。 在 for 循环(i = 0)的第一次迭代中,
p[i] = s[6-0] 并且 s[6] 是 ‘\0’
因此,p[0] 变为 ‘\0’。正如所讨论的, ‘\0’ 表示字符串。因此,不会打印任何内容,因为字符串的第一个字符是 ‘\0’。
Que – 4.下面的 C 程序片段打印了什么?
char c[] = "GATE2011";
char *p =c;
printf("%s", p + p[3] - p[1]) ;
(一) GATE2011
(B) E2011
(三) 2011
(四) 011
解决方案:如问题所示,p 指向字符数组 c[],可以表示为:
由于 p 是字符类型的指针,使用指针算法,
p + p[3] – p[1] = p + 69 – 65(使用 A 和 E 的 Ascii 值)= p + 4
现在,p + 4 将指向 2,将打印从 2 到 ‘\0’ 的字符串,即 2011。