国庆练习(Day24)

作业一

数组练习

  1. 选择题

1.1、若有定义语句:int a[3][6]; ,按在内存中的存放顺序,a 数组的第10个元素是

a[0][4]                   B) a[1][3]                     C)a[0][3]                D)a[1][4]

解析:

从 a[0][0] 开始,第一行有 6 个元素,分别是 a[0][0] 到 a[0][5],即第 1 到第 6 个元素。

接着从 a[1][0] 开始,第二行前 4 个元素是 a[1][0] 到 a[1][3],即第 7 到第 10 个元素。

所以,第 10 个元素是 a[1][3]

解答:

B

1.2、有数组 int   a[5] = {10,20,30,40,50},  以下表达式编译错误是____________。

A)   a ++ ;

B)   a[5] =  20  ;

C)    a + 20  ;

D)   (a-3,   a[3]) ;

解析:

A) a++ ;

错误:a++ 是不合法的。

原因:在 C 语言中,数组名 a 是一个指向数组第一个元素的指针常量,它的值不可改变。也就是说,数组名 a 不能被自增,因为它是一个 常量指针,指向数组首地址,不能通过 ++ 操作改变。

B) a[5] = 20 ;

错误:虽然语法上没有问题,但会导致 数组越界 错误。

原因:a[5] 实际上是访问数组的第 6 个元素,而 a[5] 数组只有 5 个元素,索引范围是 a[0] 到 a[4]。因此,访问 a[5] 会导致 越界访问,尽管某些编译器可能不会报错,但这是一个逻辑错误。

C) a + 20 ;

正确:这个表达式不会编译错误。

原因:a + 20 是一个合法的指针运算。它将指针 a 偏移 20 个元素的位置,虽然这样做的结果可能是非法的地址访问,但仅仅是表达式本身不会导致编译错误。

D) (a-3, a[3]) ;

正确:这个表达式不会编译错误。

原因:这是一个逗号表达式,先计算 a-3(虽然结果无实际意义),然后计算 a[3],最终返回 a[3] 的值。语法上没有问题。

解答:

A

1.3、以下错误的定义语句是 _______   

A)int   x[][3]  =  {{0},{1},{1,2,3}};

B)int   x[4][3]  =  {{1,2,3},{1,2,3},{1,2,3},{1,2,3}};

C)int                  x[4][]  =   {{1,2,3},{1,2,3},{1,2,3},{1,2,3}};

D)int                 x[][3]  =   {1,2,3,4};

解析:

A) int x[][3] = {{0}, {1}, {1, 2, 3}};

正确:这是合法的定义。

原因:二维数组在定义时,必须指定列的大小(本例中的 [3])。行数可以省略,编译器会根据初始化的内容推断行数。每行的元素少于 3 时,未指定的元素会自动填充为 0。因此,这个定义是合法的。

B) int x[4][3] = {{1,2,3},{1,2,3},{1,2,3},{1,2,3}};

正确:这是合法的定义。

原因:明确定义了 4 行 3 列的二维数组,并且每行都初始化了 3 个元素,符合数组初始化规则。

C) int x[4][] = {{1,2,3},{1,2,3},{1,2,3},{1,2,3}};

错误:这是非法的定义。

原因:在声明二维数组时,列的大小必须明确指定,但这个语句没有为列指定大小(即 [] 是空的)。编译器无法推断每行有多少个元素,因此会报错。

D) int x[][3] = {1, 2, 3, 4};

正确:这是合法的定义。

原因:这是二维数组的另一种初始化方式。虽然看起来像是一维数组的初始化,但编译器会将 1, 2, 3, 4 填充到 [3] 列的二维数组中。结果是 x[0][0] = 1, x[0][1] = 2, x[0][2] = 3, x[1][0] = 4,其余的未初始化元素将被自动填充为 0。因此,这个定义也是合法的。

解答:

C

1.4、int i,x[3][3]={1,2,3,4,5,6,7,8,9};则下面语句

      for(i=0;i<3;i++)

      printf(″%d, ″,x[i][2-i]);

的输出结果是               

   A)1, 4, 7     B)1, 5, 9    C)3, 6, 9    D)3, 5, 7

解析:

这里 x[i][2-i] 表示:

当 i = 0 时,x[0][2-0] = x[0][2] = 3

当 i = 1 时,x[1][2-1] = x[1][1] = 5

当 i = 2 时,x[2][2-2] = x[2][0] = 7

解答:

D

1.5、表达式“sizeof(int [1][2])/sizeof(int)”的值为_____

A)  2       B)  3      C)  4      D)  5

解析:

sizeof(int [1][2]):

这个数组包含 1 行 2 列,总共有 1 × 2 = 2 个 int 元素。

每个 int 占 4 字节,因此整个数组的大小为 2 × 4 = 8 字节。

sizeof(int):

这是单个 int 类型的大小,在大多数系统上为 4 字节。

解答:

A

1.6有以下程序

#include main()

{ char s[]="012xy\07s34f4w2";  

int i,n=0;

for(i=0;s[i]!=0;i++)

if(s[i]>='0'&&s[i]<='9')

 n++;

printf("%d\n",n);

}

程序运行后的输出结果是____________

A)0       B)3      C)7         D)8

解析:

字符数组 s[] 的内容为 "012xy\07s34f4w2":

"012xy\07s34f4w2" 是一个字符串常量。

\07 是一个八进制转义字符,对应的值是 7。

这个字符串的实际内容是:"012xy\x07s34f4w2",它的长度是 14 个字符(包括 \07)。

但在这个程序中,八进制字符不会影响字符串的解析,它仅仅是作为一个不可见的字符。

for 循环 遍历整个字符串,直到遇到空字符 '\0' 为止。

在 if (s[i] >= '0' && s[i] <= '9') 中,检查当前字符是否为数字字符 '0' 到 '9'。如果是数字字符,则计数器 n 增加。

字符串 "012xy\07s34f4w2" 中的数字字符为:

'0', '1', '2', '3', '4', '4', '2'

一共 7 个数字字符。

解答:

C

1.7、有以下程序

#include   <stdio.h>

 main(   )

{ char s[ ]=”wstuv”; printf(“%c\n”,*s+2); 

}

程序运行后的输出结果是

A)t       B)  tuv      C)y      D)出错

解析:

s 是一个字符数组,数组名 s 是指向第一个元素的指针。

*s 解引用 s,表示数组的第一个元素 s[0],即字符 'w'。

表达式 *s + 2:

*s 取的是 s[0],即字符 'w'。

'w' 在 ASCII 码中的值是 119。

*s + 2 相当于 119 + 2 = 121,ASCII 码值 121 对应的字符是 'y'。

printf("%c\n", *s + 2); 输出的就是字符 'y'。

解答:

1.8  数组  int  a[5] = {10, 20, 30, 40,50}, 有以下语句,其输出_______

       printf(“%d\n”, *(&a +1)    );

   A)  20    B)  30    C)  随机值   D)编译报错

解析:

&a 的含义:

&a 是 数组 a 的地址,它的类型是 int (*)[5],即指向一个大小为 5 的整型数组的指针。

注意,这与 a 的地址(指向数组第一个元素 a[0] 的地址)是不同的。a 作为数组名时相当于 &a[0],是一个指向第一个元素的指针,而 &a 是整个数组的地址。

&a + 1 的含义:

&a + 1:这个表达式实际上是将 &a (数组 a 的地址)偏移一个数组的大小。因为 &a 是一个指向整个数组的指针,偏移 1 意味着它指向了数组 a 之后的地址。

也就是说,&a + 1 实际上指向的是数组 a[5] 后面的内存位置。

*( &a + 1 ) 的含义:

*( &a + 1 ) 试图 解引用 偏移后的地址。由于 &a + 1 指向数组 a 之外的内存,这意味着该表达式取出的值是数组 a 之后的内存中的内容。

这里访问的是超出数组范围的内存空间,会导致未定义行为。因此,输出的值是 随机的,也就是不可预测的。

解答:

C

1.9  有以下程序

    # include <stdio.h>

int  main()

{ int   s[12]={1,2,3,4,4,3,2,1,1,1,2,3},  c[5]={0,0,0,0,0},  i  ;

for(i=0;i<12;i++)          c[s[i]]++  ;

for(i=1;i<5;i++) printf(“%d,”,c[i]);  printf(“\n”);

}

A) 4 ,3, 3, 2        B) 2 ,   3, 4, 4    

  C)  1, 2, 3 ,4      D ) 4, 4, 2 ,3

解析:

数组 s[12] 的初始化为:{1, 2, 3, 4, 4, 3, 2, 1, 1, 1, 2, 3}。

这个数组包含 12 个元素。

数组 c[5] 的初始化为:{0, 0, 0, 0, 0}。

这是一个用于统计出现次数的数组,c[i] 表示整数 i 在数组 s 中出现的次数。

for 循环统计元素出现次数:

c[s[i]]++ 根据数组 s[i] 的值,更新数组 c[] 的对应索引。

这意味着,数组 c 会记录数组 s 中数字 1 到 4 的出现次数。

数组 s 中每个数字的出现次数:

数字 1 出现了 4 次。

数字 2 出现了 3 次。

数字 3 出现了 3 次。

数字 4 出现了 2 次。

因此,数组 c 更新为:{0, 4, 3, 3, 2}。

输出部分:

for (i = 1; i < 5; i++) printf("%d,", c[i]);

该循环会打印数组 c[1] 到 c[4] 的值,也就是 4, 3, 3, 2。

解答:

 A

 1.10   有数组  int  a[3][4] = {10,20,30,40,50,60,70,80,90,100,110,120},执行以下语句输出的是_______________

      printf(“%d\n”,  *(*a+2) + 3   );   

  A) 语句有错  B) 120     C)  30     D)  33

解析:

*a:

a 是一个二维数组,*a 代表 指向第一行的指针,也就是 a[0],即地址 &a[0][0],指向的是第一个元素 10。

*a + 2:

*a 是 a[0] 的首地址,即 &a[0][0],加上 2 就是指向 a[0][2],也就是 30 的地址。

*(*a + 2):

这是对 a[0][2] 解引用,结果是 30。

*(*a + 2) + 3:

这一步是在 30 的基础上再加上 3,所以结果是 30 + 3 = 33

解答:

D

2、填空题

    2.1、有以下程序

#include   <stdio.h>

