c易错题集------指针

六、指针

通过函数指针调用函数,函数指针指向的函数要和调用函数的返回值、参数一致

ps:void fun(int *x , int *y)

void(*p)( int *,int *)

1.以下程序的输出结果是 efgh

#include <stdio.h>
int main()
{
    char *p = "abcdefgh";
	char *r = NULL;
    long *q = NULL;
    q = (long*)p;
    q++;//加减其指向的类型单元长度
    r = (char*)q;
    printf("%s",r );
	return 0;
}//如果是32位机器则long占四字节,输出efgh;如果是64位机器则long占8字节,无输出
long double	8010/96128010/12816)	有效位10字节。32位为了对齐实际分配12字节;64位分配16字节

2.以下程序 段错误

int main()
{
    char* p = "abcdef";
    printf("%c", *(p + 2));
    p += 2;
    *p = 'm';//段错误
    printf("%c\n", *p);
}
//const修饰的内容不能改
const char *p等价于char const *p
   常量指针,本质上是一个指针,指向的内容不能改。
    
    char* const p;
指针常量,本质上是一个常量,这个常量是指针。
    //指针的指向不能修改

3.以下程序 D

#include <stdio.h>
int main()
{
    char *s = "abcdefgh";
	s = s + 2;
	printf("%ld\n",s);//输出错误
    //地址输出应该是%p
    //scanf输入时%lf代表double型
    //printf输出double用%f
}
A cde				B 字符c的ASCLL码值
C 字符c的地址		 D 出错

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mue4PMti-1615088362246)(C:\Users\zjc\Desktop\scanf.png)]

除了对double类型,其他printf都是一样的

4.以下程序运行的结果 C

#include <stdio.h>
void fun(int* a,int* b)
{
    int* k;//野指针,可能出现段错误
    k = a;
    a = b;
    b = k;//只是改变了形参指针的值
	//printf("%d %d", *a, *b);
}
int main()
{
    int a = 3, b = 6, * x = &a, * y = &b;
    fun(x, y);
    printf("%d %d", a, b);
}
A 6 3						B 3 6
C 编译出错					D 0 0

5.正确的指针交换函数

 void swap(int *p1, int *p2)
     {
         int t;//注意不能定义为*t,一是容易野指针,
     //也不能直接int *t = NULL,这样就无法操作*t
         t = *p1;
         *p1 = *p2;
         *p2 = t;
     }
	//通过指针扩展了a、b局部变量的作用域
	int main()
    {
        int a = 5;
        int b = 6;
        printf("a=%d b=%d\n", a, b);
        swap(&a, &b);
        printf("a=%d b=%d\n", a, b);
    }	

6.若指针p已经正确定义,要使得p指向两个连续的整型动态存储单元,不正确的是AC

A p=2*(int*)malloc(sizeof(int));//两个不同类型相乘会出错
B p=(int*)malloc(2*sizeof(int));
//用来动态分配一块size字节大小的堆空间,并且通过返回值返回该空间的首地址,该空间地址是连续的
		 void *malloc(size_t size);
		 //void *通用指针
   		 void free(void *ptr);

C p=(int*)malloc(2*2);//int为4字节
D p=(int*)calloc(2,sizeof(int));
//功能类似与malloc,只不过它是分配一块nmemb*size个字节大小的空间,该空间地址是连续的,calloc		   
//分配的空间会被全部置0
   		 void *calloc(size_t nmemb, size_t size);

7.若有以下定义和语句,对于数组正确引用形式C

int s[4][5],(*ps)[5];//严谨点应该(*ps)[5]=NULL
ps = s;
//数组名可以看成常量指针  s == &s[0]
//s+1,  &s[0]我们说s指向s[0],+sizeof(s[0])
A &s[1]第一行元素的首地址,从0行开始
//B s[3] 代表第四行元素
//D s[1]+3  &s[1][3]
//s[1]:&s[1][0],我们就说s[1]指向s[1][0]	
					+3*sizeof(s[1][0])

A PS+1 B *(PS+3)

C PS[0] [2] D *(PS+1)+3

&s代表整个二维数组的首地址&s[0] [0]

*( * (s+1) + 2) 代表元素a[1] [2] //看成二级指针

8.从键盘输入abc f<回车> 以下程序输出结果 ff

