E47.【C语言】零散的练习题(1)

目录

1.字符串数组和常量字符串

题目

解答

★常量字符串的特点★

代码存在的潜在的风险

2.strcat和strcpy的混合考察

题目

解答

知识回顾

分析

3.大小端问题

题目

解答

4.指针数组

题目

解答

5.sizeof和strlen

题目

解答

知识回顾

[void Func(char str_arg[2])的2的含义](#void Func(char str_arg[2])的2的含义)


1.字符串数组和常量字符串

题目

cpp 复制代码
char 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. 运行出错

解答

知识回顾

52.【C语言】 字符函数和字符串函数(strcat函数)

51.【C语言】字符函数和字符串函数(strcpy函数)

分析

问题出在:

1.strcat(p1, p2),p1指向的字符串没有足够的空间追加p2指向的字符串(这不是主要原因)

2.常量字符串不可修改,因此运行出错,选D

3.大小端问题

题目

有下面 C 代码片段:

cpp 复制代码
unsigned 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的对比:

20.5.【C语言】求长度(sizeof和strlen)的两种方式

E17.【C语言】练习:sizeof和strlen的辨析

str_arg数据类型为char*,32位下占4字节,而sizeof求类型所占的字节数,因此第一个打印4

strlen求有效字符串的长度,而str_arg指向的字符串为"Hello"加上隐藏的\0一共5个字符,因此第二个打印4

void Func(char str_arg[2])的2的含义

表示这个数组接受的长度是2,但不影响strlen的打印结果,原因:数组传参的时退化成指针,即数组作为函数参数传递时,其大小信息会被忽略

相关推荐
AI科技星8 分钟前
光速飞行器动力学方程的第一性原理推导、验证与范式革命
数据结构·人工智能·线性代数·算法·机器学习·概率论
橘颂TA10 分钟前
【剑斩OFFER】算法的暴力美学——leetCode 946 题:验证栈序列
c++·算法·leetcode·职场和发展·结构与算法
闻缺陷则喜何志丹12 分钟前
【状态机动态规划】3686. 稳定子序列的数量|1969
c++·算法·动态规划·力扣·状态机动态规划
寻星探路23 分钟前
【算法通关】双指针技巧深度解析:从基础到巅峰(Java 最优解)
java·开发语言·人工智能·python·算法·ai·指针
余瑜鱼鱼鱼24 分钟前
Java数据结构:从入门到精通(十)
数据结构
wen__xvn24 分钟前
力扣第 484 场周赛
算法·leetcode·职场和发展
好奇龙猫29 分钟前
【大学院-筆記試験練習:线性代数和数据结构(5)】
数据结构·线性代数
YuTaoShao36 分钟前
【LeetCode 每日一题】865. 具有所有最深节点的最小子树——(解法一)自顶向下
算法·leetcode·职场和发展
爱吃生蚝的于勒37 分钟前
【Linux】进程间通信之匿名管道
linux·运维·服务器·c语言·数据结构·c++·vim
寻星探路1 小时前
【算法专题】哈希表:从“两数之和”到“最长连续序列”的深度解析
java·数据结构·人工智能·python·算法·ai·散列表