一、指针与数组和字符串

1、指针与数组

当声明数时,编译器在连续的内存空间分配基本地址和足够的储存空间,以容纳数组的所有元素。基本地址是数组第一个元素(索引为0)的存储位置。编译器还把数组名定义为指向第一个元素的常量指针。

元素的地址是通过索引和数据类型的比例因子来计算的;例如: x[3]的地址 = 基本地址 + (3 x 整型数据的比例因子)

如何表示元素a[i][j]的(其中:int *p; p = a;);

0

1

2

3

4

5

1

2

3

4

p----指向第 0 行的指针;

p + i----指向第 i 行的指针;

*(p+i)----指向第 i 行的第一个元素的指针;

*(p+i)+j----指向第 i 行第 j 个元素的指针;

*((p+i)+j)----存储在(i, j)单元(即第 i 行第 j 列)的值。

数组 a 的基本地址为 &a[0][0],从这个地址开始,编译器按行为所有的元素分配连续的存储空间。例如:

int a[3][4] ={

{15,27,11,35},

{22,19,31,17},

{31,23,14,36}

}

数组a的存储如下:

|15 |27| 11| 35 |22 |19 |31 |17 |31 |23 |14 |36 | |--

如果把 p 声明为整型指针,并且初始地址为a[0][0](),那么:

a[i][j] = *(p+4*i+j);

2、指针与字符串

C语言支持另一种创建字符串的方法,即使用char类型的指针变量。例如:

char *str = "good";

上述声明语句创建了一个文本字符串,然后将其地址保存在指针变量str中;这样指针 str 就指向字符串 “good” 的第一个字符,如下所示:

|g(str) | o | o | d | \0 | |--

由此,可以用指针访问整个字符串:

printf("%s",str);

put(str);

当然,也可以用指针来访问字符串中的单个字符。

3、指针数组

指针的一项重要的应用就是处理字符串表,特别是处理行的长度可变的“凹凸不平的数组”时;例如:

char *name[3] = { "New Zealand", "Australia", "India" };

上面的声明语句只分配了28个字符,这足以保存所有的字符,具体如下:

|N| e |w | |Z |e |a |l |a| n| d| \0| |-- |A| u| s| t| r| a| l| i| a| \0| |I| n| d| i| a| \0| 下面的语句可以用来显示着三个名称:

for(i = 0; i <= 2; i++) printf("%s\n",name[i]);

要访问第 i 个名称的第 j 个字符,可以这样编写语句:

char c = *(name[i]+j);

二、指针与函数

1、将指针作为函数的参数

使用指针传递变量地址的函数调用过程称为引用调用(我们已经说过,传递变量实际值的过程称为 “按值调用”)。引用调用提供了一种机制,让被调用的函数可以修改调用函数中存储的值。 请注意以下代码:

//例一

void exchange(int *a, int *b)

{

int t;

t=*a;

*a=*b;

*b=t;

}

void main()

{

int x, y;

x = 100;

y = 200;

printf("%d ,%d\\n",x,y);

exchange(&x,&y);

printf("%d ,%d\\n",x,y);

}

//例二

void exchange(int *a, int *b)

{

int *t;

t=a;

a=b;

b=t;

printf("%d ,%d\n", *a, *b);

}

void main()

{

int x, y;

x = 100;

y = 200;

printf("%d ,%d\n", x, y);

exchange(&x,&y);

printf("%d ,%d\n", x, y);

}

代码例二并不会使x,y的值发生互换,因为当函数指针a,b获得x,y的地址后,作为值进行储存,交换a,b的值并没有改变其值(x,y的地址)指向的x,y的值。

2、函数返回指针

指针是C语言的一种数据类型,因此也可以使用函数返回一个指向调用函数的指针。请看下面的代码:

int *larger(int* , int*);/*prototype*/

main()

{

int a = 10;

int b = 20;

int *p;

p = larger(&a, &b);/*Function call*/

printf("%d",p);

}

