指针(进阶)习题

目录

1.实现一个计算器,计算整形变量的加减乘除(使用回调函数)

2.使用qsort函数排序整型(实现升序)

3.使用回调函数,模拟实现qsort(采用冒泡的方式

 4.易混易错sizeof和strlen

习题1

习题2

 习题3

习题4 

 习题5

 习题6

 习题7

习题8

5.指针笔试题

 习题1:判断打印值

习题2

习题3

习题4

习题5 

习题6

习题7

习题8 


1.实现一个计算器,计算整形变量的加减乘除(使用回调函数)

int Add(int x, int y)
{
	return x + y;
}

int Sub(int x, int y)
{
	return x - y;
}

int Mul(int x, int y)
{
	return x * y;
}

int Div(int x, int y)
{
	return x / y;
}

void menu()
{
	printf("**************************\n");
	printf("**** 1. add    2. sub ****\n");
	printf("**** 3. mul    4. div ****\n");
	printf("****     0. exit      ****\n");
	printf("**************************\n");
}

int Calc(int (*pf)(int, int))
{
	int x = 0;
	int y = 0;
	printf("请输入2个操作数>:");
	scanf("%d %d", &x, &y);
	return pf(x, y);
}

int main()
{
	int input = 0;
	//计算器-计算整型变量的加、减、乘、除
	//a&b a^b a|b a>>b a<<b a>b

	do {
		menu();
	
		int ret = 0;
		printf("请选择:>");
		scanf("%d", &input);

		switch (input)
		{
		case 1:
			ret = Calc(Add);
			printf("ret = %d\n", ret);
			break;
		case 2:
			ret = Calc(Sub);
			printf("ret = %d\n", ret);
			break;
		case 3:
			ret = Calc(Mul);//
			printf("ret = %d\n", ret);
			break;
		case 4:
			ret = Calc(Div);//
			printf("ret = %d\n", ret);
			break;
		case 0:
			printf("退出程序\n");
			break;
		default:
			printf("选择错误,重新选择!\n");
			break;
		}
		
	} while (input);
	return 0;
}

2.使用qsort函数排序整型(实现升序)

先用冒牌排序实现

void bubble_sort(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz - i; i++)
	{
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] < arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}

在这里插入图片描述

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
void print_arr(int arr[], int sz)
{
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    } 
    printf("\n");
}

//qosrt函数的使用者得实现一个比较函数

int cmp_int(const void* p1, const void* p2) //提供的是整型数组元素大小的比较方式
{

    return (*(int*)p1 - *(int*)p2);
    //强制类型转换为int*,说明比较的是整型元素
    //p1,p2接收的是对应元素的地址
    //如果返回值大于0,则两元素进行交换
}

int main()
{
    int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    //排序
    qsort(arr, sz, sizeof(arr[0]), cmp_int);
    //打印
    print_arr(arr, sz);

    return 0;
 }

3.使用回调函数,模拟实现qsort(采用冒泡的方式

#define  _CRT_SECURE_NO_WARNINGS  1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int cmp1(const void* p1, const void* p2) //提供的是整型数组元素大小的比较方式
{
	return (*(int*)p1 - *(int*)p2);
}

int cmp2(const void* elem1,const  void* elem2) //提供的是浮点型数组元素大小的比较方式
{
	return	 (*(float*)elem1 - *(float*)elem2);
}

struct stu2 {
	char name[20];
	int age = 0;
};
int cmp3(const void* elem1, const void* elem2) //提供的是结构体中stu2中name成员的比较方式
{
	return  (strcmp(((struct stu2*)elem1)->name, ((struct stu2*)elem2)->name));
}

int cmp4(const void* elem1, const void* elem2)//提供的是结构体中stu2中age成员的比较方式
{
	return  (((struct stu2*)elem1)->age - ((struct stu2*)elem2)->age);
}

void customer_sort(void*base, int num, int width, int (*cmp)(const void*elem1,const void* elem2))
{
	int i = 0;
	for (; i < num - 1; i++)//确定排序趟数
	{
		for (int b = 0; b < num - 1 - i; b++)//每趟排序进行比较的次数
				{
			if (cmp(((char*)base + b * width), ((char*)base + (b + 1) * width)) > 0)
			//如果cmp函数返回值大于0,则进行交换
			{
				char tmp = 0;
				for (int j = 0; j < width; j++)
				{
					tmp = *((char*)base + b * width + j);
					*((char*)base + b * width + j) = *((char*)base + (b + 1) * width + j);
					*((char*)base + (b + 1) * width + j) = tmp;
				}
			}
		}
	}
}
int main()
{
	int arr1[10] = { 2,4,6,8,1,3,9,5,7,10 };
	float arr2[5] = { 3.0,5.0,1.0,7.0,8.0 };
	int sz = sizeof(arr2) / sizeof(*arr2);
	customer_sort(arr2, sz, sizeof(*arr2),cmp2);//如果要排序其他类型数组
	//把cmp函数换成对应的就行了
	for (int a = 0; a < sz; a++)
	{
		printf("%f ", arr2[a]);
	}
	return 0;
}

 4.易混易错sizeof和strlen

习题1

    int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof(a + 0));
	printf("%d\n", sizeof(*a));
	printf("%d\n", sizeof(a + 1));
	printf("%d\n", sizeof(a[1]));

	printf("%d\n", sizeof(&a)); 
	printf("%d\n", sizeof(* &a));
	//&a -- int(*p)[4] = &a;
	printf("%d\n", sizeof(&a + 1));
	printf("%d\n", sizeof(&a[0]));
	printf("%d\n", sizeof(&a[0] + 1));
 

在这里插入图片描述

 

