指针就是地址。
指针变量:是个变量,用来存放一个地址编号。(32位下,指针变量是4个字节)
对应类型的指针变量,只能存放对应类型的变量的地址。

扩展:char ch; ch占一个字节,它有一个地址编号,这个地址编号就是ch的地址。
int a; a占4个字节,它占有4个字节的储存单元,有4个地址编号。

指针的定义:
数据类型 * 指针变量名;
int *p; (*用来修饰变量的,说明p是个指针变量)。

关于指针的运算符
&:取地址(获取变量的地址)。*:取值(在定义指针变量时起标识作用,除此之外表示获取一个指针变量保存的地址里面的内容)。

代码1:

#include <stdio.h>
int main(int argc,char *argv[])
{int a = 100;int* p;p = &a;printf("a=%d\n", a);printf("*p=%d\n", *p);printf("&a=%d\n", &a);printf("p=%d\n", p);system("pause");return 0;
}

结果:

a=100
*p=100
&a=1898480
p=1898480

扩展:如果在一行中定义了多个指针变量,每个指针变量前面都需要加*来修饰。
int *p,*q;说明定义了两个指针。
int *p,q;说明只定义了一个指针。

指针和变量的关系:
int p;
int a;
p=&a;
就可得到
p与a是一样的,改变其中任意一个的值,另一个也会跟着改变。

注:1.指针变量可以在定义的时候初始化
int a;
int *p=&a;
2.指针变量只能保存开辟好空间的地址,不能随意保存地址。

代码2:

#include <stdio.h>
#pragma warning(disable:4996)int main(int argc, char* argv[])
{int* p1, * p2, temp, a, b;p1 = &a;p2 = &b;printf("请输入:a,b的值:\n");scanf("%d,%d", &a, &b);//p1和p2指向的变量赋值temp = *p1;*p1 = *p2;*p2 = temp;printf("a=%d,b=%d\n",a ,b );printf("*p1=%d,*p2=%d\n", *p1, *p2);return 0;
}

结果:

请输入:a,b的值:
34,65
a=65,b=34
*p1=65,*p2=34

指针与数组元素之间的关系:
数组:多个相同类型的变量的集合,每个变量都占内存空间,都有地址编号。
指针变量可以存放数组元素的地址。
例:
int a[10];
int *p;
p=&a[0];//指针变量p保存了数组a中第0个元素的地址,即a[0]的地址。

数组元素的引用方法:
方法1:数组名[下标]
int a[10];
a[2]=100;

方法2:指针名加下标
int a[10];
int *p;
p=a;
p[2]=100; //因为p和a等价
补充:c语言规定:数组的名称就是数组的首地址,即第0个元素的地址,是一个常数。
注:p和a不同,p是指针变量,而a是常量。所以可用等号给p赋值,但不能给a赋值。(int a[10];a++是错误的)

方法3:通过指针运算加取值的方法来引用数组的元素:
int a[10];
int *p;
p=a;
*(p+2)=100; //相当于p[2]=100; p是第0个元素的地址,p+2是a[2]这个元素的地址。

代码3:

#include <stdio.h>
#pragma warning(disable:4996)int main(int argc, char* argv[])
{int a[5] = { 0,1,2,3,4 };int* p;p = a;printf("a[2]=%d\n", a[2]);printf("p[2]=%d\n", p[2]);printf("*(p+2)=%d\n", *(p + 2));printf("*(a+2)=%d\n", *(a + 2));return 0;
}

结果:

a[2]=2
p[2]=2
*(p+2)=2
*(a+2)=2

指针的运算:
1.指针可以加一个整数,以下指几个方向指向的变量,结果还是地址。
2.两个相同类型的指针可以比较大小。(指向前面元素的指针小于指向后面元素的指针)。
3.两个相同类型的指针可以做减法(结果:两个指针指向的中间有多少个元素)。

指针数组:
1.指针和数组的关系:
指针可以保存数组元素的地址
可以定义一个数组,数组中有若干个相同类型的指针变量,这个数组被称为指针数组。

指针数组的概念:
指针数组本身是个数组,是个指针数组,是若干个相同类型的指针变量构成的集合。
(注:一般遇到这样的叠词,本质就是后者)

定义方法:
int *p[10]; //定义了一个整型的指针数组p,有10个元素p[0]-p[9];
每个元素都是int *类型的变量。

例:
int *p[10];
int a;
p[1]=&a;
int b[10];
p[2]=&b[3];
p[2]和*(p+2)是等价的,都是指针数组中的第2个元素。

代码4:

