C语言超详细讲解指针的使用

目录
  • 指针概述
    • 自身类型
    • 指向类型
  • 代码例子
  • 数值型指针
  • 字符型指针
    • 单字符
    • 字符数组
  • 字符串型指针
  • 字符数组总结

指针概述

C语言中指针也可以认为是一种类型,不同于数值型和字符型的类型。推演过去指针变量也就是相当于不同的变量类型,不同于数值变量、字符型变量、字符串变量。

指针变量两种类型:自身类型和指向的类型

自身类型:将变量名去掉,剩下的就是指针变量类型。

指向类型:将变量名和离它最近的一个*去掉,剩下的类型就是指针指向的类型

int num = 10;
int* p = NULL;
p = #

如代码中 指针变量的自身类型是 int * 型;指向类型是 int 型。

自身类型

自身类型是指变量p本身的类型,变量p中放的是地址内容,地址指向的是放整型的数据,为什么需要说是指向整型的地址呢?因为不同类型数据占据的不同大小的一整块内存,整型是一个占4字节大小的一个整体内存,字符型是一个占2个字节大小的一个整体内存,编译器不会把它们拆分开。如定义了一个int型变量,它的地址是0x7fffffff00,紧接着马上定义一个char型变量,他的地址就直接到了0x7fffffff04。从0x7fffffff00 ~ 0x7fffffff04中间不会再被分开了放int型数据,0x7fffffff04 ~ 0x7fffffff06中间不分开放char型数据。

所以 自身类型 是基本类型 + *组合而成,虽然里面放的都是地址,但是地址指向的一整块内容是有区别的。

指向类型

指向类型 是指 指针变量中放置的地址是指向的内容类型。

int num = 10;
int* p = NULL;
p = #
int** pp = NULL;
pp = &p;

这是一个二级指针,指向的类型是int*,说明变量pp指向的是指针类型的数据。

代码例子

代码1

 #include <stdio.h>
 int main()
 {
     int num = 100;
     printf("num = %d, num address = %#lx\n", num, &num);
     //num = 100, num address = 0x7ffd4376ff4c
     int* p = NULL;
     p = &num;
     printf("*p = %d, p =  %#lx, &p = %#lx\n", *p, p, &p);
     //*p = 100, p =  0x7ffd4376ff4c, &p = 0x7ffd4376ff40
     int** pp = NULL;
     pp = &p;
     printf("**pp = %d, *pp = %#lx, pp = %#lx\n", **pp, *pp, pp);
     //**pp = 100, *pp = 0x7ffd4376ff4c, pp = 0x7ffd4376ff40
     int arr[5]= {10,20,30,40,50};
     printf("arr address = %#lx, arr[0] address = %#lx, arr[0] = %d\n",arr,&arr[0],arr[0]);
     //arr address = 0x7ffd4376ff20, arr[0] address = 0x7ffd4376ff20, arr[0] = 10
     int* parr = NULL;
     parr = arr;
     printf("parr = %#lx, *parr = %d, *(parr+2) = %d\n",parr,*parr,*(parr+2));
     //parr = 0x7ffd4376ff20, *parr = 10, *(parr+2) = 30
     char str[6]= {'a','d','m','i','n','\0'};
     printf("str address = %#lx, str[0] address = %#lx, str[1]= %c\n", str, &str[0],str[1]);
     //str address = 0x7ffd4376ff10, str[0] address = 0x7ffd4376ff10, str[1]= d
     char* pstr = NULL;
     pstr = str;
     printf("pstr = %#lx,*pstr = %c,*(pstr+2)= %c\n",pstr,*pstr,*(pstr+2));
     //pstr = 0x7ffd4376ff10,*pstr = a,*(pstr+2)= m
     char str2[6] = "admin";
     printf("str2 = %#lx, str2[0] address = %#lx, str2 = %s, str2[1]= %c\n",str2,&str2[0],str2,str2[1]);
     //str2 = 0x7ffd4376ff00, str2[0] address = 0x7ffd4376ff00, str2 = admin, str2[1]= d
     char* pstr2 = NULL;
     pstr2 = str2;
     printf("pstr2 = %#lx, pstr2 = %s\n",pstr2, pstr2);
     //pstr2 = 0x7ffd4376ff00, pstr2 = admin
 }

