指针




指针是一种特殊变量(存储内存地址)。当然它本身也是占用内存的,所以会带来一个问题,那就是指针存在以下概念:指针的类型(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. mysql 5.1超过默认8小时空闲时间解决办法(错误:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure)

    报错: MySQL第二天早上第一次连接超时报错, com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications lin ...

  2. shell特殊符号cut命令 sort_wc_uniq命令 tee_tr_split命令 shell特殊符号

    shell特殊符号cut命令 特殊符号 *  通配符,任意个任意字符 ? 任意一个字符 # 注释字符 \  脱义字符 c=\$a\$b echo  $c | 管道符 cat  1.txt |less ...

  3. MyBatis的深入原理分析之1-架构设计以及实例分析

    MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简单.优雅.本文主要讲述MyBatis的架构设计思路,并且讨论MyBatis的几个核心部件,然后结合一个select查询实例, ...

  4. Oracle高级查询之CONNECT BY

    为了方便大家学习和测试,所有的例子都是在Oracle自带用户Scott下建立的. Oracle中的select语句可以用start with ... connect by prior ...子句实现递 ...

  5. MarkDown技巧:两种方式实现页内跳转

    MarkDown技巧:两种方式实现页内跳转 本人邮箱:JohnTsai.Work@gmail.com,欢迎交流讨论. 欢迎转载,转载请注明网址:http://www.cnblogs.com/JohnT ...

  6. BarTender连接不上数据库怎么办

    由于各种原因,在使用BarTender连接到数据库时,有可能会出现无法连接的问题,下面下编就针对两种BarTender无法连接到数据库的问题,来教大家解决的方法. 第一种 BarTender无权打开文 ...

  7. 【QT】error: Failed to retrieve MSVC Environment from "\VC\vcvarsall.bat":

    安装QT后直接打开,报错. 需要删mysql环境变量. error: Failed to retrieve MSVC Environment from "D:\Englishpath\VS2 ...

  8. JS匿名函数理解

    匿名函数的基本形式为(function(){...})(); 前面的括号包含函数体,后面的括号就是给匿名函数传递参数并立即执行之 匿名函数的作用是避免全局变量的污染以及函数名的冲突   1.小括号的作 ...

  9. [AX2012]在SSRS报表中获取从Menuitem传入的记录

    在较早版本的AX中我们运行一个报表时会用到类RunBaseReport,从它扩展一个子类,再由它运行报表,一个典型的Axapta3中的例子: class ReportProdInfo extends ...

  10. webstorm批量查找,批量替换快捷键

    ctrl+shift+f:批量查找,我的webstorm11不能用ctrl+shift+f进行批量查找了,不知道什么原因,自己又胡乱实验了一下, 发现ctrl+shift+g+f可以批量查找 ctrl ...