#include <stdio.h>
#pragma warning(disable:4996)int main(int argc, char* argv[])
{//大多数情况下,指针数组都用来保存多个字符串char* name[5] = { "Follow me","BASIC","Greatwall","FORTRAN","Com" };int i;for(i=0;i<5;i++){printf("%s\n", name[i]);}return 0;
}

结果:

Follow me
BASIC
Greatwall
FORTRAN
Com

指针的指针:即指针的地址。
int a=0x1234;
int *p=&a; *p=a
int **q=&p; **q=*P=a

代码5:

#include <stdio.h>
#pragma warning(disable:4996)int main(int argc, char* argv[])
{int a = 100;//定义一个一级指针//一级指针用于保存普通变量的地址int* p = &a;//定义一个二级指针//二级指针用于保存一级指针的地址int** q = &p;printf("a=%d %d %d\n", a, *p, **q);printf("&a=%d %d %d\n", &a, p, *q);printf("&p=%d %d ", &p, q);return 0;
}

结果:

a=100 100 100
&a=19921140 19921140 19921140
&p=19921128 19921128

字符串和指针:
字符串概念:以“\0”结尾的若干个字符的集合。
字符串存储形式:数组(在内存区开辟了一段空间存放字符串),字符串指针(在文字常量区开辟了一段空间存放字符串,将字符串的首地址赋值给str),堆(使用malloc函数在堆区申请空间,将字符串拷贝到堆区)。

1.char string[100]="I love C!"
str[0]='y';//正确可以修改
2.char *str="I love C" (几乎不用,str只能存放字符地址编号,所以说I love C不能存放在str指针变量中)
*str='y';//错误 存放在文字常量区,不可修改
3.char *str=(char *)malloc(10*sizeof(char));//动态申请了10个字节的储存空间(必须先开辟空间 再初始化)
strcpy(str,"I love C");
*str='y';//正确 因为堆区内容可修改

注:str指针指向的内容不能把修改,要看str指向哪里
str指向文字常量区的时候,内存里的内容不可修改;
str指向栈,堆,静态全局区的时候,内容的内容可以修改;

注:
char buf_aver[128];
buf_aver="helllo kitty"; //错误 因为字符数组的名字是个常量
strcpy(buf_aver,"hello kitty"); //正确char *buf_aver;
buf_aver="helllo kitty"; //正确
strcpy(buf_aver,"hello kitty"); //错误

数组指针:
二维数组:可看成多个一维数组构成,可认为二维数组的每一个元素都是一个一维数组。
例:int a[3][5]; 定义了一个3行5列的二维数组,可认为由3个一维数组构成,每个元素是一个一维数组
回顾:数组的的名字是数组的首地址,是第0个元素的地址,是个常量,数组名字加1指向下个元素
二维数组a中,a+1指向下一个元素,即下一个一位数组,即下一行。
代码6:

#include<stdio.h>
int main(int arg, char* argv[])
{int a[3][5];printf("a=%p\n", a);printf("a+1=%p\n", a + 1);return 0;
}

结果:

a=0021F774
a+1=0021F788

数组指针本身是个指针,指向一个数组,加1跳一个数组,即指向下个数组。
数组指针的作用:保存二维数组的首地址。
定义方法:
int (*p)[5]; //定义了一个数组指针变量p,p指向的是整型的有5个元素的数组。
p+1往下指5个整型,跳过一个有5 个整型元素的数组。

代码7:

#include<stdio.h>
int main(int arg, char* argv[])
{int a[3][5];int(*p)[5];//定义了一个数组指针变量p,p+1跳一个有5个元素的整型数组printf("a=%p\n", a);printf("a+1=%p\n", a + 1);p = a;printf("p=%p\n", p);printf("p+1=%p\n", p+1);return 0;
}

结果:

a=00CFFA78
a+1=00CFFA8C
p=00CFFA78
p+1=00CFFA8C

数组指针用法:可以将二维数组的首地址传递给另一个函数里面,此时函数的形参就需要定义为数组指针。
代码8:

#include<stdio.h>
void fun(int(*p)[5], int x, int y)
{p[0][1] = 101;
}
void test2()
{int i, j;int a[3][5] = {0};fun(a, 3, 5);for (i = 0; i < 3; i++){for (j = 0; j < 5; j++)printf("%d ", a[i][j]);printf("\n");}
}
int main(int arg, char* argv[])
{test2();return 0;
}

结果:

0 101 0 0 0
0 0 0 0 0
0 0 0 0 0

各种数组指针的定义:
1.一维数组指针,加1后指向下一个一维数组
2.二维数组指针,加1后指向下一个二维数组

注意:
1.指针数组:是个数组,由若干个相同类型的指针构成集合
int *p[10]; //数组p有10个int *类型的指针变量构成,分别为p[0]-p[9];
2.数组指针:本身是指针,指向一个数组,加1跳一个数组。
int (*p)[10];
p是个数组指针
3.指针的指针:
int **P;
int *q;
p=&q;