代码2

#include <stdio.h>
int main()
 {
     float num = 10;
     printf("num = %f, &num = %#lx\n\n", num, &num);
     //num = 10.000000, &num = 0x7ffcdf7ffd94
     float* pnum = &num;
     printf("*pnum = %f, pnum = %#lx, &pnum = %#lx\n\n ", *pnum, pnum, &pnum);
     //*pnum = 10.000000, pnum = 0x7ffcdf7ffd94, &pnum = 0x7ffcdf7ffd88
     float** p_pnum = &pnum;
     printf("**p_pnum = %f, *p_pnum = %#lx, p_pnum = %#lx\n\n",**p_pnum,*p_pnum,p_pnum);
     //**p_pnum = 10.000000, *p_pnum = 0x7ffcdf7ffd94, p_pnum = 0x7ffcdf7ffd88
     char arr[10] = {'a','d','m','i','n'};
     printf("arr[0]= %c, arr[5]= %c, arr[6]= %c, arr = %s\n",arr[0],arr[5],arr[6],arr);
     printf("&arr[0]= %#lx, &arr[1]= %#lx, arr= %#lx\n\n", &arr[0], &arr[1], arr);
     //arr[0]= a, arr[5]= , arr[6]= , arr = admin
     //&arr[0]= 0x7ffcdf7ffd70, &arr[1]= 0x7ffcdf7ffd71, arr= 0x7ffcdf7ffd70
     char* parr = NULL;
     parr = arr;
     printf("*parr = %c, *(parr+4)=%c, *(parr+5)=%c, parr = %s\n",*parr,*(parr+4),*(parr+5),parr);
     printf("parr = %#lx, parr+4 = %#lx, parr+5= %#lx\n\n", parr, parr+4, parr+5);
     //*parr = a, *(parr+4)=n, *(parr+5)=, parr = admin
     //parr = 0x7ffcdf7ffd70, parr+4 = 0x7ffcdf7ffd74, parr+5= 0x7ffcdf7ffd75
     char str[10]= "admin";
     printf("str[0]= %c, str[5]= %c, str[6]= %c, str = %s\n",str[0],str[5],str[6],str);
     printf("&str[0]= %#lx, &str[1]= %#lx, str = %#lx\n\n", &str[0], &str[1], str);
     //str[0]= a, str[5]= , str[6]= , str = admin
     //&str[0]= 0x7ffcdf7ffd60, &str[1]= 0x7ffcdf7ffd61, str = 0x7ffcdf7ffd60
     char* pstr = NULL;
     pstr = str;
     printf("*pstr= %c, *(pstr+4)= %c, *(pstr+5)= %c, pstr = %s\n", *pstr, *(pstr+4), *(pstr+5), pstr);
     printf("pstr = %#lx, pstr+4=%#lx, pstr+5= %#lx\n\n",pstr, pstr+4, pstr+5);
     //*pstr= a, *(pstr+4)= n, *(pstr+5)= , pstr = admin
     //pstr = 0x7ffcdf7ffd60, pstr+4=0x7ffcdf7ffd64, pstr+5= 0x7ffcdf7ffd65
 }

数值型指针

数值型指针: int* p;

如:

int num = 100;
int* p = &num;		//同时定义和初始化
int* p1 = NULL;		//定义
p1 = &num;			//初始化

字符型指针

字符型指针可以分为指针指向的是单字符还是字符数组两种

单字符

字符型指针: char* p;

char name = 'a';
char* p = &name;
printf("p = %c",*p);	//结果是 a