main(   )

{ int i,n[ ]={0,0,0,0,0};

for(i=1;i<=4;i++)

{n[i]=n[i-1]*3+1;

printf(“%d”,n[i]);}

}

程序运行后输出结果是 __________

解析:

当 i = 1:

n[1] = n[0] * 3 + 1 = 0 * 3 + 1 = 1

输出:1

当 i = 2:

n[2] = n[1] * 3 + 1 = 1 * 3 + 1 = 4

输出:4

当 i = 3:

n[3] = n[2] * 3 + 1 = 4 * 3 + 1 = 13

输出:13

当 i = 4:

n[4] = n[3] * 3 + 1 = 13 * 3 + 1 = 40

输出:40

解答:

141340

    2.2、执行以下程序的输出结果是_                   .

#include <stdio.h>

int  main()

{ int i,n[4]={1,0,0,0};

for(i=1;i<=3;i++)

{ n[i]=n[i-1]*2+1; printf("%d",n[i]); }

}

解析:

当 i = 1:

n[1] = n[0] * 2 + 1 = 1 * 2 + 1 = 3

输出:3

当 i = 2:

n[2] = n[1] * 2 + 1 = 3 * 2 + 1 = 7

输出:7

当 i = 3:

n[3] = n[2] * 2 + 1 = 7 * 2 + 1 = 15

输出:15

解答:

3715

2.3、下面程序运行的结果为_________。

       main()

        {

           int  x[5],i;

           x[0] = 1;x[1] = 2;

           for(i = 2;i<5;i++) x[i] = x[i-1] + x[i-2];

           for(i = 2;i<5;i++) printf(“%d”,x[i]);

}

解析:

i = 2:

x[2] = x[1] + x[0] = 2 + 1 = 3

当 i = 3:

x[3] = x[2] + x[1] = 3 + 2 = 5

当 i = 4:

x[4] = x[3] + x[2] = 5 + 3 = 8

数组 x 的最终内容:

x[0] = 1

x[1] = 2

x[2] = 3

x[3] = 5

x[4] = 8

第二 for 循环:

再次循环从 i = 2 到 i < 5,输出 x[2], x[3], x[4] 的值。

输出:3, 5, 8

解答:

358

2.4、有以下程序

#include <sthio.h>

int  main()

{

int  arr[] = {1,3,5,7,2,4,6,8},  i,   start  ;

scanf(“%d”, &start);

 for(i=0,i<7,i+=2)

printf(“%d”,arr[(start+i)%5]);

}

若在程序运行时输入整数 10 <回车>,则输出结果为_______

解析:

当 i = 0:

arr[(start + i) % 5] = arr[(10 + 0) % 5] = arr[10 % 5] = arr[0]

输出:1

当 i = 2:

arr[(start + i) % 5] = arr[(10 + 2) % 5] = arr[12 % 5] = arr[2]

输出:5

当 i = 4:

arr[(start + i) % 5] = arr[(10 + 4) % 5] = arr[14 % 5] = arr[4]

输出:2

当 i = 6:

arr[(start + i) % 5] = arr[(10 + 6) % 5] = arr[16 % 5] = arr[1]

输出:3

解答:

1523

2.5下面程序运行的结果为_________。

#include "stdio.h"

      main()

      { int i,j,a[]={0,2,8,4,5};

        printf("\n");

         for(i=1;i<=5;i++)

        {  j=5-i;

          printf("%2d",a[j]);

         }

      }

解析:

当 i = 1:

j = 5 - 1 = 4

输出 a[4] = 5。

当 i = 2:

j = 5 - 2 = 3

输出 a[3] = 4。

当 i = 3:

j = 5 - 3 = 2

输出 a[2] = 8。

当 i = 4:

j = 5 - 4 = 1

输出 a[1] = 2。

当 i = 5:

j = 5 - 5 = 0

输出 a[0] = 0。

解答:

5 4 8 2 0

   2.6有以下程序

#include   <stdio.h>

int  main()

{ int n[2],i,j;

for(i=0;i<2;i++) n[i]=0; for(i=0;i<2;i++)

    for(j=0;j<2;j++) n[j]=n[i]+1;

printf(“%d\n”,n[1]);

}

程序运行后的输出结果是 【】

解析:

第一次for循环作用是对数组进行初始化全部赋值为0

第二个双层for循环外层是控制次数

第一次i=0时

j=0

n[0]=n[0]+1=0+1=1

j=1

n[1]=n[0]+1=1+1=2

第二次i=1时

j=0

n[0]=n[1]+1=2+1=3

j=1

n[1]=n[1]+1=2+1=3

输出n[1]为3

解答:

3

 3、编程题

3.1、 一个班10个学生的成绩,存放在一个一维数组中,要求找出其中成绩最高的学生的成绩和该生的序号。试编程。(试着用下标法和地址法两种方法表示数组)
代码解答:

下标法:

#include <stdio.h>int main() {int scores[10] = {85, 92, 78, 90, 88, 95, 82, 80, 91, 89}; // 假设的成绩int maxScore = scores[0]; // 假设第一个学生成绩为最高分int maxIndex = 0; // 最高分的序号(下标)// 找到最高分和对应的序号for (int i = 1; i < 10; i++) {if (scores[i] > maxScore) {maxScore = scores[i]; // 更新最高分maxIndex = i; // 更新最高分序号}}// 输出结果printf("最高成绩: %d\n", maxScore);printf("该生的序号: %d\n", maxIndex + 1); // 序号从 1 开始return 0;
}

地址法:

#include <stdio.h>int main() {int scores[10] = {85, 92, 78, 90, 88, 95, 82, 80, 91, 89}; // 假设的成绩int maxScore = *scores; // 假设第一个学生成绩为最高分int maxIndex = 0; // 最高分的序号(下标)// 找到最高分和对应的序号for (int i = 1; i < 10; i++) {if (*(scores + i) > maxScore) {maxScore = *(scores + i); // 更新最高分maxIndex = i; // 更新最高分序号}}// 输出结果printf("最高成绩: %d\n", maxScore);printf("该生的序号: %d\n", maxIndex + 1); // 序号从 1 开始return 0;
}

3.2、有5个学生上4门课程,要求输入全部学生的各门课程成绩,然后输出各门课程的平均成绩,并按照各个学生的平均成绩排序(成绩最高的学生排在数组最前面,最低学生排在数组最后面的行) (试着用下标法和地址法两种方法表示数组)。

代码解答:

下标法:

#include <stdio.h>#define STUDENTS 5
#define SUBJECTS 4int main() {int scores[STUDENTS][SUBJECTS]; // 存储学生成绩float avgScores[STUDENTS]; // 存储每个学生的平均成绩float subjectAverages[SUBJECTS] = {0}; // 存储每门课程的平均成绩// 输入学生的成绩for (int i = 0; i < STUDENTS; i++) {printf("输入第 %d 个学生的4门课程成绩:\n", i + 1);for (int j = 0; j < SUBJECTS; j++) {printf("课程 %d: ", j + 1);scanf("%d", &scores[i][j]);}}// 计算每个学生的平均成绩for (int i = 0; i < STUDENTS; i++) {float total = 0;for (int j = 0; j < SUBJECTS; j++) {total += scores[i][j];}avgScores[i] = total / SUBJECTS;}// 计算每门课程的平均成绩for (int j = 0; j < SUBJECTS; j++) {float total = 0;for (int i = 0; i < STUDENTS; i++) {total += scores[i][j];}subjectAverages[j] = total / STUDENTS;}// 按照学生的平均成绩排序(简单选择排序)for (int i = 0; i < STUDENTS - 1; i++) {for (int j = i + 1; j < STUDENTS; j++) {if (avgScores[i] < avgScores[j]) {// 交换平均成绩float temp = avgScores[i];avgScores[i] = avgScores[j];avgScores[j] = temp;// 同时交换对应的成绩for (int k = 0; k < SUBJECTS; k++) {int tempScore = scores[i][k];scores[i][k] = scores[j][k];scores[j][k] = tempScore;}}}}// 输出每门课程的平均成绩printf("\n各门课程的平均成绩:\n");for (int j = 0; j < SUBJECTS; j++) {printf("课程 %d: %.2f\n", j + 1, subjectAverages[j]);}// 输出每个学生的成绩和平均成绩printf("\n学生的成绩及平均成绩:\n");for (int i = 0; i < STUDENTS; i++) {printf("第 %d 个学生成绩: ", i + 1);for (int j = 0; j < SUBJECTS; j++) {printf("%d ", scores[i][j]);}printf(" | 平均成绩: %.2f\n", avgScores[i]);}return 0;
}

地址法:

#include <stdio.h>#define STUDENTS 5
#define SUBJECTS 4int main() {int scores[STUDENTS][SUBJECTS]; // 存储学生成绩float avgScores[STUDENTS]; // 存储每个学生的平均成绩float subjectAverages[SUBJECTS] = {0}; // 存储每门课程的平均成绩// 输入学生的成绩for (int i = 0; i < STUDENTS; i++) {printf("输入第 %d 个学生的4门课程成绩:\n", i + 1);for (int j = 0; j < SUBJECTS; j++) {printf("课程 %d: ", j + 1);scanf("%d", (*(scores + i) + j)); // 地址法输入}}// 计算每个学生的平均成绩for (int i = 0; i < STUDENTS; i++) {float total = 0;for (int j = 0; j < SUBJECTS; j++) {total += *(*(scores + i) + j); // 地址法计算}avgScores[i] = total / SUBJECTS;}// 计算每门课程的平均成绩for (int j = 0; j < SUBJECTS; j++) {float total = 0;for (int i = 0; i < STUDENTS; i++) {total += *(*(scores + i) + j); // 地址法计算}subjectAverages[j] = total / STUDENTS;}// 按照学生的平均成绩排序(简单选择排序)for (int i = 0; i < STUDENTS - 1; i++) {for (int j = i + 1; j < STUDENTS; j++) {if (avgScores[i] < avgScores[j]) {// 交换平均成绩float temp = avgScores[i];avgScores[i] = avgScores[j];avgScores[j] = temp;// 同时交换对应的成绩for (int k = 0; k < SUBJECTS; k++) {int tempScore = *(*(scores + i) + k);*(*(scores + i) + k) = *(*(scores + j) + k);*(*(scores + j) + k) = tempScore;}}}}// 输出每门课程的平均成绩printf("\n各门课程的平均成绩:\n");for (int j = 0; j < SUBJECTS; j++) {printf("课程 %d: %.2f\n", j + 1, subjectAverages[j]);}// 输出每个学生的成绩和平均成绩printf("\n学生的成绩及平均成绩:\n");for (int i = 0; i < STUDENTS; i++) {printf("第 %d 个学生成绩: ", i + 1);for (int j = 0; j < SUBJECTS; j++) {printf("%d ", *(*(scores + i) + j)); // 地址法输出}printf(" | 平均成绩: %.2f\n", avgScores[i]);}return 0;
}

