C语言指针(2)

        接上一篇博客,我们来继续啃下指针这块“硬骨头”。

目录

一、assert断言

二、指针的使用和传址调用

1、strlen的模拟实现

2、传值调用和传址调用

三、数组名的理解

四、使用指针访问数组

五、一维数组传参的本质

       1、 一维数组传参的时候,传过去的是数组首元素的地址

       2、形参的部分可以写成指针的形式,也可以写成数组的形式,但本质上都是指针形式,写成数组的形式是为了方便理解

​编辑

六、冒泡排序(两两相邻元素进行比较)

        1、普通方法

2、指针形式

3、升级高效版冒泡排序

七、二级指针

     1、 指针变量也是变量,是变量就有地址,那么指针变量的地址放在哪里呢?这就是我们在这一部分讨论的问题。

      2、使用:

八、指针数组------存放指针的数组


一、assert断言

       assert.h头文件定义了宏assert(),用于在运行时确保程序符合指定条件,如果不符合则报错终止运行,这个宏常常被称为“断言”。




assert(p != NULL);




        当运行到这一句时,验证p是否为NULL,若不等于NULL,则继续运行;若等于则报错终止运行。

        assert()宏接收一个表达式为参数,如果表达式为真,assert()不会产生任何作用,程序继续运行;表达式为假,assert()就会报错。

        通过以上两个代码我们就可以看到assert()的作用了。

        当我们确定程序没有问题的时候,不需要断言的时候,我们就可以禁用断言,使用#define NDBUG指令。

        但是assert()也是有缺点的,它引入了额外的检查,增加了程序的运行时间。

二、指针的使用和传址调用

1、strlen的模拟实现

#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char *p)
{
	size_t count = 0;
	assert(p!=NULL);
	while (*p)
	{
		count++;
		p++;
	}
	return count;
}
int main()
{
	char arr[] = "abcde";
	size_t len = my_strlen(arr);
	printf("%zd\n", len);
	return 0;
}

//运行结果为 5

2、传值调用和传址调用

          对于这个问题,我们用一道例题来进行解释

           写一个函数来交换两个整型变量的值

        我们先不用函数来实现一下这个功能,代码如下:

        接下来就是使用函数了,我们定义Swap函数为交换函数:

         代码如下:

        很神奇,为什么没有交换过来呢?这是什么原因呢?三秒钟时间考虑一下。

        3

        2

        1

        好,时间到,我刚开始看到这个代码没有成功实现函数功能也很吃惊,直到我懂得了其中的道理之后就明白了自己的错误,这道题的问题就是咱们的标题:传值调用与传址调用

        接下来,就让我们一起来解决这个问题吧!

        我们可以看到,a和 b是实参,x和y是形参,当实参传递给形参的时候,形参是有自己独立的空间的,形参是实参的一份临时拷贝,对形参的修改,不会影响实参。

      所以,下面的代码才是正确的:

三、数组名的理解

通过下面的代码可以知道,数组名是数字首元素的地址

但是,这里是有两个例外的:

(1)sizeof(数组名),sizeof中单独放数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节;
(2)&数组名,这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组               首元素的地址是有区别的);

     除此之外,任何地方使用数组名,数组名都表示首元素的地址。

四、使用指针访问数组

上面的代码还可以改为这样

五、一维数组传参的本质

       1、 一维数组传参的时候,传过去的是数组首元素的地址

       2、形参的部分可以写成指针的形式,也可以写成数组的形式,但本质上都是指针形式,写成数组的形式是为了方便理解

六、冒泡排序(两两相邻元素进行比较)

        1、普通方法

#include<stdio.h>
void bubble_sort(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

        运行结果如下:

2、指针形式

#include<stdio.h>
void bubble_sort(int *arr, int sz)
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int j = 0;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (*(arr + j) > *(arr + j + 1))
			{
				int tmp = *(arr + j);
				*(arr + j) = *(arr + j + 1);
				*(arr + j + 1) = tmp;
			}
		}
	}
}
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

3、升级高效版冒泡排序

#include<stdio.h>
void bubble_sort(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int flag = 1;
		int j = 0;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				flag = 0;
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
		if (flag == 1)
			break;
	}
}
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

七、二级指针

     1、 指针变量也是变量,是变量就有地址,那么指针变量的地址放在哪里呢?这就是我们在这一部分讨论的问题。

                        二级指针变量就是用来存放一级指针变量的地址的

      2、使用:

八、指针数组------存放指针的数组

        指针数组模拟二维数组

        arr[i]访问的是arr数组的元素,arr[i]指向了整形一维数组,arr[i][j]就是整形一维数组中的元素。

#include<stdio.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 3,4,5,6,7 };
	int arr3[] = { 5,6,7,8,9 };
	int* arr[3] = {arr1, arr2, arr3};
	int i = 0;
	int j = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 5; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

运行结果如下:

        到这里C语言指针第二部分就结束了,我们又学习到了许多未曾听说过的知识,就让我们好好学习,多多复习,继续在指针的世界里遨游把!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值