day8嵌入式(2022.1.14)

简介: day8嵌入式(2022.1.14)

1.指针实际应用4:多级指针的使用


如果需要修改指针本身的指向,那么在函数传参时,必须使用地址传递。


相关代码参考demo1_二级指针的应用.c


2.指针实际应用5:空指针、野指针介绍


空指针:


指向NULL地址(0x00000000)的指针。(该块内存为不可访问区,如强行访问将导致段错误。)


Segmentation fault (core dumped)



备注:


  1. 段错误不属于语法错误,编译器是不会提示的。


出现原因:一般原因是非法内存操作(访问不可访问区域,访问越界,内存溢出。。。)


解决办法:可在关键位置添加打印语句,找出错误出现的代码行


printf("[%d]\n", __LINE__);


野指针:


指向不明确的指针,任意使用有可能导致不可预料的错误。


备注:


定义一个指针后,最后是立即对其进行指向。


如果暂时没有明确指向,可直接指向NULL。(至少不会修改宝贵数据,数据是无价的。)


3.指针实际应用6:字符串操作函数


#include <string.h>


1.strlen :计算字符串长度


size_t strlen(const char *s);


2.strcmp :比较字符串s1和s2(相同返回0,不同返回非0)


int strcmp(const char *s1, const char *s2);


3.strcpy :将源字符串src复制到目标字符串dest


char *strcpy(char *dest, const char *src);


4.strcat :将源字符串src拼接到目标字符串dest之后。


char *strcat(char *dest, const char *src);


指针习题


1 、设有定义: int a,*pa=&a; 以下 scanf 语句中能正确为变量 a 读入数据的是()


A) scanf("%d", pa); B) scanf("%d", a);


C) scanf("%d", &pa); D) scanf("%d", *pa);


2 、若有以下定义和语句


int main()
{
int a=4, b=3, *p, *q, *w;
p=&a; q=&b; w=p; q=NULL;
}


则以下选项中错误的语句是()


A) *q=0; B) w=p; C) *p=a; D) *p=*w;


3 、有以下程序


int main()
{
int a=7, b=8, *p, *q, *r;
p=&a; q=&b;
r=p; p=q; q=r;
printf("%d,%d,%d,%d\n", *p, *q, a, b);
}


程序运行以后的输出结果是 ()


A) 8,7,8,7 B) 7,8,7,8


C) 8,7,7,8 D) 7,8,8,7


4 、程序中对 fun 函数有如下说明


void *fun();


此说明的含义是 ( )


A) fun 函数无返回值


B) fun 函数的返回值可以是任意的数据类型


C) fun 函数的返回值是无值型的指针类型


D) 指针 fun 指向一个函数,该函数无返回值


5 、有以下程序


int *f(int *x,int *y)
{
if(*x<*y) return x;
else return y; }
main()
{
int a=7, b=8, *p, *q, *r;
p=&a; q=&b;
r=f(p,q);
printf("%d,%d,%d\n", *p, *q, *r);
}


执行后输出结果是 ( )


A) 7,8,8 B) 7,8,7 C) 8,7,7 D) 8,7,8


6 、设有定义语句


int x[6]={2,4,6,8,5,7}, *p=x, i;


要求依次输出 x 数组 6 个元素中的值,不能完成此操作的语句是 ()


A) for(i=0;i<6;i++) printf("%2d",*(p++));


B) for(i=0;i<6;i++) printf("%2d",*(p+i));


C) for(i=0;i<6;i++) printf("%2d",*p++);


D) for(i=0;i<6;i++) printf("%2d", (*p)++);


备注: (D) 中 (*p)++ 是元素值加 1 ,而不是指针值加 1


7 、有以下程序


main()
{
int x[8]={8,7,6,5,0,0}, *s;
s=x+3;
printf("%d\n", s[2]);
}


执行后的输出结果是 ( )


A) 随机值 B) 0 C) 5 D) 6