作业二

指针练习

  1. 选择题

1.1、若有下面的变量定义,以下语句中合法的是(    )。

int i,a[10],*p;

A) p=a+2;       B) p=a[5];   

        C) p=a[2]+2;      D) p=&(i+2);

解析:

A) p = a + 2;

这是合法的。a 是一个整型数组,a + 2 表示指向数组中第 3 个元素(索引为 2)的指针。p 可以正确地指向这个元素。

B) p = a[5];

这是不合法的。a[5] 表示数组中第 6 个元素的值(类型为 int),而 p 是一个整型指针,不能直接赋值一个 int 值。

C) p = a[2] + 2;

这是不合法的。a[2] 是数组中第 3 个元素的值(类型为 int),而 p 是指针,不能直接将一个 int 值加 2 后赋值给 p。

D) p = &(i + 2);

这是不合法的。&(i + 2) 表示 i + 2 的地址,但是 i + 2 是一个临时计算的值,不能取得地址。

解答:

A

1.2、有以下程序


main()
{
   int  a[3][3],*p,i;
   p=&a[0][0];
   for(i=0;i<9;i++)
      p[i]=i;
   for(i=0;i<3;i++)
      printf("%d ",a[1][i]);
}
程序运行后的输出结果是 ____________
A)0 1 2
B)1 2 3
C)2 3 4
D)3 4 5
 

解析:

a[0][0] = 0

a[0][1] = 1

a[0][2] = 2

a[1][0] = 3

a[1][1] = 4

a[1][2] = 5

a[2][0] = 6

a[2][1] = 7

a[2][2] = 8

这里输出的是数组 a 的第二行,即 a[1][0]、a[1][1] 和 a[1][2],对应的值是 3、4 和 5。

解答:

D

1.3、有以下程序


int  main()
{   int  a[3][2]={0},   (*ptr)[2],i,j;   
    for(i=0;i<2;i++)
    {   ptr=a+i;
        scanf("%d",*ptr);
        *ptr++;
    }
    for(i=0;i<3;i++)
    {
        for(j=0;j<2;j++)
           printf("%2d",a[i][j]);
        printf("\n");
    }
}
若运行时输入:1  2  3<回车>,则输出结果为 ___________
A)产生错误信息
B)1 0
    2 0
    0 0
C)1 2
    3 0
    0 0
D)1 0
    2 0
    3 0
 

解析:

用户输入 1 2 3(中间用空格分隔),这样在循环中会被逐个读取:

当 i = 0 时,输入 1,将其存储到 a[0][0]。

当 i = 1 时,输入 2,将其存储到 a[1][0]。

因为循环只运行了 2 次,所以 a[2] 不会被修改。

对于 i = 0,a[0] = {1, 0} 输出 1 0

对于 i = 1,a[1] = {2, 0} 输出 2 0

对于 i = 2,a[2] = {0, 0} 输出 0 0

解答:

C

1.4、有以下程序


main()
{   int  a[]={1,2,3,4,5,6,7,8,9,0},*p;
    for(p=a;p<a+10;p++)
      printf("%d,",*p);
}
程序运行后的输出结果是 __________
   A)1,2,3,4,5,6,7,8,9,0,
   B)2,3,4,5,6,7,8,9,10,1,
   C)0,1,2,3,4,5,6,7,8,9,
   D)1,1,1,1,1,1,1,1,1,,1,

解析:

p = a 将指针 p 初始化为数组 a 的首地址。

p < a + 10 是循环的条件,表示只要 p 小于数组 a 的末尾地址(即 a 的第 10 个元素的地址),循环将继续执行。

*p 表示获取 p 指向的当前元素的值,并将其打印。

在循环中,指针 p 将依次指向数组 a 中的每个元素,输出顺序为:

第一次循环:*p 是 1

第二次循环:*p 是 2

第三次循环:*p 是 3

第四次循环:*p 是 4

第五次循环:*p 是 5

第六次循环:*p 是 6

第七次循环:*p 是 7

第八次循环:*p 是 8

第九次循环:*p 是 9

第十次循环:*p 是 0

解答:

A

1.5、有以下程序


main()
{
   char  s[]="159",*p;
   p=s;
   printf("%c",*p++);
   printf("%c",*p++);
}
程序运行后的输出结果是________
A)1 5  B)1 6   C)1 2   D)5  9

解析:

第一次执行 printf("%c", *p++);:

*p 是指向当前字符 '1',所以输出 '1'。

p++ 将指针 p 移动到下一个字符 '5'。

第二次执行 printf("%c", *p++);:

此时 p 指向字符 '5',所以输出 '5'。

p++ 将指针 p 移动到下一个字符 '9'。

解答:

A

1.6、有以下程序


point(char  *p)
{
   p+=3;
}
int  main()
{   char  b[4]={'a','b','c','d'},  *p=b;
    point(p);    printf("%c\n",*p);
}
程序运行后的输出结果是 __________
A)a    B)b    C)c      D)d
 

解析:

当调用 point(p); 时,传递的是 p 的副本。因此,原始指针 pmain 函数中的值仍然指向字符数组 b 的第一个元素,即 'a'

解答:

A

1.7、设有如下定义语句 int m[ ]={2,4,6,8},   *k=m;

以下选项中,表达式的值为 6的是

A *(k+2)      B   k+2     C   *k+2     D *k+=2

解析:

A) *(k + 2)

k + 2 会指向 m[2],也就是 6。

*(k + 2) 的值为 6。

结果: 是 6。

B) k + 2

k + 2 是指针运算,它会返回指向 m[2] 的地址。

这个表达式的值是指针,不是 6。

结果: 不是 6。

C) *k + 2

*k 是 m[0],即 2。

*k + 2 的值为 2 + 2 = 4。

结果: 不是 6。

D) *k += 2

*k 是 m[0],即 2。这个表达式会将 m[0] 的值更新为 4。

此时,该表达式的值是更新后的 4,而不是 6。

结果: 不是 6。

解答:

 A

1.8、若有定义语句:int year=2009,*p=&year;,以下不能使变量 year 中的值增至 2010 的语 句是(  )。

A)*p+=1;   B)( *p)++;   C)++(*p);    D)*p++;

解析:

A) *p += 1;

这个语句会将 year 的值增加 1。

结果:year 变为 2010。

可以实现。

B) (*p)++;

这个语句会先返回 year 的值(2009),然后将 year 的值增加 1。

结果:year 变为 2010。

可以实现。

C) ++(*p);

这个语句会将 year 的值增加 1,等同于 *p += 1;。

结果:year 变为 2010。

可以实现。

D) *p++;

这个语句中的 *p++ 先返回 *p(即 year 的值 2009),然后 p 自增到指向下一个整型的位置。

这个操作不会改变 year 的值。

结果:year 仍然为 2009。

解答:

 D

1.9、设有定义:double x[10],*p=x;,以下能给数组 x 下标为 6 的元素读入数 据的正确语句是

A)scanf("%f",&x[6]);   B)scanf("%lf",*(x+6));

C)scanf("%lf",p+6);      D)scanf("%lf",p[6]);

解析:

A) scanf("%f", &x[6]);

%f 是用于读取 float 类型的格式符,而 x[6] 是 double 类型的。

这个语句是错误的,因为格式符与变量类型不匹配。

不正确。

B) scanf("%lf", *(x + 6));

*(x + 6) 表示访问 x[6] 的值,但这里不应该使用解引用操作符 *。

正确的方式是使用 & 来获取地址。

这个语句是错误的。

不正确。

C) scanf("%lf", p + 6);

p + 6 是指向 x[6] 的指针,而 %lf 是用于读取 double 类型的格式符。

这个语句是正确的,因为它可以直接将 x[6] 的地址传递给 scanf。

正确。

D) scanf("%lf", p[6]);

p[6] 等价于 *(p + 6),表示访问 x[6] 的值,而不是地址。

因此,这个语句也是错误的,因为它尝试将一个值传递给 scanf,而 scanf 需要一个地址。

不正确。

解答:

 C

1.10、若有定义语句:char s[3][10],   (*k)[3],   *p; ,则以下赋值语句正确的是____

    A)p=s;       B)p=s[0];    C)p=k;     D)k=s;

解析:

A) p = s;

s 是 char 类型的二维数组,代表 char (*)[10](指向包含 10 个字符的数组的指针)。

p 是 char *,无法直接赋值。

不正确。

B) p = s[0];

s[0] 是指向 s 的第一行的指针,类型是 char *。

这与 p 的类型相匹配,因此这个赋值是有效的。

正确。

C) p = k;

k 的类型是 char (*)[3],指向包含 3 个字符的数组。

p 的类型是 char *,这两个类型不兼容。

不正确。

D) k = s;

s 的类型是 char (*)[10](指向包含 10 个字符的数组的指针),与 k 的类型不匹配。

不正确。

解答:

 B

1.11、有定义语句:int *p[4]; 以下选项中与此语句等价的是

A)int p[4];    B)int **p;   C)int *(p[4]);    D)int (*p)[4];

解析:

int *p[4]; 定义了一个包含 4 个元素的数组 p,每个元素都是指向 int 的指针。也就是说,p 是一个指针数组,其中每个元素都指向一个 int 类型的值。

A) int p[4];

这定义了一个包含 4 个 int 类型元素的数组。与 int *p[4]; 不相同。

不等价。

B) int **p;

这定义了一个指向指针的指针,表示一个指向 int * 类型的指针。与 int *p[4]; 不相同。

不等价。

C) int *(p[4]);

这与 int *p[4]; 等价,因为它同样定义了一个包含 4 个 int * 类型元素的数组(虽然书写方式不同,但意义相同)。

等价。

D) int (*p)[4];

这定义了一个指向包含 4 个 int 元素的数组的指针,和 int *p[4]; 不同。