int *larger(int *x, int *y)

{

if(*x > *y)

return(x);/*address of a*/

else

return(y);/*address of b*/

}

注意:返回的地址必须是调用函数中变量的地址。如果返回的是指向被调用函数中局部变量的地址;将产生错误。

3、指向函数的指针

与变量一样,函数也属于某种数据类型,在内存中也需要有储存地址。因此可以声明一个指向函数的指针。如同指向字符数组的指针,可以接收任意大小的字符数组一样,指向函数的指针可以指向任意的函数,如此可以减少函数的数量,使函数的功能更加强大。指向函数的指针声明如下:

type (*fptr)();

该语句告诉编译器,fptr为指向函数的的指针,返回type类型的值。用括号把*fptr括起来是必要的。记住,下面的语句:

type *gptr();

表示的是把gptr声明为函数,它返回一个指向type类型的指针。

请仔细关注以下代码:

#include

#include

#define PI 3.1415926

double table(double (*f)(), double, double, double);

double y(double);

double cos(double);

double table(double (*f)(), double min, double max, double step)

{

double a, value;

for(a = min;a <= max; a+=step){

value = (*f)(a);

printf("%5.2f %10.4f\n,a,value");

}

}

double y(double x)

{

return (2*x*x-x+1);

}

void main()

{

printf("table of y(x) = 2*x*x-x+1\n\n");

table(y, 0.0, 2.0, 0.5);

printf("table of cos(x)\n\n");

table(cos, 0.0, PI, 0.5);

}

三、指针与结构体

在前面章节中,我们讨论把结构体作为参数传递给函数。我们还看到这样的实例,其中函数接收整个结构体的副本,并在运行后把他返回给调用函数。正如我们前面介绍的那样,该方法无论是在运行速度还是在内存使用上都不是高效的。通过以指向结构体的指针作为传递参数,然后使用指针来操纵结构体成员,就可以克服该缺点。请看以下函数:

print_invent(struct *item)

{

printf("Name: %s\n", item->name);

printf("price:%f\n", item->price);

}

该函数可以用下面的语句来调用:

print_invent(&product);

请关注以下两点:

数组名表示的是第0个元素的地址。结构体变量的数组名也是如此;

运算符“->”、“.”、“()”和“[]”的有先级最高。正确理解优先级及关联性非常重要。

