C语言学习笔记Day14

指针练习

1.程序的结果是什么?

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

在这里插入图片描述

2.假设p的值为0x100000。如下表表达式的值分别为多少?

struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
//结构体指针
//已知,结构体Test类型的变量大小是20个字节
int main()
{
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}

说明:指针类型决定了指针的运算
在这里插入图片描述

3.程序的结果是什么?

int main()
{
int a[4] = { 1, 2, 3, 4 };
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
printf( "%x,%x", ptr1[-1], *ptr2);
return 0;
}

在这里插入图片描述

4.程序的结果是什么?

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

在这里插入图片描述

5.程序的结果是什么?

int main()
{
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]);
return 0;
}

在这里插入图片描述

6.程序的结果是什么?

int main()
{
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));
return 0;
}

在这里插入图片描述

7.程序的结果是什么?

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

在这里插入图片描述

8.程序的结果是什么?

int main()
{
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);
return 0;
}

在这里插入图片描述

9.在杨氏矩阵中查找数

//杨氏矩阵
find_num(int arr[3][3], int* px, int*py, int k)
{
	int x = 0;
	int y = *py - 1;
	while (x < *px && y >= 0)
	{
		if (arr[x][y] < k)
		{
			x++;
		}
		else if(arr[x][y] > k)
		{
			y--;
		}
		else
		{
			*px = x;
			*py = y;
			return 1;
		}
	}
	return 0;//找不到
}
int main()
{
	int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
	int k = 7;
	int x = 3;
	int y = 3;
	//如果找到,返回1,找不到,返回0
	//&x,&y
	//1.传入参数
	//2.带回值
	int ret = find_num(arr, &x, &y, k);
	if (ret == 1)
	{
		printf("Find!\n");
		printf("下标为:%d %d\n", x, y);
	}
	else
	{
		printf("Not find!\n");
	}
	return 0;
}

在这里插入图片描述

10.左旋字符串中的k个字符

方法1

//左旋字符串中的k个字符
void string_left_rotate(char*str,int k)
{
	int i = 0;
	int len = strlen(str);
	for (i = 0; i < k; i++)
	{
		//每次左旋1个字符
		//第一步
		char tmp = *str;
		//第二步,把后面的n-1个字符向前挪动
		int j = 0;
		for (j = 0; j < len - 1; j++)
		{
			*(str + j) = *(str + j + 1);
		}
		//第三步,tmp放在最后
		*(str + len-1) = tmp;
	}
}
int main()
{
	char arr[10] = "abcdefg";
	int k = 2;
	string_left_rotate(arr,k);
	printf("%s\n", arr);
	return 0;
}

在这里插入图片描述
方法2

void reverse(char* left, char* right)
{
	assert(left);
	assert(right);
	while (left<right)
	{
		char tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
}
void string_left_rotate(char* str, int k)
{
	int n = strlen(str);
	reverse(str,str+k-1);//左
	reverse(str + k,str+n-1);//右
	reverse(str, str + n - 1);//整体
}
int main()
{
	char arr[10] = "abcdefg";
	int k =4;
	string_left_rotate(arr, k);
	printf("%s\n", arr);
	return 0;
}

在这里插入图片描述

11.判断一个字符串,是否为另一个字符串旋转之后的字符串

方法1

int is_string_rotate(char* str1, char* str2)
{
		int i = 0;
		int len = strlen(str1);
		for (i = 0; i < len; i++)
		{
			//每次左旋1个字符
			//第一步
			char tmp = *str1;
			//第二步,把后面的n-1个字符向前挪动
			int j = 0;
			for (j = 0; j < len - 1; j++)
			{
				*(str1 + j) = *(str1 + j + 1);
			}
			//第三步,tmp放在最后
			*(str1 + len - 1) = tmp;
			if (strcmp(str1, str2) == 0)
			{
				return 1;
			}
		}
		return 0;
}
int main()
{
	char arr1[] = "AABCD";
	char arr2[] = "BCDAA";
	int ret=is_string_rotate(arr1, arr2);
	if (ret == 1)
	{
		printf("YES!\n");
	}
	else
	{
		printf("No!\n");
	}
	return 0;
}

在这里插入图片描述
方法2

int is_string_rotate(char* str1, char* str2)
{
	//长度不相等,肯定不是旋转得到的
	if (strlen(str2) != strlen(str1));
	//1.str1字符串后面追加一个str1
	int len = strlen(str1);
	strncat(str1, str1, len);
	//2.判断str2是否为str1的子串
	char* ret = strstr(str1, str2);
	return ret != NULL;
}
int main()
{
	char arr1[] = "AABCD";
	char arr2[] = "BCDAA";
	int ret=is_string_rotate(arr1, arr2);
	if (ret == 1)
	{
		printf("YES!\n");
	}
	else
	{
		printf("No!\n");
	}
	return 0;
}

(欢迎大家批评指针,侵权即删)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值