六、指针
通过函数指针调用函数,函数指针指向的函数要和调用函数的返回值、参数一致
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 80(10)/96(12) 80(10)/128(16) 有效位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函数直接返回1,stdin流阻塞。
执行到第二个scanf函数时,字符’b’与格式化字符串”%c%d%d”中的%c匹配,stdin流终于疏通,在输入6,则将变量a,b,c分别赋值为98(‘b’的ASCII码)、2、6,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 空串一定比空格打头的字符串小
//空格也是字符