8.数组名字区地址:变成数组指针。
一维数组名字取地址,变成一维数组指针,加1跳一个一维数组。
int a[10];
a+1跳一个整型元素,是a[1]的地址。
a和a+1相差一个元素,4个字节,
&a就变成了一个一维数组指针,是int (*p)[10]类型的。
(&a)+1就和&a相差一个数组即10个元素即40个字节。

9.数组名字与指针变量的区别:
int a[10];
int p;
p=a;
相同点:
a是数组名,是a[0]的地址,p=a;即p也保存了a[0]的地址,即a和p都指向a[0],所以在引用数组元素时,
a和p等价。
a[2],
(a+2),p[2],*(p+2)都是对数组a中a[2]元素的引用。
不同点:
1.a是常量,p是变量,可以用等号"="给p赋值,但不能给a赋值。
2.对a取地址,和对p取地址结果不同。

1.指针与函数的关系(传地址):
代码9:

#include<stdio.h>
void fun(int *p, int *q)
{int temp = *p;*p = *q; *q = temp;printf("in fun:*p=%d ", *p);printf("*q=%d \n", *q);
}
void test1()
{int a, b;a = 10;b = 20;printf("before fun:a=%d ", a);printf("b=%d\n ", b);fun(&a, &b);printf("after fun:a=%d ", a);printf("b=%d \n", b);
}
int main(int arg, char* argv[])
{test1();return 0;
}

结果:

before fun:a=10 b=20in fun:*p=20 *q=10
after fun:a=20 b=10

2.指针与函数的关系(传数组)
代码10:

#include<stdio.h>//传一维数组
//void fun1(int p[])
void fun1(int *p)
{printf("%d\n", p[2]);printf("%d\n", *(p + 2));
}
void test1()
{int a[10] = { 1,2,3,4,5,6,7,8 };fun1(a);
}//传二维数组
//void fun1(int p[][])
void fun2(int(*p)[4])
{printf("%d\n", p[0][2]);printf("%d\n", *(*(p+1) + 2));
}
void test2()
{int a[2][4] = { 1,2,3,4,5,6,7,8 };fun2(a);
}
int main(int arg, char* argv[])
{test2();return 0;
}

结果:

3
7

3.指针与函数的关系:指针函数
指针作为函数的返回值。
代码11:

#include<stdio.h>char* fun()
{static char str[100] = "hello world";return str;
}void test()
{char* p;p = fun();printf("p=%s\n", p);
}
int main(int arg, char* argv[])
{test();return 0;
}

结果:

p=hello world

注:栈区开辟的空间会随着当前代码段的结束而释放空间
静态区的空间不会随着当前代码段的结束而释放空间。

