指针




指针是一种特殊变量(存储内存地址)。当然它本身也是占用内存的,所以会带来一个问题,那就是指针存在以下概念:指针的类型(int* 一个整型指针),指针指向的类型(int* p = 5, 说明指针p指向了一个整型),指针的值就是内存中5的存储地址,指针的内存地址就是存储指针占用内存的地址。下面我们来分数据类型学习指针,这里只介绍常用指针,不涉及和数组相关的指针(在数据博客中会讲解)、字符串指针的完整讲解(在字符串博客中会讲解)、还有指针的指针,也不涉及。本博客C编译标准以GNU为准,不一定遵从C99,更不一定符合Windows查下的C编译器的结果。

![](https://img2018.cnblogs.com/blog/1070321/201812/1070321-20181225143010954-930409011.png)

基本数据类型



1、整型


整型指针可以在定义时候直接初始化赋值,经过测试double和float并不支持该赋值方式。

int* p_integer = 5;

也可以通过指针等于一个变量的引用的方式赋值;例如

int var_integer = 5;
int *p_integer;
p_integer = &var_integer;

调用方式也很简单,直接p_integer是地址,&p_integer代表的是存储这个指针的内存的地址,*p_integer代表的就是值了,如下文代码所示

//整型指针
int *integer1; //定义一个整型指针
int *integer2 = 10; //定义初始化一个整型指针赋值
int var_int = 5;
integer1 = &var_int;//赋值
/*调用整型指针*/
printf("%d\n", integer1);//打印integer1的地址,直接使用指针是地址
printf("%d\n", &integer2);//打印integer2的地址,引用指针也是地址,是存储指针的内存的地址
printf("%d\n", *integer1);//打印数值,*指针名调用的是数值
printf("%d\n", &var_int);//也是地址,因为赋值的原因,这个地址就是指针integer1的地址

浮点、双精度类型


赋值方式不支持定义的时候直接初始化

//浮点数指针
double var_dou = 6.32;
double *p_dou;
p_dou = &var_dou;
float var_flo = 7.10;
float *p_flo;
p_flo= &var_flo;

调用方式也很简单,浮点数和双精度其实和整型指针差别不大,不做过多的详细叙述

//double *p = 6.32; 这是错误的
printf("%d\n", p_dou);//打印p_dou的地址,直接使用指针是地址
printf("%d\n", p_flo);//打印p_flo的地址,直接使用指针是地址,引用指针是存指针这个地址的指针存储在内存中的位置
printf("%d\n", &p_flo);//打印的是p_flo存储空间的地址
printf("%f\n", *p_dou);//打印数值,*指针名调用的是数值
printf("%d\n", &var_flo);//也是地址,因为赋值的原因,这个地址就是指针p_flo的地址

字符、字符串类型指针


字符、字符串类型指针简要,定义和赋值,很简单,注意对字符串来讲,实际上是一个char数组。这个地方在做字符串操作的时候,传进函数的参数有要求,例如strcat,一定要传数组名,不能随意传入,有坑。

char *p_char = 'a';//这是一个字符指针,指针指向a这个字符,没啥问题。
char *p_str = "abcd";//字符串指针,指针保存的地址是首字母的内存地址
char var_str[10] = "asdf";
char *p_str;
p_str = &var_str

调用也不难,这里注意两个问题,一个是在做一些操作时候,数组名带有数据size信息的,直接定义的指针没有size信息,也意味着没有多余的空间,所以strcat这类函数会报段错误。同理数组大小不够也是一样。第二。数组首地址也就是数组名的地址也是指向字符串(字符数组的首地址),在这个时候*指针表达的是第一个字符。

char *p_str1 = "abcd";//定义字符串,并赋值;
char array[10] = "abcdefg";
char *p_str2;
p_str2 = array;//给字符串(字符数组)的首地址也就是数组的名字,赋值字符串
char *p_char = 'a';//赋值字符
printf("%s\n", p_str1);//打印p_str1字符串
printf("%d\n", &p_str2);//打印p_str2的地址,直接使用指针是地址,引用指针是存指针这个地址的指针存储在内存中的位置
printf("%c\n", *p_str1);//打印第一个字符
//printf("%x\n", *p_char);//没找到这个到底输出啥?bug-1
printf("%d\n", &p_char);//打印地址,因为赋值的原因,这个地址就是指针'a'的地址
printf("%c\n", p_char);//打印唯一一个字符

复杂数据结构的指针



结构体


定义和赋值

typedef struct Student {
char name[10];
int age;
}student;
struct Student * p_struct;
student * p_struct;
strcpy(p_struct->name, "Tom");
p_struct->age = 10;
student var_struct = {"Bill", 8};
p_struct = &var_struct

调用也不难

student var_stu = {"Tom", 8};
student *p_stu;
p_stu = &var_stu;//赋值
printf("%s\n",p_stu->name);//名字
printf("%d\n",p_stu->age);//年龄
printf("%d\n",p_stu);//结构体对象地址
printf("%d\n",&var_stu);//结构体对象地址

枚举体和共用体

和结构体类似,内部字段调用也是用->,定义和赋值没啥差别

//枚举体、共用体指针
typedef enum Gender {male, female}gender;
gender var_enum = male;
gender *p_enum1 = female;
gender *p_enum2;
p_enum2 = &var_enum;
//printf("%d", *p_enum1);
printf("%d\n", p_enum1);//枚举体的值
printf("%d\n", &p_enum2);//指针地址
//printf("%d", *p_enum2);
printf("%d\n", p_enum2);//枚举体的值
printf("%d\n", &var_enum);//枚举体变量的地址
printf("******************************************************************\n");
typedef union ID {char _id_char[10]; int _id_int;}id;//定义共用体,一个数据结构,一个变量多种数据类型,但是在同一时刻只能有一种数据类型可以被使用。
id __id;
__id._id_int = 8;
printf("%d\n", __id._id_int);
id *p_uni;
p_uni = &__id;
p_uni->_id_int = 6;
printf("%d\n", p_uni->_id_int);
printf("******************************************************************\n");

特殊类型指针



void指针


常见于在函数中参数可以为任意类型指针时候使用,在函数体内再做类型转换

void *buffer;
char *p_addr = (char *)buffer;

函数指针

指针函数是返回指针的函数,函数指针如下,并不是返回指针的函数,而是用于类似python的map、reduce、lamdba等功能的函数动态选择时候。

char* (*func)(char *result, char *str1,char *str2);

char* string_add(char *result,char *str1,char *str2){
//char result[20] = "";
printf("%s\n", str1);
printf("%s\n", str2);
strcat(result, str1);
strcat(result, str2);
printf("%s\n", result);
return result;
}
//使用
func = string_add;
char result[20] = "";
printf("%s\n", (*func)(result,"T","ED"));

C语言程序设计--指针基础的更多相关文章

  1. C语言函数指针基础

    本文写的非常详细,因为我想为初学者建立一个意识模型,来帮助他们理解函数指针的语法和基础.如果你不讨厌事无巨细,请尽情阅读吧. 函数指针虽然在语法上让人有些迷惑,但不失为一种有趣而强大的工具.本文将从C ...

  2. C语言程序设计(基础)- 第7周作业(新)

    要求一(25经验值) 完成PTA中题目集名为<usth-C语言基础-第七周作业>和<usth-C语言基础-12周PTA作业>中的所有题目. 注意1:<usth-C语言基础 ...

  3. C语言程序设计(基础)- 第7周作业

    为了防止误解,自从本周开始ppt.pta作业.博客作业的命名均与学校教学周一致. 要求一(20经验值) 完成PTA中题目集名为<usth-C语言基础-第七周作业>和<usth-C语言 ...

  4. C语言程序设计(基础)- 第2周作业

    1.阅读提问的智慧,要求仔细阅读链接内容,用自己的话描述你的收获,并举例子说明应该如何提问. 2.所有同学请在自己电脑上配置git.编译器(win10 系统的话就Dev-C++).翻译软件,十一回校后 ...

  5. C语言之指针基础概念

    今天就写一下关于C语言指针的一些感想吧. 很多同学都搞不懂指针,我一开始也云里雾里没看懂指针,而且老师又把指针说得很难的样子.其实主要是把指针”*“的作用给弄混了,不用畏惧,细心点看就可以了. 首先简 ...

  6. C语言程序设计(基础)- 第0次作业

    亲爱的同学们,恭喜你成为一名大学生,我也很荣幸能够带大家一起学习大学的第一门专业基础课.还在军训的你,肯定对大学生活和计算机专业有着美好的憧憬,那么大学生活是什么样子的那?计算机专业应该怎么学习那?请 ...

  7. C语言程序设计(基础)最后一次作业-- 总结报告

    本次作业是本学期的最后一次作业,有始有终,本次作业回顾下本学期的第0次作业,回答下面几个问题. 注意:在回答问题时请不要简单的回答 "不是","是".请把这当成 ...

  8. C语言程序设计(基础)- 第14、15周作业

    从本周开始,将作业标记为学校自然周,而不是开课的周数. 要求一(25经验值) 完成14.15周的所有PTA中题目集. 注意1:一周两次pta作业,包括四次. 要求二(50经验值) 博客的具体书写内容和 ...

  9. C语言程序设计(基础)- 第6周作业

    一.PTA作业 完成PTA第六周作业中4个题目的思路列在博客中. 1.7-1 高速公路超速处罚 2.7-2 计算油费 3.7-3 比较大小 4.7-4 两个数的简单计算器 (必须使用switch结构实 ...

随机推荐

  1. iOS:获取 NSDate 的年

    NSDate *currentDate = [NSDate date]; NSCalendar* calendar = [NSCalendar currentCalendar]; NSDateComp ...

  2. 解决:ADODB.Stream 错误 '800a0bbc' 写入文件失败

    重装更改目录为e盘后,上传文件出现问题.解决方法: 调用adodb.stream的savetofile方法时发生错误, ADODB.Stream 错误 800a0bbc 写入文件失败.(msxml3. ...

  3. [转]java的(PO,VO,TO,BO,DAO,POJO)类名包名解释

    java的(PO,VO,TO,BO,DAO,POJO)类名包名解释 2015-04-28 20:11 by Loull, 18 阅读, 0 评论, 收藏, 编辑 VO:值对象.视图对象 PO:持久对象 ...

  4. sar监控工具详解

    转自http://www.cnblogs.com/Amaranthus/p/3745680.html SAR NAME: SAR报告,收集,保存系统活动信息 语法: sar  [ -A ] [ -b ...

  5. windows下卸载oracle11g

    oracle11g卸载   oracle11g卸载 卸载oracle: 1.开始--控制面板--性能和维护--管理工具--服务    停止所有的oracle服务. 2.开始--程序--oracle-- ...

  6. 小企业是否能用得上"ITIL"?

    在小型IT部门中,明显存在着迫切的IT管理需求.但目前主流ITSM解决方案的价格.实施周期.复杂程度.对人力资源的占用等使他们难以承受.     浦发机械公司的计算机部经理老张带着十几个员工,经过数年 ...

  7. position absolute定位之所属的containing box

    http://www.w3.org/TR/CSS2/visudet.html#containing-block-details http://www.zhihu.com/question/199267 ...

  8. Hash冲突的解决方法

    虽然我们不希望发生冲突,但实际上发生冲突的可能性仍是存在的.当关键字值域远大于哈希表的长度,而且事先并不知道关键字的具体取值时.冲突就难免会发 生.另外,当关键字的实际取值大于哈希表的长度时,而且表中 ...

  9. flexbox子盒子flex属性

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. MFC框架程序解析

    MFC的 程序框架: WinMain函数:程序首先到达全局变量theApp,再到达theAPP的构造函数,最后到达WinMain函数处. 问:为何要定义一个全局对象theAPP,让其在WinMain函 ...