首页 > 其他分享 >C语言——指针初阶(一)

C语言——指针初阶(一)

时间:2024-11-27 22:31:06浏览次数:6  
标签:初阶 变量 int C语言 地址 字节 指针

目录

一.什么是指针???

        指针是什么?

        指针变量:

        总结:

        总结:

二.指针和指针类型

指针+-整数:

        总结:

指针的解引用

总结:

三.野指针

如何规避野指针

往期回顾:


一.什么是指针???

        指针是什么?

        指针理解的2个要点:

       1. 指针是内存中一个最小单元的编号,也就是地址

       2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量

        总结:指针就是地址,口语中说的指针通常指的是指针变量。

        指针变量:

        我们可以通过&(取地址操作符)取出变量的内存其实地址,把地址可以存放到一个变量中,这个变量就是指针变量。

        比如:

#include <stdio.h>
int main()
{
 int a = 10;//在内存中开辟一块空间
 int *p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。
    //a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量
中,p就是一个之指针变量。
 return 0;
}

p就是一个指针变量,而*p叫做指针变量的解引用,指向p指针所指的对象

        总结:

        经过仔细的计算和权衡我们发现一个字节给一个对应的地址是比较合适的。 对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电 平(低电压)就是(1或者0);

        那么32根地址线产生的地址就会是:

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000001 ...

11111111 11111111 11111111 11111111  

        这里就有2的32次方个地址。 每个地址标识一个字节,那我们就可以给 (2^32Byte == 2^32/1024KB == 2^32/1024/1024MB==2^32/1024/1024/1024GB == 4GB)4G的空闲进行编址。 

        这里我们就明白: 在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以 一个指针变量的大小就应该是4个字节。 那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地 址。

        总结:

        指针是用来存放地址的,地址是唯一标示一块地址空间的。 指针的大小在32位平台是4个字节,在64位平台是8个字节。

二.指针和指针类型

        当有这样的代码:

int num = 10;
p = &num;

        要将&num(num的地址)保存到p中,我们知道p就是一个指针变量,那它的类型是怎样的呢? 我们给指针变量相应的类型。

char  *pc = NULL; int   *pi = NULL; short *ps = NULL; long  *pl = NULL; float *pf = NULL; double *pd = NULL;

        这里可以看到,指针的定义方式是: type + * 。

        其实: char* 类型的指针是为了存放 char 类型变量的地址。 short* 类型的指针是为了存放 short 类型变量的地址。 int* 类型的指针是为了存放 int 类型变量的地址。

        那指针类型的意义是什么?

        我们接着讨论:

指针+-整数:

        如下代码:

#include <stdio.h>
//演示实例
int main()
{
 int n = 10;
 char *pc = (char*)&n;
 int *pi = &n;
 
 printf("%p\n", &n);
 printf("%p\n", pc);
 printf("%p\n", pc+1);
 printf("%p\n", pi);
 printf("%p\n", pi+1);
 return  0;
}

根据运行结果我们发现:当指针变量的类型是char型的时候,指针+1,指针向后移动一位,当是int型的时候,指针+1,指针向后移动4位。

        总结:

        指针的类型决定了指针向前或者向后走一步有多大(距离)。

指针的解引用

//演示实例
#include <stdio.h>
int main()
{
 int n = 0x11223344;
 char *pc = (char *)&n;
 int *pi = &n;
 *pc = 0;   //重点在调试的过程中观察内存的变化。
 *pi = 0;   //重点在调试的过程中观察内存的变化。
 return 0;
}

通过调试中窗口-内存-找到n的地址,接着进行调试

当代码运行到1399行的时候,n的地址第一位变成00;

当代码运行到1400行的时候,n的地址前四位全变成00;

总结:

        指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。简单来说,指针变量体现了访问指针内存的一种视角,想怎样访问内存应该找相应的指针变量。

        比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

三.野指针

        野指针成因:

①指针未初始化

#include <stdio.h>
int main()
{ 
 int *p;//局部变量指针未初始化,默认为随机值
    *p = 20;
 return 0;
}

②指针越界访问

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = arr;
	int i = 0;
	for (i = 0; i <= 10; i++)
	{
		printf("%d", *p);//当i=10的时候再运行出现越界访问
		p++;
	}
	return 0;
}

如何规避野指针

1. 指针初始化

2. 小心指针越界

3. 指针指向空间释放即使置NULL(空指针——专门用来初始化指针的)

4. 避免返回局部变量的地址