8 、有以下程序段


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


b=p[5];


b 中的值是 ( )


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


9 、有以下程序


void fun(int *a,int i,int j)
{
int t; if(i<j){
t=a[i]; a[i]=a[j]; a[j]=t; fun(a,++i,--j);
}
}
main()
{
int a[]={1,2,3,4,5,6}, i;
fun(a,0,5);
for(i=0; i<6; i++)
printf("%d", a[i]);
}


执行后的输出结果是 ( )


A) 6 5 4 3 2 1 B) 4 3 2 1 5 6


C) 4 5 6 1 2 3 D) 1 2 3 4 5 6


10 、有以下程序


void swap1(int c0[], int c1[])
{
int t;
t=c0[0]; c0[0]=c1[0]; c1[0]=t;
}
void swap2(int *c0, int *c1)
{
int t;
t=*c0; *c0=*c1; *c1=t;
}
main()
{
int a[2]={3,5}, b[2]={3,5};
swap1(a, a+1); swap2(&b[0], &b[1]);
printf("%d %d %d %d\n", a[0], a[1], b[0], b[1]);
}


A ) 3 5 5 3 B ) 5 3 3 5


C ) 3 5 3 5 D ) 5 3 5 3


11 、有以下程序


main() // 指向包含 3 个元素的一维数组的指针变量
{
int a[][3]={{1,2,3},{4,5,0}}, (*pa)[3], i;
pa=a;
for(i=0; i<3; i++) {
if(i<2) pa[1][i]=pa[1][i]-1;
else pa[1][i]=1;
}
printf("%d\n", a[0][1]+a[1][1]+a[1][2]);
}


执行后输出结果是 ( )


A) 7 B) 6 C) 8 D) 无确定值


12 、若有以下说明和语句:


int c[4][5], (*p)[5];


p=c;


能正确引用 c 数组元素的是 ( )


A) p+1 B) *(p+3) C) *(p+1)+3 D) *(p[0]+2)


13 、有以下程序


main()
{
int a[3][3], *p, i;
p=&a[0][0];
for(i=0;i<9;i++)
p[i]=i+1;
printf("%d\n", a[1][2]);
}


程序执行以后的输出结果是 ( )


A) 3 B) 6 C) 9 D) 7


14 、有以下程序


main()
{
char s[]="Yes\n/No", *ps=s;
puts(ps+4);
*(ps+4)=0;
puts(s);
}


程序运行后的输出结果是 ( )


A) n/No B) /No C) n/No D) /No


Yes Yes Yes /No


/No /No Yes


15 、有以下程序


main()
{
char str[][20]={"Hello", "Beijing"}, *p=str[0];
printf("%d\n", strlen(p+20));
}


程序运行后的输出结果是 ( )


A) 0 B) 5 C) 7 D) 20


16 、有以下程序


main()
{
char s[]="ABCD", *p;
for(p=s+1; p<s+4; p++)
printf("%s\n", p);
}


程序运行后的输出结果是 ( )


17 、以下程序运行后的输出结果是 ( )


main()
{
char a[]="Language", b[]="Programe";
char *p1,*p2; int k;
p1=a; p2=b;
for(k=0; k<8; k++)
if(*(p1+k)==*(p2+k))
printf("%c", *(p1+k));
}


18 、有以下程序


main()
{
char *p[10]={"abc", "aabdfg", "dcdbe", "abbd", "cd"};
printf("%d\n", strlen(p[4]));
}


执行后输出结果是 ()


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


19 、若有定义: int *p[3]; ,则以下叙述中正确的是 ()


A) 定义了一个基类型为 int 的指针变量 p ,该变量具有 3 个指针。


B) 定义了一个指针数组 p ,该数组含有 3 个元素,每个元素都是基类型为 int

的指针。


C) 定义了一个名为 *p 的整型数组,该数组含有 3 个 int 类型元素。