4.指针与函数的关系:函数指针
指针保存函数的地址。
c语言规定:函数的名字就是函数的首地址,即函数的入口地址,我们可以定义一个指针变量,来存放函数的地址。这个指针变量就是函数的指针变量。
定义方法: int (*p)(int,int); //定义了一个函数指针变量p,p指向的函数
必须有一个整型的返回值,有两个整型参数。
函数指针数组:本质是一个数组,数组里面的每个元素都是一个函数指针。
定义:
int (*p10;
定义一个函数指针数组,有10个元素p[0]-p[9],每个元素都是函数指针变量,。。。

函数指针最常用的地方:给函数传参。
函数指针最常用的地方就是将一个函数作为参数传递给另一个函数的时候要使用函数指针
将一个函数作为参数传递给另一个函数,将这个函数称为回调函数。

代码12:

#include<stdio.h>
int add(int x, int y)
{return x + y;
}int sub(int x, int y)
{return x - y;
}int mux(int x, int y)
{return x * y;
}int dive(int x, int y)
{return x / y;
}int process(int (*p)(int, int), int a, int b)
{int ret;ret = (*p)(a, b);return ret;
}
int main(int arg, char* argv[])
{int num;num = process(add, 1, 8);printf("num=%d", num);return 0;
}

结果:

num=9

C语言--指针和数组相关推荐

  1. c语言指针数组课件,C语言指针与数组教程课件.ppt

    C语言指针与数组教程;教学要求;本章主要内容;引子;#include void swap ( int x, int y ) { printf("调用时:x地址为:%p, 值为:%d\n&qu ...

  2. C语言 指针和数组区别 - C语言零基础入门教程

    目录 一.前言 二.指针和数组区别 1.通过 sizeof 获取大小 a.计算数组大小 b.计算指针大小 2.指针和数组赋值方式不同 a.指针赋值 b.数组赋值 3.指针是指针变量,数组是指针常量 三 ...

  3. c语言指针和数组的联系

    c语言指针与数组 **一.指针与一维数组** 1.一维数组的存储方式 2. 对一维数组名的理解 3. 数组下标和指针的关系 4.一位数组名与取数组首地址的区别 **二.指针与二维数组** 1.二维数组 ...

  4. C语言中指针与数组的区别,C语言 指针与数组的详解及区别

    C语言 指针与数组的详解及对比 通俗理解数组指针和指针数组 数组指针: eg:int( *arr)[10]; 数组指针通俗理解就是这个数组作为指针,指向某一个变量. 指针数组: eg:int*arr[ ...

  5. 指针c语言与数组,C语言指针与数组

    C语言指针与数组 数组的下标应该从0还是1开始? 我提议的妥协方案是0.5,可惜他们未予认真考虑便一口回绝    -- Stan Kelly-Bootle 1. 数组并非指针 为什么很多人会认为指针和 ...

  6. c语言指针与数组的深入理解

    引言:本篇再一次写到指针,学过c语言的都知道,指针是初学c语言时候遇到的一个比较难搞的知识点.你尽管可以想的简单,但是其实如果去用的话,没有一个更加深入的理解,那么后续的学习到数据结构就会艰难无比. ...

  7. c语言指针数组 难点总结,C语言指针与数组的难点分析.pdf

    C语言指针与数组的难点分析,c语言指针数组,c语言二维数组指针,c语言指针数组初始化,c语言函数指针数组,c语言数组与指针,c语言结构体数组指针,c语言指向数组的指针,c语言字符串数组指针,c语言数组 ...

  8. c 语言 指针 指向数组,C 指向数组的指针

    您可以先跳过本章,等了解了 C 指针的概念之后,再来学习本章的内容. 如果您对 C 语言中指针的概念有所了解,那么就可以开始本章的学习.数组名是一个指向数组中第一个元素的常量指针.因此,在下面的声明中 ...

  9. C语言指针和数组的天生姻缘

    指针和数组的天生姻缘 以指针的方式来访问数组 指针和下标访问数组的本质 数组和指针并不是相等的 从内存角度理解指针访问数组的实质 指针和数组类型的匹配问题 以指针的方式来访问数组 数组元素使用时不能整 ...

  10. C语言指针、数组与sizeof运算符

    指针.数组与sizeof运算符 指针.数组与sizeof运算符 指针.数组与sizeof运算符 Sizeof是C语言的一个运算符,sizeof的作用是用来返回()里面的变量或者数据类型占用的内存字节数 ...

最新文章

  1. WEB免费打印控件推荐
  2. Web Service之Soap请求响应内容中文编码解密
  3. 1MySQL是面向对象型数据库_数据库及MySQL基础(1)
  4. Ubuntu安装Chrome及hosts修改
  5. 配置httpd虚拟主机
  6. scss百分号操作符的一个使用例子
  7. java与mysql的交互_java与数据库交互常用到的一些方法
  8. LeetCode 56. 合并区间(优先队列)
  9. 5G 准备向 Wi-Fi 的 6GHz 频段下手了?
  10. js swipe 图片滑动控件实现 任意尺寸适用任意屏幕
  11. python 大图找小图_20 M 的图片能压缩到 2 M?20行Python代码,无损压缩千百张图片...
  12. 遗传算法python实例_Python遗传算法框架使用实例(一)使用Geatpy实现句子匹配
  13. 虚拟机安装教程win7_VMware15虚拟机软件安装教程
  14. Windows11系统引导修复(因EasyBCD误删win11启动)
  15. 交叉编译及交叉编译工具链的安装
  16. 小程序中使用全局样式
  17. php写超级简单的登陆注册页面(适用期末作业至少要求带有数据库的)
  18. VMware之虚拟交换机
  19. 开发者企业公司 邓白氏公司 D-U-N-S Number
  20. 【饭谈】领导叫你搞个自动化平台,你要怎么入手?不会上来就开始新建项目写代码吧?

热门文章

  1. 解决Winows缺少xinput1_2.dll问题
  2. PMP®项目管理|不同场景使用不同沟通方式
  3. 周赛 2019-12-15
  4. PHP教程9-流程结构
  5. Mathtype安装失败的解决方法
  6. python3+mysql创建数据库管理兔子信息
  7. 常见宽带故障排查手册
  8. 计算机专业简历中的项目负责,计算机专业项目经历填写范文
  9. 荣耀电视鸿蒙系统,搭载鸿蒙系统,荣耀智慧屏要做智能电视下一代!
  10. Android用中文怎么读,siri怎么读翻译成中文是什么意思?安卓手机上有siri吗?