指针数据类型 java_C/C++ 指针的小结——指针与其它数据类型(数组、字符串、函数、结构体)的关系...相关推荐

  1. C语言结构体的定义与使用、结构体数组、指向结构体的指针(有代码详解)

    1.结构体的定义与使用 结构体是一种构造数据类型 把不同类型的数据组合成一个整体 结构体的定义形式: struct 结构体名{结构体所包含的变量或数组 }; 结构体是一种集合,它里面包含了多个变量或数 ...

  2. C语言中结构化数据(变量,指针,数组,字符串,结构体和联合)的内存表示

    目录 结构化数据表示 一.内存地址: 二.全局变量和局部变量的内存布局 三.数据在内存中的表示 四.数组在内存中的表示 五.字符串在内存中的表示 六.结构和联合在内存中的表示 结构化数据表示 一.内存 ...

  3. C语言笔记含源码(变量、输入输出、分支、循环、函数、数组、指针、字符串、结构体)小总结

    文章目录 一.变量与输入输出 二.分支语句 三.循环 四.函数 五.数组 六.指针 七.字符串 八.结构体 一.变量与输入输出 定义变量需要:类型.变量名.变量值(可有可无) #include < ...

  4. 初识C语言(1)(2)(3)(4) C语言入门 保姆级教程 变量 常量 字符串 转义字符 操作符 关键字 字符串 指针 函数 结构体 数组 选择语句 循环语句

    一.如何写C语言代码 1.编译器 2.创建项目 3.创建源文件 4.写代码 5.编译+链接+运行 项目名字不要汉语,不要特殊字符,不要加空格,项目路径一般为你想要的路径 C语言中,一般创建.c源文件, ...

  5. C语言—用结构体指针给数组赋值(结构体指针指向字符串,给字符串赋值)

    数组定义: char acBuf[sizeof(TRANS_HEAD_S) + sizeof(USER_HEAD_S) + 4] = {0}; 结构体定义: typedef struct {int i ...

  6. c语言中指针数组赋值字符串,C语言—用结构体指针给数组赋值(结构体指针指向字符串,给字符串赋值)...

    数组定义: char acBuf[sizeof(TRANS_HEAD_S) + sizeof(USER_HEAD_S) + 4] = {0}; 结构体定义: typedef struct { int ...

  7. C语言 字符串转结构体,字符串指针转化为结构体指针!

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include struct abc { unsigned int num; char c; }; typedef abc* pabc ...

  8. STM32的C语言重点知识(1.C语言数据类型+2.C语言宏定义+3.C语言typedef+4.C语言结构体+5.C语言枚举)

    1.C语言数据类型: 注:目的是看到stdint,如看到int8_t;uint16_t能够瞬间知道表示的是char,8字节:unsigned short,16字节. ST关键字意思是在老版本的引脚说明 ...

  9. 【黑马程序员 C++教程从0到1入门编程】【笔记1】数据类型、运算符、程序流程结构、数组、函数、指针、结构体

    黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难 文章目录 1.C++初识 1.1 第一个c++程序 1.2 注释 1.3 变量 1.4 常量 1.5 关键字 1.6 标识符命名规则 2 ...

  10. C++阶段01笔记汇总【C++软件安装、C++初识、数据类型、运算符、程序流程结构、数组、函数、指针、结构体】

    C++| 匠心之作 从0到1入门学编程[视频+课件+笔记+源码] 目录 C++课程安排 1 C++初识 1.1 第一个C++程序 1.1.1 创建项目 1.1.2 创建文件 1.1.3 编写代码 1. ...

最新文章

  1. 通用数据级别权限的框架设计与实现(4)-单条记录的权限控制
  2. element ui 图片控件 排序_Element-ui上传图片后隐藏上存控件
  3. 对想进入Unity开发新人的一些建议
  4. 2019年3月20日 894. All Possible Full Binary Trees
  5. 对于初学者而言!如何处理 Python 入门难以进步的现象?
  6. boost::geometry::math::equals用法的测试程序
  7. mysql 导入导出.sql文件
  8. Windows 系统版本判断
  9. win8.1 USB启动盘制作(不支持UEFI,不支持GPT分区)
  10. 深入react技术栈(10):受控组件和非受控组件
  11. 4乘4方格走的路线_苏州周边4个冷门自驾游路线景点推荐
  12. 12306否认60万用户数据泄露
  13. Java报警110_Java入门基础SL110
  14. nagios 安装步骤-1
  15. android热门消息推送横向测评![转]
  16. Chrome十周年,作了一次死
  17. 【CS229】代价函数与梯度下降
  18. 计算机网络实验教程钱德沛_计算机网络实验教程完成版.pdf
  19. 联想重装系统去掉保护_如何去掉联想硬盘保护系统?
  20. 计算机一级exc除法函数,excel除法函数 excel除法如何表示

热门文章

  1. Exchange server 2010系列教程之三 发送邮件测试
  2. python 3 面向过程编程
  3. 构建微服务:Spring boot 入门篇
  4. 登录时记住用户名和密码及cookie案例应用
  5. Javascript学习总结 - JS基础系列 二
  6. 网络工程师第五站-有线、无线同网段混合组网(多FAT案例)
  7. linux下web压力测试工具ab使用及详解
  8. iphone开发我的新浪微博客户端-用户登录准备篇(1.1)
  9. leetcode107. 二叉树的层次遍历 II
  10. c# 实现刷卡_如何在RecyclerView中实现“刷卡选项”