D) 定义了一个可指向一维数组的指针变量 p ,所指一维数组应具有 3 个 int 类

型元素。


指针习题答案:


1~5:  AACCB


6~10:  DBDAD


11~15: ADBBC


16:


BCD


CD


D


17:gae


18: 2


19: B


选A。


int a, *pa=&a;


// 指针pa指向变量a


scanf中的%d,表示需要输入数据到整型变量中。


(int *)


A) scanf("%d", pa); // int *,正确


B) scanf("%d", a); // int,类型不匹配


C) scanf("%d", &pa); // int **,类型不匹配


D) scanf("%d", *pa); // int,类型不匹配


2.选A


    int a=4, b=3, *p, *q, *w;
    p=&a;   // p -> a
    q=&b;   // q -> b
    w=p;    // w -> a
    q=NULL; // q -> NULL


A) *q=0; // 错误。访问了不可访问区域


B) w=p; // 正确。因指针p存储了a地址,使指针w指向a


C)*p=a; // 正确。a = a


D) *p=*w; // 正确。a = a


3.选C


    int a=7, b=8, *p, *q, *r;
    p=&a;   // p -> a
    q=&b;   // q -> b
    r=p;    // r -> a
    p=q;    // p -> b
    q=r;    // q -> a
    printf("%d,%d,%d,%d\n", *p, *q, a, b);


4.选C



返回值为void *的函数(指针函数)


A) fun 函数无返回值 //错误,void fun();


B) fun 函数的返回值可以是任意的数据类型 // 错误,只能是任意的指针类型。


C) fun 函数的返回值是无值型的指针类型(任意类型的指针)


D)指针 fun 指向一个函数,该函数无返回值 // 错误。不是指针。void (*fun)(void)


5. 选B


    int a=7, b=8, *p, *q, *r;
    p=&a;   // p -> a
    q=&b;   // q -> b
    r=f(p,q);   // 地址传递(返回最小值的地址) r -> a
    printf("%d,%d,%d\n", *p, *q, *r);


6. 选D


A)for(i=0;i<6;i++)  printf("%2d",*(p++)); // ++优先级高于*,与C相同


B) for(i=0;i<6;i++)  printf("%2d",*(p+i)); // 与AC不同,指针p本身不偏移。


C) for(i=0;i<6;i++)  printf("%2d",*p++);


D) for(i=0;i<6;i++)  printf("%2d", (*p)++); // 错误。因为操作元素值++


p++ =>   p=p+1; p+=1;


7.选B


    int x[8]={8,7,6,5,0,0}, *s;
    s=x+3;  // s -> 数据5
    printf("%d\n", s[2]);   // s[2]=*(s+2)


8.选D


    // p -> 数据4
    int a[10]={1,2,3,4,5,6,7,8,9,10}, *p=&a[3], b;
    b=p[5]; // *(p+5)   数据9


9.选A


//  1:   &a[0]    0     5
//  2:   &a[0]    1     4
//  3:   &a[0]    2     3
//  4:   &a[0]    3     2
void fun(int *a,int i,int j)
{  
    int t;
    // 1:0<5    ,逻辑真,成立
    // 2:1<4    ,逻辑真,成立
    // 3:2<3    ,逻辑真,成立
    // 4:3<2    ,逻辑假,不成立
    if(i<j)
    {
        t=a[i];
        a[i]=a[j];
        a[j]=t;
        // 1:6 2 3 4 5 1
        // 2:6 5 3 4 2 1
        // 3:6 5 4 3 2 1
        fun(a,++i,--j);
        // 1: &a[0] 1 4
        // 2: &a[0] 2 3
        // 3: &a[0] 3 2
    }
}
main()
{  
    //       0 1 2 3 4 5
    int a[]={1,2,3,4,5,6}, i;
    fun(a, 0, 5);
    for(i=0; i<6; i++)  
        printf("%d", a[i]);
}