这里需要注意需要用 占位符 %c 去承接内容(或者说显示内容)

字符数组

字符型指针:char* p;

char arr[6] = {'a','d','m','i','n','\0'};
printf("arr = %s, arr = %#lx\n",arr,arr);	//admin,0x7ffffffc0
printf("arr[0]= %c,arr[1]= %c\n",arr[0],arr[1]);//a,d
char* parr = NULL;
parr = arr;     //也可以 parr =  &arr,但是编译时会报warning
printf("parr = %s, parr = %#lx\n", parr,parr);	//admin,0x7ffffffc0
printf("*(parr)= %c,*(parr + 1) = %c\n",*parr, *(parr+1));  

这里需要注意字符数组末尾需要加‘\0’字符表示字符数组结束,或者编译器自己会自动加上,所以在定义字符数组长度时需要加+1。

注意 字符数组名既可以表示地址也可以表示整个字符数组的内容,而不是第一个字符。相应的指针也是整个字符数组的内容。

printf("arr = %c\n", arr);
printf("parr = %c\n", parr);

以上两行代码可以编译过但是不能显示内容,需要用占位符%s去承接整个字符数组内容。

字符串型指针

字符型指针:char* p;

char str[5] = "admin";
printf("str = %s,str = %#lx\n",str,str); // admin,0x7ffffffe0.
printf("str[0]= %c, str[1]= %c\n",str[0],str[1]);	// a,d
char* pstr = NULL;
pstr = str;
printf("pstr = %s, pstr = %#lx\n",pstr,pstr); // admin,0x7ffffffe0.
printf("*pstr = %c,*(pstr+1) = %c\n",*pstr,*(pstr+1)); // a,d

如代码中结果显示所示,字符串数组名即是地址,同时也是数组内容,根据占位符的不同显示不同内容,占位符为%s时显示字符串,%#lx显示地址。同样的对于赋值给的指针变量也具有同样的功能。

但是如果这里

printf("str = %c\n",str);	//可以编译过但是不显示任何信息

字符数组总结

字符数组和字符串数组名都可以即表示地址又表示地址对应的内容,注意看需要它以什么形式显示,显示内容用%s,显示地址用%#lx。

字符数组和字符串数组名对应的地址都是第一个字符所在的地址。如上面的代码中 &arr[0] 和 arr 得到的地址相同

到此这篇关于C语言超详细讲解指针的使用的文章就介绍到这了,更多相关C语言指针内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2022-05-20

C语言详细讲解指针数组的用法

目录 1. 指针数组定义方法 2. 指针的指针(二级指针) 3. 字符串和指针 4. 数组指针 定义方法 数组指针的用法 1. 指针数组定义方法 格式: 类型说明符 *数组名[ 元素个数 ] int *p[10]; // 定义了一个整型指针数组p,有10个元素,都是int *类型的变量 指针数组的分类: 同指针类型的分类,见上一篇 大多数情况下,指针数组都用来保存多个字符串. #include <stdio.h> int main() { char *name[5] = {"Hell

C语言超详细讲解指针的概念与使用

目录 一.指针与一维数组 1. 指针与数组基础 2. 指针与数组 3. 一个思考 二.指针与字符串 三.指针和二维数组 1. 指针数组与数组指针 2. 指针数组 3. 数组指针 一.指针与一维数组 1. 指针与数组基础 先说明几点干货: 1. 数组是变量的集合,并且数组中的多个变量在内存空间上是连续存储的. 2. 数组名是数组的入口地址,同时也是首元素的地址,数组名是一个地址常量,不能更改. 3. 数组的指针是指数组在内存中的起始地址,数组元素的地址是指数组元素在内存中的其实地址. 对于第一点数

C语言&nbsp;从根本上理解指针

