C语言之指针(上) -----Day14

一.知识点整理

1.指针基础概念

1.1 什么是指针?

简单的来说,指针就是一个数据类型,用来表示内存地址

1.2 直接访问和间接访问

  • 直接访问

直接用过变量访问里面的值

在这里插入图片描述

  • 间接访问

将一个变量的地址存放在另一个变量中,通过变量b来访问a的值
在这里插入图片描述

1.3 定义指针变量

  • 声明 数据类型 *指针变量名

int *p ; char *q

1.4 指针初始化

  • 指针在使用时一定要初始化,有两种方法
//方法一
int *p, a;
p = &a;
//方法二
int a;
int *p = &a;

如果指针未初始化,我们叫做野指针或者悬挂指针

1.5 指针操作符*和&

  • ‘*’ 表示解引用符

可以用过*来访问指针变量所指向地址的变量

  • &表示取地址符

用来取变量的地址
例如:*(&a) : 表示先取a的地址在访问a,相当于直接反问变量a

1.6 指针变量的大小

  • 32位操作系统下:为4个字节
  • 64位操作系统下:为8个字节

2. 指针与数组

2.1 定义和关系

  • 数组元素的指针就是数组元素的地址
  • 定义方法
int a[10]; // 定义10个整型的数组
int *p;   // 定义指向整型变量的指针
p = a; // 把数组a元素的首地址给指针变量p

2.2 引用数组元素

  • 下标法

a[i];

  • 指针法

*(a+i) 或 *(p+1) // a表示数组名

2.3 指针作为形参传入函数

int main()
{
	int a[10];
	fun(a,10);
}
fun(int *a, int n){}

2.4 二维数组与指针

2.4.1 行指针与列指针
//定义一个二维数组
int a[3][3] = {1,2,3,4,5,6,7,8,9};
int (*p)[5];//表示p指向整一行,也称行指针
p = a;
printf(" a :%p\n",a);
printf(" p :%p\n",p);
p++;
printf(" p++ :%p\n",p);//偏移整一行的地址
  • 行指针

行指针是一个二级地址,其指向的是一个一级地址

  • 列指针

列指针是一个一级地址,其只想的是数组元素的地址

  • 例题:声明几个指针变量取遍历二维数组并打印
int main()
{
	int a[3][5] = {0};
	int *p;
    for(p = a; p < a+3; p++)
    {
        int *q = *p;
        for(q=*p; q < *p+5;q++)
            {
	printf("%d",*q);
             }
    printf("\n");
    }
}

2.5 字符串与指针

  • 字符串指针
"1234"//值是字符串第一个元素的地址,直到'\0'
char *p = "1234";
char buf;
buf[] = "1234";
buf = "5678";//错的

"1234"为字符串常量,常量是不能够用变量的方式来修改

  • 字符串赋值方式
char str[20];
str = "hello world!"

二. 难点易错点整理

1.内存单元是什么?变量名是什么?地址是什么?值是什么?

内存单元就是根据你所定义的数据类型所分配的,比如你定义了int型变量,那么系统就会给你分配4个字节的地址;
变量名就是用户自定义的名称,系统会自动为它分配相应的地址;
地址就是内存的编号,相当于你家的门牌号一样
就是一定具体的常量,通俗一点就是门里面的你;

2. 32位操作系统:每一个进程都有4个G的虚拟内存,内存是如何进行分布的?

在这里插入图片描述

  • 代码段

存放的是代码的指令,由各个函数产生,函数的每一个语句将最终经过编绎和汇编生成二进制机器代码,只读而且不能修改

  • 只读数据段

存放的是全局变量、静态变量、字符串常量。const修饰的全局变量在常量区;const修饰的局部变量只是为了防止修改,没有放入常量区。

  • 读写数据段(data)

通常已初始化的全局变量和局部静态变量被放在了读写数据段。

  • 堆(heap)

是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)

栈是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。

3.区分指针和指针变量

指针就是变量的地址,而用来存放地址的变量称为指针变量:指针变量的值是指针

4. 函数参数的传入

  • 设计一个数组长度为10的数组, 随机取值范围0-9,
    要求返回奇数的和和偶数的和,并返回奇数的个数
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int get(int *a,int *ji,int *ou)
{
	int count = 0;
	*ji = 0; *ou = 0;
	for(int i = 0; i < 10; i++)
	{
		if(a[i] % 2 == 0)
		{
			*ou += a[i];
		}
		else if(a[i] % 2 == 1)
		{
			*ji += a[i];
			count++;
		}
	}
	return count;
}
int main()
{
	int n1=0,n2=0,n3=0;
	srand(time(NULL));
	int a[10] = {0};
	for(int i = 0;i < 10; i++)
		a[i] = rand()%10;
	for(int j = 0; j < 10;j++)
	  printf("%d ",a[j]);
	printf("\n");
	n3 =get(a,&n1,&n2);
	printf("%d %d %d\n ",n3,n1,n2);
}

这个代码中是通过函数将多个函数值返回出来,而一般的return只能返回一个值,具体操作为**int get(int *a,int *ji,int *ou)**在函数里面定义了指针变量,并在主函数里面通过取地址符将值传入和传出

5. 数组指针与指针数组

数组指针就是通过指针来表示数组和操作数组的元素,而指针数组表示的是数组里面保存的是指针变量;

6.哪些情况会让程序报段错误

1.访问非法内存
2.修改只读常量
3.数组越界过多

三.自我总结

通过了一天对指针的学习,我也算是面对了我在C语言里面的心魔,知识点相比之前的函数、数组等,难度也提高了很多,与此同时知识的复杂度也提高了很多,相当的绕脑袋,就像指针、指针变量、数组指针、指针数组、数组a在主函数里面是常量,但是在函数里面却变成了地址等等,但是在学习之后,我也对这些概念有了一定的把握。

最后,送上一句话:孤臣万里,挑灯看剑,我与指针相缠绵!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值