不等价。

解答:

 C

1.12、若有定义语句:int a[4][10], *p, *q[4]; 且 0≤i<4,则错误的赋值 是

A)p=a  B)q[i]=a[i]  C)p=a[i]  D)p=&a[2][1]

解析:

选项A:p = a

a 是一个二维数组 int a[4][10],在 C 语言中,a 的类型是 int (*)[10](指向包含 10 个整数的一维数组的指针)。

p 是一个 int * 类型的指针。

在这种情况下,p = a 的赋值是 不合法 的,因为:

a 是一个指向一维数组的指针,不能直接赋值给一个指向单个 int 的指针 p。这种赋值会导致类型不匹配。

正确的赋值应该是 p = &a[0][0],这样 p 才会指向数组的第一个元素。

解答:

A

1.13、若有以下定义

int x[10],*pt=x;

则对 x 数组元素的正确应用是

A)*&x[10]    B)*(x+3)

3C)*(pt+10) D)pt+3

解析:

A)*&x[10]

x[10] 超出了数组的有效范围(合法索引为 0 到 9),因此访问 x[10] 是不合法的。

结果:不合法

B)*(x + 3)

x + 3 指向数组 x 的第四个元素(索引为 3)。

*(x + 3) 访问这个元素的值。

结果:合法,返回 x[3] 的值。

C)*(pt + 10)

pt + 10 超出了数组的有效范围(合法索引为 0 到 9),所以访问 *(pt + 10) 是不合法的。

结果:不合法

D)pt + 3

pt + 3 指向 x 数组的第四个元素(索引为 3),但此表达式本身不访问元素的值,只是计算地址。

结果:不合法,不直接返回数组元素的值。

解答:

B

1.14、有以下程序

#include <stdio.h>

main()

{ int a[ ]={1,2,3,4},y,*p=&a[3];

--p; y=*p; printf(“y=%d\n”,y);

}

程序的运行结果是

A)y=0   B)y=1    C)y=2   D)y=3

解析:

数组 a 的定义为 {1, 2, 3, 4},索引从 0 到 3。

a[0] = 1

a[1] = 2

a[2] = 3

a[3] = 4

指针 p 初始化为指向 a[3],即 p 的值为 &a[3](地址值指向元素 4)。

执行 --p;,指针 p 现在指向 a[2],即元素值 3。

y = *p; 解引用 p 得到 a[2] 的值,赋值给 y。所以 y = 3。

最后,printf("y=%d\n", y); 打印 y 的值。

解答:

D

1.15、设char  *s = “\ta\017bc”;则指针变量s指向的字符串所占的字节数是_______

   A)  6   B)  2   C)   5   D) 9

解析:

\t 表示一个制表符(Tab),占用 1 个字节。

a 是一个普通字符,占用 1 个字节。

\017 是一个八进制数,表示字符 \017,对应的十进制值为 15,实际上是控制字符,占用 1 个字节。

b 是一个普通字符,占用 1 个字节。

c 是一个普通字符,占用 1 个字节。

字符串的结束符 \0,占用 1 个字节。

解答:

A

1.16、  若有定义语句:char s[3][10],  (*k)[3],   *p;,则以下赋值语句正确的是 A)p=s; B)p=k; C)p=s[0]; D)k=s;
解析:

A) p = s;

s 是 char 类型的二维数组,代表 char (*)[10](指向包含 10 个字符的数组的指针)。

p 是 char *,无法直接赋值。

不正确。

C) p = s[0];

s[0] 是指向 s 的第一行的指针,类型是 char *。

这与 p 的类型相匹配,因此这个赋值是有效的。

正确。

B) p = k;

k 的类型是 char (*)[3],指向包含 3 个字符的数组。

p 的类型是 char *,这两个类型不兼容。

不正确。

D) k = s;

s 的类型是 char (*)[10](指向包含 10 个字符的数组的指针),与 k 的类型不匹配。

不正确。

解答:

C

2、填空题

2.1以下程序的输出结果是_______

#include<stdio.h>

main()

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

p=a+2;

printf(“%d”,*p++);

}

解析:

数组初始化:

int a[5] = {2, 4, 6, 8, 10};:数组 a 被初始化为 2, 4, 6, 8, 10。

指针赋值:

p = a + 2;:指针 p 指向数组 a 的第三个元素(a[2]),即 6。

打印输出:

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

*p 取出 p 指向的值(即 6)。

p++ 后缀自增,指针 p 将指向下一个元素(a[3],值为 8)。

因此,输出 6。

解答:

6

2.2、以下程序段的定义语句中,x[1]的初值是_____,程序运行后输出的内容是_______

#include<stdio.h>

 main()

{ int x[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},*p[4],i;

for(i=0;i<4;i++)

{ p[i]=&x[2*i+1]; printf(“%d ”,p[i][0]);

}

printf(“\n”);

}

解析:

数组 x 的初始化:

x 被初始化为 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16。

x[1] 的初值:

因此,x[1] 的初值是 2。

在 for 循环中,指针 p[i] 被赋值为 &x[2*i + 1]:

当 i = 0:

p[0] = &x[2*0 + 1] = &x[1],此时 p[0] 指向 x[1](值为 2)。

输出 p[0][0],即 *p[0],结果为 2。

当 i = 1:

p[1] = &x[2*1 + 1] = &x[3],此时 p[1] 指向 x[3](值为 4)。

输出 p[1][0],即 *p[1],结果为 4。

当 i = 2:

p[2] = &x[2*2 + 1] = &x[5],此时 p[2] 指向 x[5](值为 6)。

输出 p[2][0],即 *p[2],结果为 6。

当 i = 3:

p[3] = &x[2*3 + 1] = &x[7],此时 p[3] 指向 x[7](值为 8)。

输出 p[3][0],即 *p[3],结果为 8。

解答:

2        2468

    2.3  以下程序段的输出结果是( )

#include <sthio.h>

mian()

{ char *ch[4]={“red”,”green”,”blue”}; int  i=0;

while(ch[i]);

{   putchar(ch[i][0];    i++;   }

}

解析:

字符指针数组 ch:

char *ch[4] = {"red", "green", "blue", NULL}; 这是一个字符指针数组,存储了三个字符串和一个 NULL 指针,用于标识数组的结束。

while (ch[i]) 循环:

循环的条件是 ch[i],它会检查 ch[i] 是否为 NULL。如果不是,则继续执行循环。

输出 putchar(ch[i][0]):

ch[i][0] 获取字符串 ch[i] 的第一个字符。

对于字符串数组中的每个字符串,输出其首字符:

当 i = 0 时,ch[0] 是 "red",输出 r。

当 i = 1 时,ch[1] 是 "green",输出 g。

当 i = 2 时,ch[2] 是 "blue",输出 b。

当 i = 3 时,ch[3] 是 NULL,循环结束。

解答:

rgb

       2.4、以下程序的功能是:借助指针变量找出数组元素中最大值所在的位置并输出该最大值。 请在输出语句中填写代表最大值的输出项。

#include   <stdio.h> 

int   main()

{ int a[10], *p, *s;

for(p=a; p-a<10; p++)

scanf(“%d”,  p);

for(p=a,s=a;p-a<10;p++)

if(*p>*s) s=p;

printf(“max=%d,  序号:%d\n” , ___________ );

}

解析:

输入数组:使用 scanf 输入 10 个整数。

查找最大值:

使用两个指针 p 和 s,其中 s 初始化为指向数组的起始位置,p 遍历整个数组。

在循环中,如果当前指针 p 所指向的值大于 s 所指向的值,则更新 s,使其指向当前更大的值。

输出最大值和序号:

*s:表示最大值。

s - a:表示最大值在数组中的索引位置。

解答:

*s,s-a

2.5 有以下程序,输出结果为_________

      main()

int a[5]={1,2,3,4,5};   

int *ptr=(int *)(&a+1);   

printf("%d,%d",*(a+1),*(ptr-1));

}  

解析:

数组定义:

int a[5] = {1, 2, 3, 4, 5}; 定义了一个包含五个整数的数组 a。

指针定义:

int *ptr = (int *)(&a + 1);

&a 是数组 a 的地址,其类型是 int (*)[5](指向数组的指针)。

&a + 1 的效果是获取 a 数组之后的内存地址,这个地址是 a 的末尾加上整个数组的大小(即 5 个 int 的大小,通常是 20 字节,假设 int 是 4 字节)。

由于 &a + 1 结果是一个指向 int[5] 的指针,因此在进行强制类型转换后,ptr 实际指向的是 a 数组之后的第一个 int(即 a[5])。

打印输出:

*(a + 1):

这个表达式指向 a 数组的第二个元素,值是 2。

*(ptr - 1):

ptr - 1 实际上是指向 a[4](数组的最后一个元素),值是 5。

解答:

2,5

2.6  以下程序的功能是:借助指针变量找出数组元素中最大值所在的位置并输出该最大值。 请在输出语句中填写代表最大值的输出项。

#include <stdio.h>

int main( )

{ int a[10], *p, *s;

for(p=a;p-a<10; p++)

scanf(“%d”,p);

 for(p=a,s=a;p-a<10;p++)

 if(*p>*s) s=p;

printf(“max=%d\n” ,  ______ );

解析:

输入数组:使用 scanf 输入 10 个整数。

查找最大值:

使用两个指针 p 和 s,其中 s 初始化为指向数组的起始位置,p 遍历整个数组。

在循环中,如果当前指针 p 所指向的值大于 s 所指向的值,则更新 s,使其指向当前更大的值。

输出最大值和序号:

*s:表示最大值。

s - a:表示最大值在数组中的索引位置。

解答:

*s,s-a

3、编程题

3.1、 有一个整型数组int [10] = {10,20,30,40,50,60,70,80,90,100};标准输入一个整型数值m(0<m<10) ,使前面10-m个数值向后移动m个位置,最后m个数变成前面的m个数
代码解答: 
#include <stdio.h>int main() {int arr[10] = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};int m;// 输入m的值,确保0 < m < 10printf("请输入一个整数 m (0 < m < 10): ");scanf("%d", &m);// 检查输入的合法性if (m <= 0 || m >= 10) {printf("输入不合法!m的值必须在0到10之间。\n");return 1; // 结束程序}// 移动数组// 从后往前移动for (int i = 9; i >= m; i--) {arr[i] = arr[i - m];}// 将最后m个数变成前面的m个数for (int i = 0; i < m; i++) {arr[i] = 10 * (i + 1); // 将前m个数设为10, 20, 30, ...}// 输出结果printf("移动后的数组为:");for (int i = 0; i < 10; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}

                     

作业三

结构体共用体练习

  1. 选择题

   1.1、设有以下语句:

typedef struct REC

{

           char c;

           int a[4];

}REC1;

则下面叙述中正确的是____________。

A)可以用REC定义结构体变量