目录 一.* 的意义 二.传值调用与传址调用 三.常量与指针 四.小结 一.* 的意义 在指针声明时,* 号表示所声明的变量为指针 在指针使用时,* 号表示取指针所指向的内存空间中的值 如下: int i = 0; int j = 0; int* p = &i; //指针声明 j = *p; //取值 变量 p 保存着变量 i 的内存地址,即:p <--> &i *p <--> i * 号类似一把钥匙,通过这把钥匙可以打开内存,读取内存中的值. 下面看一个指针的使用

c语言中的二级指针做函数参数说明

目录 二级指针做函数参数 二级指针作为形参简单实例分析 实例 一级指针二级指针做函数形参 下面看看实例 二级指针做函数参数 1.用指针做函数参数申请动态内存的问题 //如果函数参数是指针,不能用一级指针做函数参数实现申请动态内存   void getMemory(char *p, int num) {     p = (char *)malloc(sizeof(char)*num); } void main() {     char *str = NULL;     getMemory(str,

C语言一看就懂的指针与结构体介绍

目录 指针 结构体 指针 指针是C语言或者是c++里面最让人头疼的内容之一,正所谓指针在手,可以任指天下,这里只是简单的介绍指针的一些概念,后期我们将会深入剖析指针的基本原理. 注意:一个汉字占2个字节! 首先我们需要认识一下内存这个基本概念: 内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的,为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节,为了能够有效的访问到内存中的每个单元,就把内存单元进行了编号,这些编号被称为内存单元的地址. #inc

C语言进阶教程之函数指针详解