习题2

    char arr[] = { 'a','b','c','d','e','f' };
    printf("%d\n", sizeof(arr));//这里没有\0之分
	printf("%d\n", sizeof(arr + 0));
	printf("%d\n", sizeof(*arr));
	printf("%d\n", sizeof(arr[1]));
	printf("%d\n", sizeof(&arr));
	printf("%d\n", sizeof(&arr + 1));
	printf("%d\n", sizeof(&arr[0] + 1));

 习题3

    char arr[] = { 'a','b','c','d','e','f' };
    printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr + 0));
	//printf("%d\n", strlen(*arr));
	//printf("%d\n", strlen(arr[1]));
	printf("%d\n", strlen(&arr));
	printf("%d\n", strlen(&arr + 1));
	printf("%d\n", strlen(&arr[0] + 1));

在这里插入图片描述

 因为strlen结束标志是\0,所以前俩个找不到结束标志结果就是随机值;第三和第四个错了,strlen()应该传递的是地址,他们却传递了具体数值,把数值97当成具体地址;第五个传递过去依然会被认为是arr首地址,随机值;第六个跳过一个数组,也是随机值;第七个同理,从b的地址向后寻找\0,也是随机值。
————————————————
版权声明:本文为CSDN博主「林慢慢脑瓜子嗡嗡的」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_48953972/article/details/117591550

习题4 

	char arr[] = "abcdef";
	//[a b c d e f \0]
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr + 0));
	//printf("%d\n", strlen(*arr));
	//printf("%d\n", strlen(arr[1]));
	printf("%d\n", strlen(&arr));
	printf("%d\n", strlen(&arr + 1));
	printf("%d\n", strlen(&arr[0] + 1));

在这里插入图片描述

 习题5

	char arr[] = "abcdef";
	//[a b c d e f \0]
    printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr + 0));
	printf("%d\n", sizeof(*arr));
	printf("%d\n", sizeof(arr[1]));
	printf("%d\n", sizeof(&arr));
	printf("%d\n", sizeof(&arr + 1));
	printf("%d\n", sizeof(&arr[0] + 1));

在这里插入图片描述

 习题6

	char* p = "abcdef";

	printf("%d\n", sizeof(p));
	printf("%d\n", sizeof(p + 1));
	printf("%d\n", sizeof(*p));
	printf("%d\n", sizeof(p[0]));
	printf("%d\n", sizeof(&p));
	printf("%d\n", sizeof(&p + 1));
	printf("%d\n", sizeof(&p[0] + 1));

答案:4/8;4/8;1;1;4/8;4/8;4/8

 习题7

char* p = "abcdef";
printf("%d\n", strlen(p));
printf("%d\n", strlen(p + 1));
printf("%d\n", strlen(*p));
printf("%d\n", strlen(p[0]));

printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p + 1));
printf("%d\n", strlen(&p[0] + 1));
 

答案:

6;5;err;err;

第五个随机(对p取地址,向后去\0压根不知道结果);

第六个随机,与第五个同理;

5 。

 

习题8

int a[3][4] = { 0 };

printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a[0][0]));
printf("%d\n", sizeof(a[0]));

printf("%d\n", sizeof(a[0] + 1));
printf("%d\n", sizeof(*(a[0] + 1)));

printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(*(a + 1)));

printf("%d\n", sizeof(&a[0] + 1));

printf("%d\n", sizeof(*(&a[0] + 1)));

printf("%d\n", sizeof(*a));

printf("%d\n", sizeof(a[3]));
printf("%d\n", sizeof(a[-1]));

在这里插入图片描述

 sizeof表达时不参与运算:

#include <stdio.h>
int main()
{
	short s = 5;
	int a = 4;
	printf("%d\n", sizeof(s = a + 6));//1
	printf("%d\n", s);//2

	return 0;
}

打印结果: 2 5 

5.指针笔试题

 习题1:判断打印值

int a[5] = { 1, 2, 3, 4, 5 };
int* ptr = (int*)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1));

  &a 取的是整个数组的地址,&a+1跳过整个数组

 

习题2

由于还没学习结构体,这里告知结构体的大小是20个字节。

假设p 的值为0x100000。 如下表达式的值分别为多少?
已知,结构体Test类型的变量大小是20个字节

提示:指针类型决定了指针的 运算

struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}* p;


int main()
{
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}

1.p是结构体指针,加1跳过一个结构体大小。0x100014

2.强制转化成整型类型,加1就是加1。0x100001

3.p指向(unsigned int*)无符号整型指针,加1跳过一个整型变量的大小,即加4。0x100004

习题3

   int a[4] = { 1, 2, 3, 4 };
   int* ptr1 = (int*)(&a + 1);
   int* ptr2 = (int*)((int)a + 1);

   printf("%x,%x", ptr1[-1], *ptr2);

习题4

用小括号即为逗号表达式,逗号表达式只要最后一个,多出来的部分后面补0

   int a[3][2] = { (0, 1), (2, 3), (4, 5) };
   int* p;
   p = a[0];
   printf("%d", p[0]);

 

习题5 

int a[5][5];
int(*p)[4];
p = a;
printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);

 

习题6

int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* ptr1 = (int*)(&aa + 1);
int* ptr2 = (int*)(*(aa + 1));
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));

结果:10,5 

习题7

char* a[] = { "work","at","alibaba" };
char** pa = a;
pa++;
printf("%s\n", *pa);

 打印结果:at

习题8 

char* c[] = { "ENTER","NEW","POINT","FIRST" };
char** cp[] = { c + 3,c + 2,c + 1,c };
char*** cpp = cp;

printf("%s\n", **++cpp);
printf("%s\n", *--* ++cpp + 3);
printf("%s\n", *cpp[-2] + 3);
printf("%s\n", cpp[-1][-1] + 1);

 

 在这里插入图片描述 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值