int main()
{
    char* p = NULL, * q = NULL;
    p = (char*)malloc(sizeof(char) * 20);
    q = p;
    scanf("%s%s", p, q);//scanf遇到空格space、table、回车enter会认为字符串输入结束
    printf("%s%s\n", p, q);//第二次输入的字符会覆盖第一次的
    return 0;
}
 程序的输入都建有一个缓冲区,即输入缓冲区。一次输入过程是这样的,当一次键盘输入结束时会将输入的数据存入输入缓冲区,而cin函数,scanf函数直接从输入缓冲区中取数据。正因为cin函数,scanf函数是直接从缓冲区取数据的,所以有时候当缓冲区中有残留数据时,cin函数,scanf函数会直接取得这些残留数据而不会请求键盘输入,这就是有时自己写的代码中为什么会出现输入语句失效的原因!

#include<stdio.h>
int main(void)
{
	int a=0,b=0,c=0,ret=0;
	ret=scanf("%d%d%d",&a,&b,&c);
	printf("第一次读入数量:%d\n",ret);
	ret=scanf("%d%d%d",&a,&b,&c);
	printf("第二次读入数量:%d\n",ret);
	return 0;
}
//

在这里插入图片描述
在这里插入图片描述

执行到第一个scanf时,当输入字符’b’的时候与ret=scanf("%d%d%d",&a,&b,&c);中的格式化字符串不匹配,stdin流被阻塞,scanf函数不在读取后面的部分,直接将1返回,表示只将stdin流中的1读入到了变量a中。
  执行到第二个scanf时,字符’b’还是与格式化字符串不匹配,stdin流仍然被阻塞,所以没有提示输入,scanf函数将0返回。

在这里插入图片描述

当把第二个scanf函数内的格式化字符串改为”%c%d%d”时.
执行到第一个scanf函数时,由于输入’b’的原因scanf函数直接返回1stdin流阻塞。
执行到第二个scanf函数时,字符’b’与格式化字符串”%c%d%d”中的%c匹配,stdin流终于疏通,在输入6,则将变量a,b,c分别赋值为98(‘b’的ASCII码)26,scanf函数返回3

10.有以下程序,执行后输出:C

int main()
{
    char *s[]={"one","two","three"},*p = NULL;
    p = s[1];
    printf("%c,%s\n",*(p+1),s[0]);
}
A n,two									B t,one
C w,one									D o,two
    //p是指向s[1],p==&s[1][0],*(&s[1][0]+1),s[1][1]

11.程序运行后的输出结果是 C

int main()
{
    char p[20] = { 'a','b','c','d' };
    char q[] = "abc", r[] = "abcde";
    strcpy(p + strlen(q), r);
    //先将p右移3位到d的位置,然后将r的内容拷贝过来,覆盖d,
    //此时p中abcabcde
    strcat(p, q);
    //把q拼接过来,此时p中abcabcdeabc
    printf("%d %d\n", sizeof(p), strlen(p));
    return 0;
}
//用来把src指向的字符串,接到dest的末尾(第一个'\0')去,直到拼接到src的'\0'处
//它也有一个bug
	char *strcat(char *dest, const char *src);
//dest:要保证它的空间足够大

//用来把src中的字符串,拷贝到dest指向的空间中去,包括src的最后哪个'\0'
	char *strcpy(char *dest, const char *src);
//同样的,strcpy也有严重的问题,不会检查dest是否空间足够大---有越界风险

A 20 9 B 9 9

C 20 11 D 11 11

12.以下程序的输出结果是 6

int main()
{
    char p[20] = { 'a','b','c','d' };
    char q[] = "abc", r[] = "abcde";
    strcat(p, r);//拼接后abcdabcde
    strcpy(p + strlen(q), q);//右移到d开始拷贝,abccde
    printf("%d\n", strlen(p));
    return 0;
}
size_t strlen(const char *s);
//返回值为字符串s的长度,不包括'\0',遇到'\0'停止计数

13.以下关于字符串的叙述中正确的是 D

A c语言中有字符串类型的常量和变量 
//字符串常量
B 两个字符串中的字符个数相同时才能进行字符串大小的比较 
//任意
C 可以用关系运算符对字符串的大小进行比较
//比较两个字符串,一个字符一个字符比较,遇到'\0'结束比较/中间某一个字符不相等结束比较
//返回如果两个字符串相同返回0,如果s1中的某个字符比s2的大,那么就返回正值,否则返回负值
	int strcmp(const char *s1, const char *s2);
D 空串一定比空格打头的字符串小
//空格也是字符

持续更新中

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值