B)REC1是struct REC类型的变量

C)REC是struct 类型的变量。

D)可以用REC1定义结构体变量

解析:

A)可以用 REC 定义结构体变量

错误。REC 是结构体的标签名,而不是类型名。你需要使用 struct REC 来定义结构体变量。

B)REC1 是 struct REC 类型的变量

错误。REC1 是 struct REC 的别名,不是变量。它是一个类型名。

C)REC 是 struct 类型的变量

错误。REC 是结构体的标签名,不是变量。结构体变量需要显式地定义,比如 struct REC myVar;。

D)可以用 REC1 定义结构体变量

正确。因为 REC1 是 struct REC 的别名,所以你可以使用 REC1 来定义结构体变量,如 REC1 myVar;。

解答 :

D

1.2、下列关于结构的说法错误的是______.

A)结构是由用户自定义的一种数据类型。

B)结构中可设定若干个不同数据类型的成员。

C)结构中成员的数据类型可以是另一个已定义的结构

D)在定义结构时,可以为成员设置默认值。

解析:

A) 结构是由用户自定义的一种数据类型。

正确。结构确实是用户定义的一种数据类型,可以包含多个成员。

B) 结构中可设定若干个不同数据类型的成员。

正确。结构的成员可以是不同的数据类型,例如整型、字符型、浮点型等。

C) 结构中成员的数据类型可以是另一个已定义的结构。

正确。结构的成员可以是其他结构类型,这样可以实现嵌套结构。

D) 在定义结构时,可以为成员设置默认值。

错误。在 C 语言中,不能直接在结构定义时为成员设置默认值。需要在定义结构变量后,通过赋值来设置成员的值。

解答 :

D

1.3、以下结构体类型说明和变量定义中,正确的是______。

A)  struct SS                             B)  struct

{                                                  {

              char flag;                                         char flag;

              float x;                                             float x;

}                                                }SS;

                         struct SS  a, b;

C)  struct ss                              D)typedef

{                                                         {

       char flag;                                                char flag;

              float x;                                                 float x

};                                                        }SS;

               struct  ss  a,b;             SS a,b;

解析:

A)在定义结构体时少了个`;`

B)struct 关键字后面缺少结构体的名称。正确的写法应该是 struct SS

C)正确

D)typedef 语句的写法不正确。typedef 后面需要跟 struct 类型的完整定义,且结构体变量的定义也有错误,正确写法应该是 typedef struct { ... } SS;,然后可以用 SS a, b; 来声明变量。

解答 :
C
1.4、设有以下说明语句:

struct stu

{

            int a;

            float b;

}stutype;

则下面的叙述不正确的是____________。

A)struct是结构体类型的关键字

B)struct stu是用户定义的结构体类型名

C)stutype 是用户定义的结构体类型名

D)a 和b 都是结构体成员名

解析:

A) 正确。struct 确实是结构体类型的关键字。

B) 正确。struct stu 是结构体类型的声明,其中 stu 是用户定义的结构体类型名。

C) 错误。stutype 是结构体的类型定义,并不是用户定义的结构体类型名。实际上,stutype 是该结构体类型的一个别名。

D) 正确。a 和 b 确实是结构体成员名

解答 :

C

1.5、根据下面的定义,能打印出字母M的语句是____________。

struct person

{

              char name[9];

              int age;

};

struct person class[10] = {“John”,17,”Paul”,19,”Mary”,18,”adam”,16};

A)  printf(“%c\n”,class[3].name);

B)  printf(“%c\n”,class[3].name[1]);

C)  printf(“%c\n”,class[2].name[1]);

D)  printf(“%c\n”,class[2].name[0]);

解析:

A) printf(“%c\n”,class[3].name);

这将尝试打印 class[3].name,这是一个字符串(字符数组),会导致类型不匹配错误。

B) printf(“%c\n”,class[3].name[1]);

class[3].name 对应的字符串是 "adam",name[1] 是 'd',因此不会打印出 M。

C) printf(“%c\n”,class[2].name[1]);

class[2].name 对应的字符串是 "Mary",name[1] 是 'a',因此不会打印出 M。

D) printf(“%c\n”,class[2].name[0]);

class[2].name 对应的字符串是 "Mary",name[0] 是 'M',所以这条语句将打印出字母 M。

解答 :

D

1.6、若有如下定义:

struct person

{

      int id;

          char name[10];

}per,*s = &per;

则以下对结构体成员的引用中错误的是____________。

A) per.name                  B) s->name[0]

C) (*per).name[8]         D) (*s).id

解析:

A) per.name

这是一个正确的引用,直接访问 per 的 name 成员。

B) s->name[0]

这是一个正确的引用,使用箭头运算符(->)访问指针 s 指向的结构体的 name 成员。

C) (*per).name[8]

这是错误的引用。这里的 per 是一个结构体变量,而不是指针,因此不能使用解引用操作符 *。正确的写法应为 (*s).name[8] 或 s->name[8]。

D) (*s).id

这是一个正确的引用,使用解引用操作符访问指针 s 指向的结构体的 id 成员。

解答 :

C

1.7、下面程序的运行结构是____________。

main()

{

          struct cmplx{int x;

                                   int y;

                     }cnum[2] = {1,3,2,7};

printf(“%d\n”,cnum[0].y/cnum[0].x*cnum[1].x);

}

A)0     B)1    C)3        D)6

解析:

结构体初始化:

cnum[0] 初始化为 {1, 3},即 cnum[0].x = 1 和 cnum[0].y = 3。

cnum[1] 初始化为 {2, 7},即 cnum[1].x = 2 和 cnum[1].y = 7。

计算表达式:

首先计算 cnum[0].y / cnum[0].x:

cnum[0].y/cnum[0].x=3/1=3

cnum[0].y/cnum[0].x=3/1=3

然后乘以 cnum[1].x:

3∗cnum[1].x=3∗2=6

3∗cnum[1].x=3∗2=6

输出结果:

程序输出 6。

解答 :

D

1.8、若有以下定义和语句:

struct student

{

          int age;

          int num;

};

struct student stu[3] = {{1001,20},{1002,19},{1003,21}};

main( )

{

          sturct student *p;

          p = stu;

          …

}

则以下不正确的引用形式是____________。

A)  (p++) ->num               B)  p++

C)  (*p).num                      D)  p = &stu.age

解析:

A) (p++) -> num

合法:这个表达式首先访问指针 p 指向的 num 成员,然后将 p 增加到下一个 student 结构体(这通常是有效的,尽管需要注意这种用法在某些情况下会导致未定义行为)。

B) p++

合法:这个表达式增加指针 p,将其指向下一个 student 结构体。

C) (*p).num

合法:这个表达式解引用指针 p 并访问 num 成员。

D) p = &stu.age

不合法:stu 是一个结构体数组,stu.age 不是有效的表达式。结构体数组的成员必须通过索引来访问。例如,应该使用 stu[0].age 来获取第一个结构体的 age 成员的地址

解答 :

D

1.9、设有以下定义和语句,以下引用形式不合法的是____________。

struct s

{

           int il;

           struct s *i2;

char  *i0;

};

   static struct s a[3] = {2,&a[1],'\0',4,&a[2], ‘\0’ , 6 ,&a[1], ‘\0’  },*ptr;

ptr = a;

A)  ptr->i1++    B)  *ptr->i2     C) ++ptr->i0     D)  *ptr->i1

解析:

A) ptr->i1++

合法:这个表达式对 ptr 所指向的结构体的 i1 成员进行自增操作。

B) *ptr->i2

合法:ptr->i2 返回指向另一个 struct s 的指针,*ptr->i2 解引用该指针。

C) ++ptr->i0

合法:ptr->i0 是一个指向字符的指针,因此可以对其进行自增操作,指向下一个字符。

D) *ptr->i1

不合法:ptr->i1 是一个 int 类型的成员,不能解引用。解引用只能用于指针类型。

解答 :

D

1.10、设有如下定义:

struct sk

{

             int n;

             float x;

}data,*p;

若要使p指向data中的n域,则正确的赋值语句是____________。

A) p = &data.n;                   B) *p = data.n;

C) p =(struct sk *)&data.n;     D) p = (struct sk *)data.n;

解析:

A) p = &data.n;

不合法:&data.n 是一个指向 int 的指针,但 p 是指向 struct sk 的指针。

B) *p = data.n;

不合法:*p 期望一个 struct sk 类型的值,但 data.n 是 int 类型,类型不匹配。

C) p =(struct sk *)&data.n;

合法:&data.n 是一个指向 int 的指针,强制转换为 struct sk * 是合适的,因为它们的类型不同。

D) p = (struct sk *)data.n;

不合法:data.n 是 int 类型,强制转换为 struct sk * 不合适,可能会导致不正确的内存访问。

解答 :

C

1.11、若有以下程序段:

struct dent

{

       int n;

       int *m;

};

int a = 1,b = 2,c = 3;

struct dent s[3] = {{101,&a},{102,&b},{103,&c}};

main()

{

  struct dent *p;

           p =s;

          …

}

则以下表达式中值为2的是____________。

A)  (++p)->m         B)  *(p++)->m

C)  (*p).m               D)  *(++p)->m

解析:

A) (++p)->m

p 指向 s[0],执行 ++p 后,p 指向 s[1]。

p->m 是 s[1].m,即 &b,其值为 2。

值为 2。

B) *(p++)->m

p 指向 s[0],首先解引用 p,p->m 是 s[0].m,即 &a,其值为 1。

然后 p++ 会使 p 指向 s[1]。所以这个表达式返回的是 *(&a) 的值,结果为 1。

值为 1。

C) (*p).m

此时 p 指向 s[0],(*p).m 是 s[0].m,即 &a,值为 1。

值为 1。

D) *(++p)->m

p 指向 s[0],执行 ++p 后,p 指向 s[1]。