10.选D


swap1(a, a+1);


swap2(&b[0], &b[1]);


上述函数都是地址传递。


11,选A


    //              2     +  4    +  1
    printf("%d\n", a[0][1]+a[1][1]+a[1][2]);


12,选D


int c[4][5], (*p)[5];


p=c; // p -> c第1个子数组


能正确引用c数组int元素的是(  )


A) p+1     // 数组地址


B) *(p+3)  // 数组首元素地址


C) *(p+1)+3    // int元素地址


D) *(p[0]+2)  //  p[0][2]能够成功访问int


13,选B


//    0 1 2
//0:  1 2 3
//1:  4 5 <6>
//2:  7 8 9 


14,选B


    // 指针s指向字符串常量(位于只读区),不可写入。
    // char *s="Yes\n/No", *ps=s;
    // 数组s存储着字符串(合法内存,可读可写)
    //                                                  ps+4
    char s[]="Yes\n/No", *ps=s;     // 'Y' 'e' 's' '\n' '\0' 'N' 'o' '\0'(字符串结束符)
    printf("sizeof: %ld\n", sizeof(s));
    printf("strlen: %ld\n", strlen(s));
    puts(ps+4);     // printf("%s\n");
    *(ps+4)=0;  // 将 '/' 修改为 '\0'
    puts(s);        // printf("%s\n");


15,选C


    //              char [20]   char [20]
    char str[][20]={"Hello", "Beijing"}, *p=str[0]; // str[0]->*str
    // p -> 'H'


16,输出:


BCD


CD


D



17.输出:gae


    char a[]="Language", b[]="Programe";
    char *p1, *p2;  
    int k;
    p1=a;   // p1 -> 'L'
    p2=b;   // p2 -> 'P'
    // "Language"
    // "Programe"
    for(k=0; k<8; k++)  // 0~7
        if(*(p1+k)==*(p2+k))  // if(a[k] == b[k])
            printf("%c", *(p1+k));  // gae


18,选A


    // 指针数组   p[0]      p[1]    p[2]     p[3]   p[4]
    char *p[10]={"abc", "aabdfg", "dcdbe", "abbd", "cd"};
    printf("%d\n", strlen(p[4]));   *(p+4)


19.选B


int *p[3]; // 数组,长度为3,元素类型 int *


A) 定义了一个基类型为int的指针变量p,该变量具有3个指针。


B) 定义了一个指针数组p,该数组含有3个元素,每个元素都是基类型为int的指针。


C) 定义了一个名为*p的整型数组,该数组含有3个int类型元素。


D) 定义了一个可指向一维数组的指针变量p,所指一维数组应具有3个int类型元素。 ---> int (*p)[3]


demo1_二级指针的应用


#include<stdio.h>
// 值传递(传递的是指针指向数据地址)
void func_1(int *p)
{
  p += 2; //p1 = p1+2;
  printf("func_1: p: %d\n", *p);
}
// 地址传递(传递的是指针本身的地址)
// void func_2(int *(*p))
void func_2(int **p)  // 也称为二级指针
{
  *p += 2;
}
int main()
{
  int arr[5] = {1, 3, 5, 7, 9};
  int *p1 = arr;  // 指针p1指向数据1
  printf("p1: %d\n", *p1);
  // func_1(p1);    // 传递arr[0](数据1)地址
  func_2(&p1);    // 传递指针p1本身的地址
  printf("p1: %d\n", *p1);
  return 0;
}


demo2_空指针和野指针


#include<stdio.h>
int main()
{
  int *p1 = NULL;
  // printf("%d\n", *p1);
  int arr[5] = {1, 3, 5, 7, 9};
printf("[%d]\n", __LINE__);
  arr[454554654646546] = 100;   // 问题出现在这里
printf("[%d]\n", __LINE__);
  printf("%d\n", arr[454554654646546]);
printf("[%d]\n", __LINE__);
  int a;    // 随机值
  int *p1;  // 野指针,也是随机值(可能是任意数据地址)
  // *p1 = xxxx;    // 随意访问可能导致出现问题。
  return 0;
}