目录 一.函数指针 1.概念 1.2函数指针的使用方法 1.3练习巩固 1.4小结一下 二.阅读两段有趣的代码 1.( *(void( *)( ))0 )( ) 2.void (* signal(int,void( * )( int ) ) )(int) 附:函数指针的应用——函数回调 总结 一.函数指针 1.概念 函数指针:首先它是一个指针,一个指向函数的指针,在内存空间中存放的是函数的地址: 请看示例: int main(){ int a = 10; int*pa = &a; char ch

C语言由浅入深理解指针

目录 1. 相关概念 2. 指针的定义方法 3. 指针的分类 4. 指针和变量的关系 5. 指针与数组的关系 6. 指针的运算 1. 相关概念 操作系统给每个存储单元分配了一个编号,从ox00 00 00 00~0xff ff ff ff,这个编号称为地址,指针就是地址 指针变量:即这个变量用来存放一个地址编号 无论什么类型的地址,都是存储单元的变换,在32位平台下都是4个字节,即任何类型的指针变量都是4个字节大小,64位操作系统占8个字节. 对应类型的指针变量,只能存放对应类型的地址.例如整型

C语言中二级指针解析(指向指针的指针)

目录 二级指针(指向指针的指针) 二级指针的定义与理解 二级指针定义格式 二级指针赋值实例 二级指针(指向指针的指针) 指针可以指向一份普通类型的数据,例如 int.double.char 等,也可以指向一份指针类型的数据,例如 int *.double *.char * 等. 如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针. 假设有一个 int 类型的变量 a,p1是指向 a 的指针变量,p2 又是指向 p1 的指针变量,它们的关系如下图所示: 将这种关系转换为C语

C语言中二级指针的实例详解

C语言中二级指针的实例详解 用图说明 示例代码: #include <stdio.h> int main(int argc, const char * argv[]) { // int a = 5; int *p1 = &a; //-打印地址-----地址相同--------------- printf("&a = %p\n", &a);// printf("p1 = %p\n", p1);// int **p2 = &p

Go语言中结构体方法副本传参与指针传参的区别介绍

GO语言结构体方法跟结构体指针方法的区别 首先,我定了三个接口.一个结构和三个方法: type DeptModeA interface { Name() string SetName(name string) } type DeptModeB interface { Relocate(building string, floor uint8) } type Dept struct { name string building string floor uint8 Key string } fun

详细分析c++ const 指针与指向const的指针

最近在复习C++,指针这块真的是重难点,很久了也没有去理会,今晚好好总结一下const指针,好久没有写过博客了,记录一下~ const指针的定义: const指针是指针变量的值一经初始化,就不可以改变指向,初始化是必要的.其定义形式如下: type *const 指针名称; 声明指针时,可以在类型前或后使用关键字const,也可在两个位置都使用.例如,下面都是合法的声明,但是含义大不同: const int * pOne;    //指向整形常量 的指针,它指向的值不能修改 int * cons

C语言 函数指针(指向函数的指针)详解

一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似.我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数.这种指针就是函数指针. 函数指针的定义形式为: returnType (*pointerName)(param list); returnType 为函数返回值类型,pointerNmae 为指针名称,param list 为函数参数列表.参数列表中

深入const int *p与int * const p的区别详解(常量指针与指向常量的指针)

对于指针和常量,有以下三种形式都是正确的: 复制代码 代码如下: const char * myPtr = &char_A;//指向常量的指针char * const myPtr = &char_A;//常量的指针const char * const myPtr = &char_A;//指向常量的常量指针 下面依次对这三种类型进行介绍.因为*操作符是左操作符,左操作符的优先级是从右到左,对于1.常量指针(Constant Pointers) 复制代码 代码如下: int * con

C++中指向对象的常指针与指向常对象的指针详解

指向对象的常指针 将指向对象的指针变量声明为const型,并使之初始化,这样指针值始终保持为其初始值,不能改变. 复制代码 代码如下: Time t1(10,12,15),t2;Time * const ptr1=&t1;ptr1=&t2; 定义指向对象的常指针的一般形式为 类名    *    const    指针变量=对象地址; 注意应该在定义指针变量时使之初始化 指向对象的常指针变量的值不能被改变,即始终指向同一个对象,但可以改变其所指向对象中的数据成员(非const型)的值. 往

C语言中的函数指针学习笔记

一.定义函数指针 return_type (*func_pointer)(parameter_list) 普通指针变量的定义 int * p; char * pointer; 类型的限定都在变量前面: 函数指针类型的限定是前后都有,前面是返回类型,后面是输入参数. 利用typedef 可以简化上面的表达方式. typedef return_type (*FunctionPointer) (parameter_list); FunctionPointer func_pointer; 这样是不是容易

详解C语言函数返回值解析

详解C语言函数返回值解析 程序一: int main() { int *p; int i; int*fun(void); p=fun(); for(i=0;i<3;i++) { printf("%d\n",*p); p++; } return 0; }; int* fun(void) { static int str[]={1,2,3,4,5}; int*q=str; return q; } //不能正确返回 虽然str是在动态变量区,而该动态变量是局部的,函数结束时不保留的.

C语言中的指针以及二级指针代码详解

很多初学者都对C中的指针很迷糊,希望这篇blog能帮助到大家: 1.什么是"指针": 在执行C程序的时候,由于我们的数据是存储在内存中的.所以对于C程序本身来说,如果想找到相应被调用的数据,就要知道存储该数据的内存地址是多少,换言之,C程序通过已知的内存地址到相应的内存位置存储数据. 这里简单说一下内存管理(对于初学者来说.为了避免专业术语引发的理解问题,下面的叙述尽量避免专业定义:),对于现代计算机系统来说,内存空间分为两个区域,一个是"数据区",一个是"

深入解析C语言中函数指针的定义与使用

1.函数指针的定义     函数是由执行语句组成的指令序列或者代码,这些代码的有序集合根据其大小被分配到一定的内存空间中,这一片内存空间的起始地址就成为函数的地址,不同的函数有不同的函数地址,编译器通过函数名来索引函数的入口地址,为了方便操作类型属性相同的函数,c/c++引入了函数指针,函数指针就是指向代码入口地址的指针,是指向函数的指针变量. 因而"函数指针"本身首先应该是指针变量,只不过该指针变量指向函数.这正如用指针变量可指向整形变量.字符型.数组一样,这里是指向函数.C在编译时