5. 指针使用之前检查有效性

#include <stdio.h>
int main()
{
    int *p = NULL;
    //....
    int a = 10;
    p = &a;
    if(p != NULL)
   {
        *p = 20;
   }
    return 0;
}

往期回顾:

C语言函数递归经典题型——汉诺塔问题-CSDN博客

C语言——数组基本知识(二)-CSDN博客

C语言——数组基本知识(一)-CSDN博客

C语言——数组逐元素操作练习-CSDN博客

C语言编程练习:验证哥德巴赫猜想 进制转换 rand函数-CSDN博客

C语言——函数基本知识(三)-CSDN博客

C语言——函数基本知识(二)-CSDN博客

C语言 ——函数基本知识(一)-CSDN博客

C语言——二分法查找讲解-CSDN博客

C语言算法经典基础题型——求一个数的回文数(两种方法)_编程计算一个数的回数-CSDN博客

标签:初阶,变量,int,C语言,地址,字节,指针
From: https://blog.csdn.net/hjx1235/article/details/144094258

相关文章

  • C语言中对文件的输入输出
    在c中的文件操作通过读的形式,打开文件用FILE打开用FILE*类型的指针接受文件指针的首地址并且我们可以用读或写的方式打开文件使用r来读取文件当然也要判断是否读取文件成功,若读取成功fopen会传出指针,若失败则会传出空指针,所以要判断读取是否成功当然,当文件不存在时使用r会......
  • 零基础C语言-插入排序
    插入排序插入排序是排序算法当中一种很基础的算法,同时他也我们日常生活当中所见到最多的排序。比如我们在拿扑克牌的时候,所用的排序方法就是将手中刚刚拿到的牌放入一个比前边大后边小的位置,直接插入进去,这就是插入排序。所以我们要对插入排序进行实现我们就要进行代码......
  • C语言实例之10求0-10000中的水仙花数
    1.水仙花数的描述水仙花数(Narcissisticnumber)也被称作自恋数、自幂数等。它是指一个三位数,其各位数字的立方和等于该数本身。例如,153是一个水仙花数,因为13......
  • 【C语言】· 第五讲 · Printf 与 Scanf 学习笔记
    Printf与Scanf一、printf1、 基本⽤法printf()的作⽤是将参数⽂本输出到屏幕。它名字⾥⾯的f代表format(格式化),表⽰可以定制输出⽂本的格式。printf()不会在⾏尾⾃动添加换⾏符,运⾏结束后,光标就停留在输出结束的地⽅,不会⾃动换⾏。为了让光标移到下⼀⾏的开头......
  • 【C语言的奥秘6】函数知识点总结最全
    一、什么是函数程序是由多个零件组合而成的,而函数就是这种“零件”的一个较小的单位。也可以叫子程序。在计算机科学中,子程序是一个大型程序中的某部分代码,由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。一般会有输入参数并有返回值,......
  • C语言动态内存管理的讲解
    一、动态内存为何存在在动态内存管理之前,我们已经学过了在栈空间开辟内存的方式:inta=4;(在栈区开辟四个字节的空间)chararr[10];(在栈区开辟10个字节的连续空间)这些开辟空间的方式有两个特点:(1)空间开辟的大小是固定的;(2)数组在申明的时候,必须指定数组的长度,数组空间大小......
  • C语言:基本数据类型
    整型数据        用来存放整型数据的变量我们定义一个整型的变量,C编译系统实际是在内存中分配了能够存储一个整型数据的存储空间,并用变量名来标识这个空间,对该空间的使用也就可以通过变量名来访问。若不知道你所用的C编译系统对变量分配的存储空间的大小,可用sizeof......
  • 【快慢指针技巧】:高效解决链表和数组问题(26,83,27)
    ......
  • Go: 指针方法与值方法<->指针类型与值类型
    在Go中,指针方法可以被值类型调用,这归因于Go编译器的自动解引用特性。如果一个方法是为指针类型定义的,而我们使用值类型去调用它,Go会自动将值的地址传递给方法,使得调用能够正常进行。例子解析1.指针方法的定义假设我们定义了一个方法绑定在结构体的指针上:typePersons......
  • 指针测试总结(一)(一维数组)
    1.取一维数组的首地址intmain(){intarr[3]={5,8,1};printf("%d\n",arr);printf("%d\n",&arr);printf("%d\n",&arr[0]);printf("%d\n",&arr+0);}输出结果:1096809108109680910810968091081......