demo3_字符串操作函数


#include <stdio.h>
#include <string.h>
int main()
{
//1.  strlen    :计算字符串长度
  char *str1 = "hello"; // 最后有结束符'\0'
  // printf("str1: %ld\n", sizeof(str1));   //错误,计算的是指针的大小
  printf("str1: %ld\n", strlen(str1));
// 2. strcmp    :比较字符串s1和s2
  // char *str2;    // 野指针,不能写入内容
  // char str2[10] = {0}; // 清零数组
  char str2[10];  // 暂时为随机值
  bzero(str2, sizeof(str2));  // 清零数组
  scanf("%s", str2);    //(输入字符串不能大于10字节)
  if(strcmp(str1, str2) == 0)
    printf("Same!\n");
  else
    printf("Diffrent!\n");
//3.  strcpy    :将源字符串src复制到目标字符串dest
  char str3[10] = {0};
  strcpy(str3, str2);
  printf("str3: %s\n", str2);
// 4. strcat      :将源字符串src拼接到目标字符串dest之后。
  char str4[10] = "123";
  strcat(str4, str3);
  printf("str4: %s\n", str4);
  return 0;
}


demo4_用户名判断


#include <stdio.h>
#include <string.h>
int main()
{
  char str1[10];
  // bzero(str1, strlen(str1)); // str1中还没有数据,长度为0
  bzero(str1, sizeof(str1));  
  scanf("%s", str1);
  // char *str2 = "hello,"; // 错误的。str2指针指向字符串常量,不允许修改
  char str2[20] = "hello,"; // 正确的。str2是数组,合法内存,可以存入数据。
  if(strcmp(str1, "Tom") == 0)
  {
    strcat(str2, str1);
    printf("str2: %s\n", str2);
  }
  else
  {
    printf("ERROR\n");
  }
  return 0;
}


demo5_习题讲解


#include <stdio.h>
#include <string.h>
main()
{   
  // 指针数组   p[0]    p[1]  p[2]   p[3] p[4]
  char *p[10]={"abc", "aabdfg", "dcdbe", "abbd", "cd"};
  printf("%d\n", strlen(p[4])); *(p+4)
}
相关文章
|
6月前
|
机器学习/深度学习 人工智能 安全
嵌入式会越来越卷吗?
嵌入式系统,融合硬件与软件,正以前所未有的速度普及和多样化。从智能手机到医疗保健,它们无处不在,推动着技术边界不断扩展。随着AI和IoT的发展,嵌入式系统变得更智能、高效。然而,技术进步也带来了安全挑战,数据保护和系统稳定性成为重要议题。未来,嵌入式系统将在物联网中扮演关键角色,同时教育和跨领域合作将塑造其发展路径。面对挑战,我们需要创新与合作,确保其健康且持续的进步。
|
5月前
|
C语言
嵌入式程设
嵌入式程设
|
传感器 人工智能 安全
有什么是嵌入式不能满足的?
从20世纪60年代开始,嵌入式系统就已经开始出现,当时主要应用于航空航天、国防、工业自动化等领域
|
存储
day7嵌入式(2022.1.13)
day7嵌入式(2022.1.13)
|
Linux Windows
day9嵌入式(2022.1.15)
day9嵌入式(2022.1.15)
|
机器学习/深度学习 C语言
嵌入式day5(2022.1.11)
嵌入式day5(2022.1.11)
|
C语言
嵌入式day4(2022.1.10)
嵌入式day4(2022.1.10)
|
自然语言处理 编译器 C语言
day11嵌入式(2022.1.17)
day11嵌入式(2022.1.17)
嵌入式C++(四)
嵌入式C++(四)
嵌入式C++(四)