指针1

一、什么是指针

1、概念:我们将内存中字节的编号称为地址或指针

2、CPU只能通过地址来取得内存中的代码和数据,所以一切都是地址

在编写代码过程中我们认为变量名表示数据本身,而函数名、字符串和数组名表示的代码块或数据块的首地址

二、变量与指针

1、指针变量

概念:数据在内存中的地址也称为指针,如果一个变量存储一份数据的指针,我们就成为指针变量

定义:定义指针变量与定义普通变量非常相似,不过要在变量名前加星号*

           格式:  数据类型*变量名;

                         数据类型*变量名 = 指

注意: *表示这是一个指针变量,该变量存放的是一个数据的地址,数据类型表示该指针变量所指向地址内存的数据类型。

例如:char*p1= &a;

           float *p2= &c;

//修改指针变量

p1 = &b;

p2 = &d;

定义指针变量的时候一定要带*,给指针变量赋值时不带*。

2、指针变量存储了数据的地址,通过指针变量能够获得改地址上的数据,格式为:

*pointer;                //这里的*称为指针运算符,用来取得某个地址上的数据。

如:int x = 10;
int y = 20;
int *px = &x;
int *py = &y;
y = *px + 5;   //表示把x的内容加5并赋给y,*px+5相当于(*px)+5
y = ++*px;    //px的内容加上1之后赋给y,++*px相当于++(*px)
y = *px++;    //相当于y=*(px++)
py = px;        //把一个指针的值赋给另一个指针
3、指针变量的运算

指针变量的加减运算的结果个数据类型的长度有关。

指针变量的加1是让指针移动一个字节而不是简单的加一。

三、指针与数组

1、数组指针

假设p是指向Arr中第n个元素的值,那么*p++,*++p,(*p)++是什么意思?

(1)*p++等价于*(p++),表示先取得第n个元素的值,再将p指向下一个元素。

(2)*++p等价于*(p++)会先进行++p运算,使得p的值增加,指向下一个元素,整体上相当于*(p+1),所以会获得第 n+1的数组的值。

 (3)(*p)++会先取得第个元素的值,在对该元素的值加1,假设p指向第0个元素的值,并且第0个元素的值为99.执行完该语句后,第0个元素就会变成100.

2、指针数组

定义:如果一个数组中所有元素保存的都是指针,那么我们称它为指针数组

格式:datatype *arrayname【length】

3、指针与二维数组

(1)指向二维数组指针的定义

在内存中所有的二维数组都是连续存放的,它们之间没有“缝隙”。以下面的二维数组 a 为例:int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} }; 假设数组 a 中第 0 个元素的地址为 1000,那么每个一维数组的首地址如下图所示:

    
  
为了更好的理解指针和二维数组的关系,我们先来定义一个指向 a 的指针变量 p: 
int  (*p)[4] = a;      //int (*p)[4]; p = a;
// int arr[] = {1,2,3};      int *p = arr;  
// int arr[][4] = {{1,2},{3,4},{5,6}};     int (*p)[4] = arr;
注意:1、括号中的*表明 p 是一个指针,它指向一个数组,数组的类型为int [4],这正是 a 所包含的每个一维数组的类型。
2、[ ]的优先级高于*,( )是必须要加的,如果赤裸裸地写作int *p[4],那么应该理解为int *(p[4]),p 就成了一个指针数组,而不是二维数组指针。
 
二、用指向二维数组的指针访问二维数组
1) p指向数组 a 的开头,也即第 0 行;p+1前进一行,指向第 1 行。
2) *(p+1) = a[1]表示取地址上的数据,也就是整个第 1 行数据。(例3_1)
3) *(p+1)+1表示第 1 行第 1 个元素的地址。如何理解呢?
*(p+1)单独使用时表示的是第 1 行数据,放在表达式中会被转换为第 1 行数据的首地址,也就是第 1 行第 0 个元素的地址,因为使用整行数据没有实际的含义,编译器遇到这种情况都会转换为指向该行第 0 个元素的指针;就像一维数组的名字,在定义时或者和 sizeof、& 一起使用时才表示整个数组,出现在表达式中就会被转换为指向数组第 0 个元素的指针。
4) *(*(p+1) +1) = a[1][1]  表示第 1 行第 1 个元素的值。很明显,增加一个 * 表示取地址上的数据。
根据上面的结论,可以很容易推出以下的等价关系:
a+i == p+i
a[i] == p[i] == *(a+i) == *(p+i)
a[i][j] == p[i][j] == *(a[i]+j) == *(p[i]+j) == *(*(a+i)+j) == *(*(p+i)+j)

四、指针与字符串

1、C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中.

2、字符指针

除了字符数组,C语言还支持另外一种表示字符串的方法就是直接使用一个指针指向字符串。

3、字符指针
     除了字符数组,C语言还支持另外一种表示字符串的方法,就是直接使用一个指针指向字符串,
例如:char *str = "hello";     或者:    char *str;str = "hello";
字符串中的所有字符在内存中是连续排列的,str 指向的是字符串的第 0 个字符;我们通常将第 0 个字符的地址称为字符串的首地址。字符串中每个字符的类型都是char,所以 str 的类型也必须是char *。
4、两类存放字符的区别
     它们最根本的区别是在内存中的存储区域不一样,字符数组存储在全局数据区或栈区,第二种形式的字符串存储在常量区。全局数据区和栈区的字符串(也包括其他数据)有读取和写入的权限,而常量区的字符串(也包括其他数据)只有读取权限,没有写入权限。内存权限的不同导致的一个明显结果就是,字符数组在定义后可以读取和修改每个字符,而对于第二种形式的字符串,一旦被定义后就只能读取不能修改,任何对它的赋值都是错误的。另外,字符数组的sieof(str)为数组中元素个数(包括‘\0’),字符指针的sizeof(str)为指针大小。(例3)
5、何种情况使用字符数组还是字符串常量

     在编程过程中如果只涉及到对字符串的读取,那么字符数组和字符串常量都能够满足要求;如果有写入(修改)操作,只能使用字符数组,不能使用字符串常量。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值