*(p->m) 是 *(s[1].m),即 *(&b),值为 2。

值为 2。

解答 :

AD

1.12、若有以下说明和语句,则对pup中sex域的正确引用方式是____________

struct pupil

{

            char name[20];

            int sex;

}pup,*p;

p = &pup;

A)  p.pup.sex              B)  p->pup.sex

C)  (*p).pup.sex         D)  (*p).sex

解析:

A) p.pup.sex

p 是指针,不能用点运算符(.)直接引用。此写法不合法。

错误。

B) p->pup.sex

p 是指向 pup 的指针,p->pup 表示对 pup 的引用,但 pup 是结构体变量而不是结构体成员。这个表达式是不合法的。

错误。

C) (*p).pup.sex

(*p) 是 pup 的引用,但同样 (*p).pup 是不合法的,因为 pup 是结构体变量而不是结构体成员。

错误。

D) (*p).sex

(*p) 解引用指针 p,得到 pup 结构体,然后可以直接访问 sex 域。

这是合法且正确的引用方式。

正确。

解答 :

D

1.13、以下程序的输出结果是____________。

struct stu

{

       int x;

              int *y;

}*p;

int dt[4] = {10,20,30,40};

struct stu a[4] = {50,&dt[0],60,&dt[1],70,&dt[2],80,&dt[3]};

main( )

{

            p = a;

            printf(“%d,”,++p->x);

            printf(“%d”,(++p)->x);

            printf(“%d”,++(*p->y));

}

A)10,20,20                    B)50,60,21

C)51,60,21                    D)60,70,31

解析:

第一行: printf("%d,", ++p->x);

p 最初指向 a[0],即 x = 50。

++p->x 会先将 p->x(即 a[0].x)加 1,然后输出 51。

此时 a[0].x 的值变为 51。

输出: 51

第二行: printf("%d", (++p)->x);

++p 将 p 移动到 a[1],即 x = 60。

输出 60。

输出: 60

第三行: printf("%d", ++(*p->y));

此时 p 仍然指向 a[1]。

p->y 指向 dt[1],即 y = 20。

++(*p->y) 将 dt[1] 的值加 1,变为 21。

输出: 21

解答 :

C

1.14、若有以下说明和语句,则下面表达式中值为1002的是____________。

struct   student

{

            int age;

            int num;

};

struct student stu[3] = {{1001,20},{1002,19},{1003,21}};

struct student  *p;

p = stu;

A)  (p++)->num                     B)  (p++)->age

C)  (*p).num                           D)  (*++p).age

解析:

A) (p++)->num

p++ 先使用 p 的当前值(stu[0]),然后将 p 指向 stu[1]。

p->num 为 20(stu[0].num),所以输出是 20,不是 1002。

B) (p++)->age

同样,p++ 先使用 stu[0],然后将 p 指向 stu[1]。

p->age 为 1001(stu[0].age),所以输出是 1001,不是 1002。

C) (*p).num

此时 p 仍然指向 stu[0],所以 (*p).num 为 20,不是 1002。

D) (*++p).age

++p 将 p 移动到 stu[1]。

(*p).age 为 1002(stu[1].age),所以输出是 1002。

解答 :

D

1.15、以下对结构体变量stu1中成员age的非法引用是____________。

struct student

{

            int age;

            int num;

}stu1,*p;

p = &stu1;

A) stu1.age                          B) student.age

C) p ->age                              D) (*p).age

解析:

A) stu1.age

这是合法的引用,直接访问 stu1 中的 age 成员。

B) student.age

这是非法的引用。student 是结构体类型名,而不是变量名。不能直接通过结构体类型名访问结构体成员。

C) p->age

这是合法的引用。指针 p 指向 stu1,通过箭头运算符可以访问 age 成员。

D) (*p).age

这是合法的引用。解引用指针 p 后可以通过点运算符访问 age 成员

解答 :

B

1.16、 设有以下说明和定义语句,则下面表达式中值为3的是____________

struct s

{

             int il;

             struct s *i2;

};

static struct s a[3] = {1,&a[1],2,&a[2],3,&a[0]},*ptr;

ptr = &a[1];

A)ptr->il++                              B)ptr++->il

C)(ptr++)->il                                      D)++ptr->il

解析:

A) ptr->il++

ptr->il 的当前值为 2,执行 ptr->il++ 后,值变为 3,并且返回的值是 2。所以这个表达式的结果不是 3。

B) ptr++->il

先计算 ptr->il,此时 ptr 指向 a[1],所以返回值为 2,然后 ptr 移动到下一个元素(指向 a[2])。所以返回值不是 3。

C) (ptr++)->il

这个表达式与选项 B 类似,首先返回 ptr->il 的值,即 2,然后再进行指针自增。返回值不是 3。

D) ++ptr->il

这个表达式会首先对 ptr->il 进行自增,ptr 指向 a[1],ptr->il 从 2 自增到 3,并返回自增后的值 3。

解答 :

D

1.17、若有以下定义和语句:

union data

{

     int i;

              char c;

              float f;

}a;

int n;

则以下语句正确的是____________。

A)a = 5;                                      B)a.f = 1.2

C)printf(“%d\n”,a);      D)n =a;

解析:

A) a = 5;

这是错误的,因为 a 是一个联合体,无法直接赋值为一个整数。正确的写法应该是使用 a.i = 5;。

B) a.f = 1.2;

这是正确的,虽然可能会引起类型问题(由于不同数据类型共用同一内存位置),但语法上是合法的。

C) printf(“%d\n”, a);

这是错误的,因为 a 是一个联合体,不能直接作为 %d 的参数。你需要使用 a.i 来打印 int 类型的值,例如 printf("%d\n", a.i);。

D) n = a;

这是错误的,因为不能将一个联合体直接赋值给一个整数变量。需要使用 n = a.i;。

解答 :

B

1.18、以下程序在32位操作系统的运行结果是____________。

#include <stdio.h>

main( )

{

                  union{

                         long a;

                          int b;

                          char c;

               }m;

printf(“%d\n”,sizeof(m));

}

A) 2              B)4        C) 6              D)8

解析:

long 类型:在32位操作系统上,通常为4字节。

int 类型:在32位操作系统上,通常为4字节。

char 类型:大小为1字节。

由于联合体的大小取决于其最大成员的大小,且在32位系统上 long 和 int 的大小都是4字节,因此联合体 m 的大小将是4字节。

解答 :

B

1.19、以下程序的运行结果是____________

#include <stdio.h>

union pw

{

       int i;

       char ch[2];

}a;

main( )

{

            a.ch[0] = 13;

a.ch[1] = '0';

printf(“%d\n”,a.i);

}

A) 12301             B)4813         C) 208          D) 209

解析:

内存布局分析

a.ch[0] 被赋值为 13,其十六进制表示为 0x0D。

a.ch[1] 被赋值为字符 '0',其 ASCII 值为 48,十六进制表示为 0x30。

联合体的内存结构通常是按照小端字节序(little-endian)存储的:

a.ch[0](低位字节)存储在地址的低位,即 0x0D。

a.ch[1](高位字节)存储在地址的高位,即 0x30。

计算 a.i

在小端字节序下,a.i 的内存布局如下:

低位(ch[0]):0x0D (13)

高位(ch[1]):0x30 (48)

将这两个字节合并为一个整数 i:

a.i=0x30×256+0x0D=48×256+13=12288+13=12201

解答 :

A

1.20、下面对typedef的叙述中不正确的是____________

A) 用typedef可以定义各种类型名,但不能用来定义变量

B) 用typedef可以增加新类型

C) 用typedef只是将已存在的类型用一个新的标识符来代表

D) 使用typedef有利于程序的通用和移植

解析:

A) 用typedef可以定义各种类型名,但不能用来定义变量

正确。typedef 用于为现有类型创建别名,不能直接用于定义变量。

B) 用typedef可以增加新类型

不正确。typedef 不能创建新的数据类型,它只是为现有类型提供新的名称。

C) 用typedef只是将已存在的类型用一个新的标识符来代表

正确。typedef 创建的只是类型的别名,实际上没有创建新的类型。

D) 使用typedef有利于程序的通用和移植

正确。通过使用 typedef,可以使代码更易读并增强移植性,因为可以在不同的平台上使用不同的类型实现。

解答 :

B

1.21、下面程序在64位操作系统的运行结果是____________。

typedef union {  long a[2];

                                      int b[4];

                                      char c[8];

}TY;

TY our;

main()

{

            printf(“%d\n”,sizeof(our));

}

A) 32            B)16                    C) 8              D)24

解析:

在这个程序中,TY 是一个 union,其成员包括:

一个包含 2 个 long 类型元素的数组 a[2]。

一个包含 4 个 int 类型元素的数组 b[4]。

一个包含 8 个 char 类型元素的数组 c[8]。

union 的大小由其最大成员决定。在 64 位操作系统中:

一个 long 类型通常占用 8 字节,因此 a[2] 占用 16 字节。

一个 int 类型通常占用 4 字节,因此 b[4] 占用 16 字节。

一个 char 类型占用 1 字节,因此 c[8] 占用 8 字节。

因此,union TY 的大小取决于其最大成员 a[2],即 16 字节。因此,sizeof(our) 将返回 16。

解答 :

B

二、填空题

2.1、有结构体

 struct ST

{

           int a;

           float b;

           sturct ST *c;

           double x[3];

}st1;

请填空,完成以下对数组s的定义,使其每个元素均为上述结构体类型。

____________ s[10];   

解析:

要定义一个包含结构体 ST 类型元素的数组 s,需要将结构体 ST 的定义放在数组定义之前

解答 :

struct ST

2.2、 以下程序的运行结果是____________。

struct n

{  int x;

           char c;

};

main( )

{

           struct n a = {10,'x'};

           func(a);

           printf(“%d,%c”,a.x,a.c);

}

func(struct n b)

{

            b.x = 20;

            b.c = 'y';

}

解析:

没传地址,所以原变量不变

解答 :

10 x

2.3、以下程序的运行结果是_____

main()

{

           struct EXAMPLE

            {

                  struct{ int x;

                               int y;

                               }in;

                  int a;

                  int b;

            }e;

e.a = 1;  e.b = 2;

e.in.x = e.a*e.b;

e.in.y = e.a +e.b;

printf(“%d,%d”,e.in.x,e.in.y);

}

解析:

