结构化程序设计

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) 的返回值:

  1. f(4):

    • if (4) 为真,所以返回 f(3) + 4
  2. f(3):

    • if (3) 为真,所以返回 f(2) + 3
  3. f(2):

    • if (2) 为真,所以返回 f(1) + 2
  4. f(1):

    • if (1) 为真,所以返回 f(0) + 1
  5. 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);
这是不正确的。初始化字符数组时没有终止符\0puts(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,需要执行以下步骤:

  1. qnext 指向 pnext,即 q->next = p->next
  2. pnext 指向 q,即 p->next = q

这样,链表就变成:

head -> ... -> p -> q -> p->next -> ...

选项解析:

  • A. p->next = q->next; q->next = p;

    • 这是错误的。这会导致链表断裂,并且会形成一个环。
  • B. q->next = p->next; p = q;

    • 这是错误的。虽然 qnext 被正确设置,但 p 被赋值为 q,这并没有改变链表结构。
  • C. p->next = q->next; p->next = q;

    • 这是错误的。p->next = q->next 会将 pnext 改变,从而破坏链表结构。
  • 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

解释:

  1. 初始化数组和指针

    int a[]={10,9,8,7,6,5,4,3,2,1};
    int *p;
    p = a;
    

    这里定义了一个数组 a,并将指针 p 指向数组 a 的起始位置(即 a[0])。

  2. 解析 printf 语句

    printf("%d,%d", *p+9, *(p+9) );
    

    • *p 是指针 p 所指向的值,即 a[0] 的值 10
    • *p + 910 + 9,即 19
    • p + 9 是指向数组 a 第 9 个元素的指针(0 索引基准的第 10 个元素),即 a[9],其值为 1
    • *(p + 9)a[9] 的值,即 1
  3. 因此,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,并初始化了前四个元素:

  1. a[0]: name = "ZHAO", age = 14
  2. a[1]: name = "WANG", age = 15
  3. a[2]: name = "LIU", age = 16
  4. a[3]: name = "ZHANG", age = 17
  5. a[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=&xx 是两个不同的变量定义。正确的定义应该是 int x, *px=&x;
  • D. int x, px=x;

    • 这是不正确的。这里 px 被定义为一个 int 类型的变量,而不是指针类型。正确的形式应该是 int x, *px=&x;

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值