C语言中函数返回值的类型是由( )决定的。
A.return
语句中的表达式类型
B.调用该函数的主调函数的类型
C.调用函数时临时决定
D.定义函数时所指定的函数类型
D. 定义函数时所指定的函数类型
解释: 在C语言中,函数返回值的类型在函数定义时指定。例如,定义一个函数时,返回值类型会在函数头部声明:
int foo() {
return 0;
}
在这个例子中,函数foo
的返回值类型是int
,这个类型在函数定义时已经指定。无论return
语句中的表达式类型是什么。
以下说法正确的是:
A. 一个C语言源文件(.c文件)必须包含main函数
B. 一个C语言源文件(.c文件)可以包含两个以上main函数
C. C语言头文件(.h文件)和源文件(.c文件)都可以进行编译
D. 在一个可以正确执行的C语言程序中,一个C语言函数的声明(原型)可以出现任意多次么,函数的返回值类型都是由定义时指定的类型决定的。
D. 在一个可以正确执行的C语言程序中,一个C语言函数的声明(原型)可以出现任意多次
解释:
A. 错误。一个C语言源文件不一定要包含main函数,只有编译成可执行程序时才需要main函数作为程序的入口点。一个项目可以由多个源文件组成,只有其中一个文件需要包含main函数。
B. 错误。一个C语言程序只能有一个main函数作为入口点,一个源文件中不可以包含多个main函数,否则会导致链接错误。
C. 错误。C语言头文件(.h文件)不能单独编译,必须包含在源文件(.c文件)中进行编译。只有源文件可以单独编译。
D. 正确。函数声明(原型)可以在多个地方出现,只要它们一致,不会影响程序的正确执行。这在大型项目中是很常见的做法,用于不同的文件之间共享函数原型。
对于以下递归函数f,调用f(4),其返回值为() 。
int f(int n)
{ if (n) return f(n - 1) + n;
else return n;
}
A.10
B.4
C.0
D.以上均不是
我们可以通过展开递归调用来计算 f(4)
的返回值:
-
f(4)
:if (4)
为真,所以返回f(3) + 4
-
f(3)
:if (3)
为真,所以返回f(2) + 3
-
f(2)
:if (2)
为真,所以返回f(1) + 2
-
f(1)
:if (1)
为真,所以返回f(0) + 1
-
f(0)
:if (0)
为假,所以返回0
将这些值代入:
f(0) = 0
f(1) = f(0) + 1 = 0 + 1 = 1
f(2) = f(1) + 2 = 1 + 2 = 3
f(3) = f(2) + 3 = 3 + 3 = 6
f(4) = f(3) + 4 = 6 + 4 = 10
因此,f(4)
的返回值为 10
。
不正确的赋值或赋初值的方式是____。 A. char str[]="string";
B. char str[7]={'s', 't', 'r', 'i', 'n', 'g'};
C. char str[10];str="string";
D. char str[7]={'s', 't', 'r', 'i', 'n', 'g', '\0’};
不正确的赋值或赋初值的方式是:
C. char str[10];str="string";
解释:
A. char str[]="string";
这是正确的。使用字符串常量初始化字符数组,编译器会自动计算数组的长度并添加终止符\0
。
B. char str[7]={'s', 't', 'r', 'i', 'n', 'g'};
这是正确的。这里初始化字符数组的每个元素,但没有终止符\0
,这在某些情况下可能会引起问题,但语法上是正确的。
C. char str[10];str="string";
这是不正确的。数组初始化不能使用赋值语句,必须在定义时进行初始化。正确的初始化方式
char str[10] = "string";
char str[10] = {'s', 't', 'r', 'i', 'n', 'g', '\0'};
因为字符数组不能通过赋值运算符直接赋值一个字符串常量。
D. char str[7]={'s', 't', 'r', 'i', 'n', 'g', '\0’};
这是正确的。初始化字符数组的每个元素,并且包括了字符串终止符\0
。
假设scanf
语句执行时输入ABCDE
<回车>,能使puts(s)
语句正确输出ABCDE
字符串的程序段是__。
A.char s[5]={"ABCDE"}; puts(s);
B.char s[5]={'A', 'B', 'C', 'D', 'E'}; puts(s);
C.char *s; scanf("%s", s); puts(s);
D.char *s; s="ABCDE"; puts(s);
A. char s[5]={"ABCDE"}; puts(s);
这是不正确的。s
数组大小是5,不能正确包含字符串终止符\0
,而且不会通过scanf
读入数据。
B. char s[5]={'A', 'B', 'C', 'D', 'E'}; puts(s);
这是不正确的。初始化字符数组时没有终止符\0
,puts(s)
输出可能会导致未定义行为。
C. char* s; scanf("%s", s); puts(s);
这是不正确的。char *s
只是一个指针,没有分配内存空间。scanf
会导致未定义行为。
对于以下结构定义,++p->str
中的++
加在____。
struct {
int len;
char *str;
} *p;
A.指针str上
B.指针p上
C.str指的内容上
D.以上均不是
解释:
p
是一个指向结构体的指针。p->str
表示结构体指针p
所指向的结构体中的str
成员,这是一个字符指针。++p->str
会先解引用p
,获取到结构体,然后访问结构体的str
成员,最后对str
指向的内容进行递增操作。
因此,++p->str
中的++
操作符是加在str
指向的内容上的。
有如下定义:
struct Student{
char name[10];
int age;
char gender;
}std[3], *p=std;
则以下各输入语句中错误的是:
A.scanf("%d",&(*p).age);
B.scanf("%c",&std[0].gender);
C.scanf("%c",&(p->gender));
D.scanf("%s",&std.name);
%d
:读取或输出一个十进制整数
%c
:读取或输出一个字符。
%s
:读取或输出一个字符串(即字符数组),字符串以空字符 \0
结尾
-
A.
scanf("%d", &(*p).age);
- 这是正确的用法。
(*p).age
等价于p->age
,它表示结构体指针p
所指向的结构体的age
成员的地址,使用%d
格式说明符读取一个整数,并将其存储在age
中。
- 这是正确的用法。
-
B.
scanf("%c", &std[0].gender);
- 这是正确的用法。
std[0].gender
表示第一个Student
结构体的gender
成员的地址,使用%c
格式说明符读取一个字符,并将其存储在gender
中。
- 这是正确的用法。
-
C.
scanf("%c", &(p->gender));
- 这是正确的用法。
p->gender
等价于(*p).gender
,它表示结构体指针p
所指向的结构体的gender
成员的地址,使用%c
格式说明符读取一个字符,并将其存储在gender
中。
- 这是正确的用法。
-
D.
scanf("%s", &std.name);
- 这是错误的用法。
std
是一个结构体数组,不能直接使用&std.name
。正确的用法是使用特定结构体实例的name
成员。 - 正确的用法应该是
scanf("%s", std[0].name);
,它表示读取一个字符串,并将其存储在第一个Student
结构体的name
成员中。
- 这是错误的用法。
在一个单链表head中,若要在指针p所指结点后插入一个q指针所指结点,则执行()。
A.p->next=q->next; q->next=p;
B.q->next=p->next; p=q;
C.p->next=q->next; p->next=q;
D.q->next=p->next; p->next=q;
在一个单链表中,若要在指针 p
所指结点后插入一个 q
指针所指结点,则正确的操作顺序是:
D. q->next = p->next; p->next = q;
解释:
假设单链表如下:
head -> ... -> p -> p->next -> ...
要在结点 p
后插入结点 q
,需要执行以下步骤:
- 将
q
的next
指向p
的next
,即q->next = p->next
。 - 将
p
的next
指向q
,即p->next = q
。
这样,链表就变成:
head -> ... -> p -> q -> p->next -> ...
选项解析:
-
A. p->next = q->next; q->next = p;
- 这是错误的。这会导致链表断裂,并且会形成一个环。
-
B. q->next = p->next; p = q;
- 这是错误的。虽然
q
的next
被正确设置,但p
被赋值为q
,这并没有改变链表结构。
- 这是错误的。虽然
-
C. p->next = q->next; p->next = q;
- 这是错误的。
p->next = q->next
会将p
的next
改变,从而破坏链表结构。
- 这是错误的。
-
D. q->next = p->next; p->next = q;
- 这是正确的。这会将
q
插入到p
之后,保持链表结构完整。
- 这是正确的。这会将
因此,正确的操作是 D. q->next = p->next; p->next = q;
有以下程序段:
int a[]={10,9,8,7,6,5,4,3,2,1}, *p;
p=a;
printf("%d,%d", *p+9, *(p+9) );
输出结果为( )。
A.1,1
B.19,10
C.19,1
D.19,19
解释:
-
初始化数组和指针:
int a[]={10,9,8,7,6,5,4,3,2,1}; int *p; p = a;
这里定义了一个数组
a
,并将指针p
指向数组a
的起始位置(即a[0]
)。 -
解析
printf
语句:printf("%d,%d", *p+9, *(p+9) );
-
*p
是指针p
所指向的值,即a[0]
的值10
。*p + 9
是10 + 9
,即19
。p + 9
是指向数组a
第 9 个元素的指针(0 索引基准的第 10 个元素),即a[9]
,其值为1
。*(p + 9)
是a[9]
的值,即1
。
-
因此,
printf("%d,%d", *p+9, *(p+9) );
输出的结果是:C. 19,1
定义下列结构体数组:
struct stu
{ char name[10];
int age;
}a[5]={"ZHAO",14, "WANG",15, "LIU",16, "ZHANG",17};
执行语句printf("%d, %s",a[2].age, a[1].name)的输出结果为( )。
A.15, ZHAO
B.16, WANG
C.17, LIU
D.17, ZHAO
这个定义创建了一个 struct stu
类型的数组 a
,并初始化了前四个元素:
a[0]
:name
= "ZHAO",age
= 14a[1]
:name
= "WANG",age
= 15a[2]
:name
= "LIU",age
= 16a[3]
:name
= "ZHANG",age
= 17a[4]
: 未初始化
这条语句会输出:
a[2].age
: 这是a[2]
结构体的age
成员,对应的值是16
。a[1].name
: 这是a[1]
结构体的name
成员,对应的值是"WANG"
。
因此,执行语句 printf("%d, %s", a[2].age, a[1].name);
的输出结果是:
16, WANG
下列语句定义px为指向int类型变量x的指针,正确的是( )
A.int x,*px=x;
B.int x,*px=&x;
C.int *px=&x,x;
D.int x, px=x;
要定义 px
为指向 int
类型变量 x
的指针,正确的语句是:
*B. int x,px=&x;
解释:
-
*A. int x,px=x;
- 这是不正确的。这里
*px
被初始化为x
的值,而不是x
的地址。正确的形式应该是将px
初始化为x
的地址。
- 这是不正确的。这里
-
*B. int x,px=&x;
- 这是正确的。这里
x
被定义为一个int
类型的变量,然后px
被定义为一个指向int
类型的指针,并且被初始化为x
的地址(&x
)。
- 这是正确的。这里
-
*C. int px=&x,x;
- 这是语法错误。在这种情况下,编译器会认为
int *px=&x
和x
是两个不同的变量定义。正确的定义应该是int x, *px=&x;
。
- 这是语法错误。在这种情况下,编译器会认为
-
D. int x, px=x;
- 这是不正确的。这里
px
被定义为一个int
类型的变量,而不是指针类型。正确的形式应该是int x, *px=&x;
。
- 这是不正确的。这里