e.in.x 被赋值为 e.a 和 e.b 的乘积,即 1 * 2 = 2。

e.in.y 被赋值为 e.a 和 e.b 的和,即 1 + 2 = 3。

解答 :

2,3

2.4、 以下程序的输出结果是____________。

#include <stdio.h>

struct abc

{

          char c;

          float v;

};

void fun1(strcut abc b)

{

          b.c = 'A';

          b.v = 80.7;

}

void fun2(struct abc *b)

{

      (*b).c = 'C';

           (*b).v = 92.5;

}

int main()

{

    struct abc a = {'B',98.5};

          fun1(a);

          printf(“%c,%4.1f\n”,a.c,a.v);

          fun2(&a);

           printf(“%c,%4.1f\n”,a.c,a.v);

}

解析:

fun1是值传送,原变量不变,fun2是地址传送原变量发生改变

解答 :

B, 98.5
C, 92.5

2.8、若已定义:

struct num

{

          int a;

          int b;

          float f;

} n = {1,3,5.0}

struct num *pn = &n;

则表达式pn->b/n.a*++pn->b的值是1,表达式(*pn).a + pn->f的值是2

解析:

初始状态:

n.a = 1

n.b = 3

n.f = 5.0

pn 指向 n。

解析:

pn->b 当前值为 3。

n.a 的值为 1。

++pn->b 将 pn->b 先自增,然后使用新值。自增操作会使 n.b 从 3 变为 4。

因此:

pn->b 变为 4(自增后)。

pn->b / n.a 计算为 4 / 1 = 4。

最终表达式的值为 4 * 4 = 16。

2. 表达式 (*pn).a + pn->f

解析:

(*pn).a 是 n.a 的值,等于 1。

pn->f 是 n.f 的值,等于 5.0。

因此:

这个表达式计算为 1 + 5.0 = 6.0。

总结

第一个表达式 pn->b / n.a * ++pn->b 的值是 16。

第二个表达式 (*pn).a + pn->f 的值是 6.0。

解答 :

16,6.0

2.9、以下程序的运行结果是____________。

struct ks

{

          int a;

          int *b;

} s[4],*p;

main()

{

          int n = 1,i;

          printf(“\n”);

          for(i = 0;i < 4;i++)

           {

                  s[i].a = n;

                  s[i].b = &s[i].a;

                  n = n+2;

            }

p = &s[0];

p++;

printf(“%d,%d\n”,(++p)->a,     (p++)->a   )  ;

}

解析:

在 for 循环中:

s[0].a = 1

s[1].a = 3

s[2].a = 5

s[3].a = 7

对应的指针 b 均指向各自的 a 成员。 ++p 使 p 指向 s[2],然后访问 s[2].a 的值,即 5。

(p++)->a 先访问当前 p 指向的 s[2] 的 a 的值(即 5),然后 p 自增到 s[3]。

因此,printf 的输出将是:

第一个 %d 输出 5(来自 s[2].a)。

第二个 %d 输出 5(来自 s[2].a,因为 p++ 操作在这一步之后才改变 p 的指向)。

解答 :

5,5

2.10、以下程序的运行结果为____________

struct s

{

           int a;

           float b;

           char *c;

}

main( )

{

             static struct s x = {19,83.5,”zhang”};

             struct s *px = &x;

             printf(“%d%.1f%s\n”,x.a,x.b,x.c);

             printf(“%d%.1f%s\n”,px->a,(*px).b,px->c);

             printf(“%c%s\n”,*px->c-1,&px->c[1]);

}

解析:

第一个 printf 语句

x.a 输出 19。

x.b 输出 83.5,使用 .1f 格式输出,显示为 83.5。

x.c 输出字符串 "zhang"

第二个 printf 语句:

px->a 输出 19(和 x.a 一样)。

(*px).b 输出 83.5(和 x.b 一样)。

px->c 输出字符串 "zhang"(和 x.c 一样)

第三个 printf 语句

*px->c 访问的是 x.c 的第一个字符,即 'z',然后减去 1,得到字符 'y'。

&px->c[1] 指向字符串 "zhang" 的第二个字符,即 "hang"

解答 :

19 83.5zhang
19 83.5zhang
yhang

2.11、设有以下定义和语句,请在printf语句的【】中天上能够正确输出的变量及相应的格式说明。

union

{

            int n;

            double x;

}num;

num.n = 10;

num.x = 10.5;

printf(“1”,2);

解析:

输出 num.n

如果我们尝试输出 num.n,我们会得到一个未定义的结果,因为 num.x 被赋值为 10.5,并且 num.n 的值是不可预知的。

输出 num.x

输出 num.x 是有效的,因为 num.x 是最近赋值的成员。

解答 :

printf("%f", num.x);

2.12、以下程序的运行结果是____________。

main()

{

           struct EXAMPLE

            {

                  union

                  {

                        int x;

                        int y;

                   }in;

                 int a;

                 int b;

            }e;

            e.a = 1; e.b = 2;

            e.in.x = e.a *e.b;

            e.in.y = e.a +e.b;

            printf(“%d,%d”,e.in.x,e.in.y);

}

解析:

联合体的所有成员共享同一块内存,这意味着在联合体中赋值的最后一个成员会覆盖之前赋值的成员。

在这里,当我们执行 e.in.y = e.a + e.b; 时,由于 in 是一个联合体,e.in.y 的赋值将覆盖 e.in.x 的值。虽然 e.in.x 被赋值为 2,但在下一行代码中,e.in.y 被赋值为 3,此时 e.in.x 的值实际上是 3。

解答 :

3,3

2.13、以下程序的运行结果是____________。

union ks

{

             int a;

             int b;

};

union ks s[4];

union ks *p;

main( )

{

int n = 1,i;

printf(“\n”);

for(i = 0;i < 4;i++)

           {

                 s[i].a = n;

                 s[i].b = s[i].a + i;

                 n = n+2;

            }

p = &s[2];

printf(“%d,”,p++->a);

printf(“%d”,++p->a);

}

解析:

联合体数组初始化:

s[0]:

s[0].a = 1

s[0].b = 1 + 0 = 1(s[0].b 取值是 1,覆盖了 s[0].a)

s[1]:

s[1].a = 3

s[1].b = 3 + 1 = 4(s[1].b 取值是 4,覆盖了 s[1].a)

s[2]:

s[2].a = 5

s[2].b = 5 + 2 = 7(s[2].b 取值是 7,覆盖了 s[2].a)

s[3]:

s[3].a = 7

s[3].b = 7 + 3 = 10(s[3].b 取值是 10,覆盖了 s[3].a)

最终状态:

s[0]:a = 1, b = 1

s[1]:a = 4, b = 4

s[2]:a = 7, b = 7

s[3]:a = 10, b = 10

指针操作:

p = &s[2];,指向 s[2](p->a 为 7)。

解答 :

7,11

2.14、以下程序的运行结果是____________

main( )

{

            union EXAMPLE

              {

                  struct

                        {

                             int x;

                             int y;

                         }in

                    int a;

                    int b;

               }e;

e.a = 1;

e.b = 2;

e.in.x = e.a * e.b;

e.in.y = e.a +e.b;

printf(“%d %d”,e.in.x,e.in.y);

}

解析:

定义和初始化联合体:

联合体 EXAMPLE 中有一个结构体 in,包含两个整数 x 和 y,以及两个整数 a 和 b。

由于这是一个联合体,a、b、in.x 和 in.y 共用同一块内存。

赋值操作:

e.a = 1;:设置 e.a 为 1。此时 e.b 和结构体成员 in 的内容不确定,因为联合体的成员共享内存。

e.b = 2;:设置 e.b 为 2。由于 a 和 b 是联合体的成员,所以此时 e.a 的值可能会被覆盖,但在这一点上我们关注的是后面的计算。

e.in.x = e.a * e.b;:这里的计算中,e.a 和 e.b 的值都分别为 1 和 2。所以 e.in.x 的值为 1 * 2 = 2。

e.in.y = e.a + e.b;:这里的计算中,e.a 和 e.b 的值都分别为 1 和 2。所以 e.in.y 的值为 1 + 2 = 3。

联合体内存重用:

由于 in 结构体和 a、b 共享内存,后面的赋值可能会影响值。在这个过程中,in.x 和 in.y 被赋值,但实际上因为是联合体,只有最后一个写入的值有效。即使我们在赋值之前对 e.a 和 e.b 进行了操作,实际上 e.in.y 在这里并不会被赋值为 3,而是被 e.in.x 所覆盖。

打印输出:

printf("%d %d", e.in.x, e.in.y); 在这里可能会输出 4 和 8,原因在于内存共享导致后面的值覆盖了之前的值。

最后,由于 in.x 和 in.y 共享内存,它们最终可能会取到我们未预见的值(具体依赖于编译器、内存对齐等)。

解答 :

4,8

2.15、以下程序的运行结果为____________。

#include <stdio.h>

struct w

{

           char low;

           char high;

};

union u

{

           struct w byte;

           int word;

}uu;

int  main( )

{

            uu.word = 0x1234;

            printf(“Word value:%04x\n”,uu.word);

            printf(“High value:%02x\n”,uu.byte.high);

            printf(“Low value:%02x\n”,uu.byte.low);

            uu.byte.low = oxff;

             printf(“Word value: %04x\n”,uu.word);

}

解析:

联合体的定义:

struct w 定义了一个结构体,包含两个 char 类型的成员 low 和 high。

union u 定义了一个联合体,包含 struct w 和一个 int 类型的 word。联合体的所有成员共享同一块内存。

将值赋给联合体

uu.word = 0x1234; 将 0x1234(十六进制数,等于4660)存入联合体的 word 成员。

在大端字节序(big-endian)系统中,0x1234 将存储为:

high: 0x12

low: 0x34

打印输出:

printf("Word value:%04x\n", uu.word); 输出 Word value:1234。

printf("High value:%02x\n", uu.byte.high); 输出高字节,结果为 12。

printf("Low value:%02x\n", uu.byte.low); 输出低字节,结果为 34。

修改低字节:

uu.byte.low = 0xff; 将联合体中的低字节设置为 0xff。在内存中,word 的值将被更新为:

高字节仍然为 0x12,低字节现在为 0xff。

所以现在 word 的值为 0x12ff。

最后输出:

printf("Word value: %04x\n", uu.word); 输出 Word value:12ff。

解答 :

1234
12
34
12ff

2.16、以下程序的输出结果为____________

enum coin{ penny, nickel, dime, quarter,  half_dollar, dollar };

char *name[] =

 {“penny”,”nickel”,”dime”,”quarter”,”half_dollar”,”dollar”};

main( )

{

            enum coin money1,money2;

money1 = dime;

money2 = dollar;

printf(“%d %d\n”,meney1,money2)

printf(“%s %s\n”,name[(int)money1],name[(int)money2]);

}

解析:

枚举类型定义

在这里定义了一个枚举类型 coin,枚举的值分别是:

penny = 0

nickel = 1

dime = 2

quarter = 3

half_dollar = 4

dollar = 5

字符指针数组定义

这里定义了一个字符指针数组 name,用于存储对应的枚举名称。

枚举变量赋值

将 money1 设置为 dime,值为 2;将 money2 设置为 dollar,值为 5

打印输出

输出 money1 和 money2 的整数值,结果为 2 5

访问字符串数组

name[(int)money1]:(int)money1 的值是 2,因此输出 name[2],对应的字符串为 "dime"。

name[(int)money2]:(int)money2 的值是 5,因此输出 name[5],对应的字符串为 "dollar"。

解答 :

2 5
dime dollar
 

2.17、以下程序的输出结果是____________。

#include <stdio.h>

typedef   int   INT;

int  main()

{

   INT a,b;

   a = 5;

         b = 6;

        printf("a = %d\tb = %d\n",a,b);

         {

          float   INT;

           INT = 3.0;

          printf("2*INT = %.2f\n",2*INT);

         }

}

解析:

类型定义:

typedef int INT;

使用 typedef 定义了一个新类型 INT,它是 int 的别名。因此,在程序中使用 INT 等价于使用 int。

变量声明和赋值:

INT a, b;

a = 5; 

b = 6;

这里定义了两个 INT 类型的变量 a 和 b,并将它们赋值为 5 和 6。

打印变量值:

printf("a = %d\tb = %d\n", a, b); 

输出为:

a = 5 b = 6

进入新作用域:

float INT; 

INT = 3.0; 

在这个新作用域中,INT 被重新定义为 float 类型。这会遮蔽前面的 typedef 定义,所以在这个作用域中 INT 不再是 int 的别名,而是一个 float 类型的变量。

计算并打印:

printf("2*INT = %.2f\n", 2 * INT); // 计算 2 * INT 的值,并打印

这里 INT 是 float 类型,并且被赋值为 3.0。因此,2 * INT 的计算结果是 6.0。输出为:

2*INT = 6.00

解答 :

a = 5      b = 6
2*INT = 6.00
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1556561.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Java中TreeMap,HashMap和LinkedHashMap的区别

先决条件&#xff1a;Java 中的 HashMap 和 TreeMap TreeMap、HashMap 和 LinkedHashMap&#xff1a;有什么相似之处&#xff1f; 所有类都提供键->值映射和遍历键的方法。这些类之间最重要的区别是时间保证和键的顺序。 HashMap、TreeMap 和LinkedHashMap三个类都实现了…

【数据结构】【队列】算法汇总

一、顺序队列【相当于一维数组】 1.准备工作 #define MAXQSIZE 100 typedef struct{QElemType*base;int front;int rear; }SqQueue; 2.队满&#xff0c;队空。入队&#xff0c;出队 二、链式队列 1.准备工作 typedef struct Qnode{ElemType data;struct Qnode*next; }Qnod…

Github优质项目推荐 - 第五期

文章目录 Github优质项目推荐 - 第五期一、【localsend】&#xff0c;47.5k stars - 附近设备文件互传二、【Pake】&#xff0c;29.9k stars - 网页变成桌面应用三、【laravel-crm】&#xff0c;10.7k stars - CRM 解决方案四、【localstack】&#xff0c;55.7k stars - 本地 A…

RabbitMQ(学习前言)

目录 学习MQ之前有必要先去温故下微服务知识体系&#xff0c;以加深本章节的理解 一、微服务间的通讯方式 1. 基本介绍 2. 同步通讯 2.1. 什么是同步通讯 2.2. 同步通讯存在的问题 问题一&#xff1a;耦合度高 问题二&#xff1a;性能和吞吐能力下降 问题三&#xff1a…

时序必读论文16|ICLR24 CARD:通道对齐鲁棒混合时序预测Transformer

论文标题&#xff1a;CARD: Channel Aligned Robust Blend Transformer for Time Series Forecasting 论文链接&#xff1a;https://arxiv.org/abs/2305.12095 代码链接&#xff1a;https://github.com/wxie9/CARD 前言 Transformer取得成功的一个关键因素是通道独立&#…

SpringBoot框架下旅游管理系统的创新设计与实现

第二章 相关技术简介 2.1 JAVA技术 本次系统开发采用的是面向对象的Java作为软件编程语言&#xff0c;Java表面上很像C&#xff0c;但是Java仅仅是继承了C的某些优点&#xff0c;程序员很少使用的C语言的特征在Java设计中去掉了。Java编程语言并没有什么结构&#xff0c;它把数…

Arduino UNO R3自学笔记21 之 Arduino电机的闭环控制(PID)

注意&#xff1a;学习和写作过程中&#xff0c;部分资料搜集于互联网&#xff0c;如有侵权请联系删除。 前言&#xff1a;上篇写了电机速度测定&#xff0c;这篇主要是讲测定出的速度用于反馈&#xff0c;使得实际速度快速响应到需要的速度。 1.控制系统介绍 分2大类&#x…

​​​​​​​如何使用Immersity AI将图片转换成3D效果视频

随着技术的进步&#xff0c;图片处理变得越来越强大和直观。借助Immersity AI这样的工具&#xff0c;我们现在可以轻松地将平面图片转换成3D效果视频。以下是如何使用Immersity AI进行这一转换的详细步骤。 第一步&#xff1a;访问Immersity AI网站 首先&#xff0c;打开你的…

Spring开发最佳实践之跨域处理

1. 跨域处理 1.1 异常现象 1.2 异常原因分析 跨源资源共享的官方定义如下&#xff1a; 跨源资源共享&#xff08;CORS&#xff0c;Cross Origin Resource Sharing。或通俗地译为跨域资源共享&#xff09;是一种基于 HTTP 头的机制&#xff0c;该机制通过允许服务器标示除了它自…

在mac中通过ip连接打印机并实现双面打印

首先需要找到电脑自带的打印。添加打印机。 填写好打印机的ip地址&#xff0c;然后添加。 填写好ip地址后&#xff0c;直接添加就行 添加完打印机后其实就可以打印了。但是有些功能可能实现不了&#xff0c;比如说双面打印。为了实现双面打印的功能&#xff0c;需要再进行设置…

Vue83 引入elementUI

笔记 安装插件 安装按需引入插件 代码 ### App.vue <template><div><button>原生的按钮</button><input type"text"><atguigu-row><atguigu-button>默认按钮</atguigu-button><atguigu-button type"pr…

Arduino UNO R3自学笔记22 之 Arduino基础篇学习总结

注意&#xff1a;学习和写作过程中&#xff0c;部分资料搜集于互联网&#xff0c;如有侵权请联系删除。 前言&#xff1a;目前将Arduino的大多数基础内容学习了&#xff0c;做个总结。 1.编程语言 学习单片机&#xff0c;在面向单片机编程时&#xff0c;语言是最基础的&#…

localhost与127.0.0.1傻傻分不清楚,区别详解来了

对应程序员来说&#xff0c;localhost和127.0.0.1经常使用&#xff0c;但是却又傻傻分不清楚&#xff01;尽管它们在实际应用中经常互换使用&#xff0c;但它们之间确实存在一些细微的差别。本文我将详细探讨localhost与127.0.0.1的区别。 一、定义与解析方式 localhost 定…

SSM外卖点餐软件APP-计算机毕业设计源码30768

目 录 摘要 1 绪论 1.1 研究背景 1.2研究目的 1.3论文结构与章节安排 2 外卖点餐软件APP系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 操作可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能…

旅游管理自动化:SpringBoot系统设计与实现

第二章 相关技术简介 2.1 JAVA技术 本次系统开发采用的是面向对象的Java作为软件编程语言&#xff0c;Java表面上很像C&#xff0c;但是Java仅仅是继承了C的某些优点&#xff0c;程序员很少使用的C语言的特征在Java设计中去掉了。Java编程语言并没有什么结构&#xff0c;它把数…

【爬虫】网站反debugger、内存爆破以及网站限制开发者工具

【爬虫】网站反debugger、内存爆破以及网站直接限制开发者工具 声明&#xff1a;本文中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0…

就业市场需求分析:基于前程无忧岗位数据分析

背景介绍&#xff1a;在前程无忧网站&#xff0c;以"数据分析师""武汉"作为搜索关键词&#xff0c;爬取50页岗位数据合计980条。以该数据为基础&#xff0c;从岗位搜索匹配度、HR活跃度、不同区域/行业/企业的岗位数量和薪资分布等角度进行分析。 1、原始数…

电商平台数据批量获取自动抓取的实现方法分享(API)

电商竞争白热化的今天&#xff0c;一个电商卖家往往会在多个平台铺设店铺来获取更多的客户。有没有什么高效的电商数据采集工具可以整合多个店铺的数据呢。 在这里给大家推荐使用API&#xff0c;完成主流电商平台数据采集、ERP、OA等业务系统数据采集、行业数据采集。 API取数…

UE5 武器IK瞄准系统

创建空项目 创建基础蓝图类My_GameMode,My_HUD,My_PlayChar,My_PlayController 项目设置地图模式 近裁平面 0.1 My_PlayChar蓝图中添加摄像机,角色骨骼网格体,武器骨骼网格体 编辑角色骨骼,预览控制器使用特定动画,动画选择ANM_ark-47-Idle hand_r 添加插槽WeaponMes…

​​​​​​​如何使用Hugging Face上的FacePoke工具调整照片中人的头部位置

在照片处理中&#xff0c;调整人物的头部位置可以为你带来创意无限的效果。借助Hugging Face上的FacePoke工具&#xff0c;这一操作变得前所未有的简单和高效。以下是详细步骤&#xff0c;教你如何使用FacePoke来调整照片中人的头部位置。 第一步&#xff1a;访问FacePoke工具…