c语言学习第三天笔记

指针:
1、在C语言中,允许用一个变量来存放指针,这种变量称为指针变量。指针变量的值就是某份数据的地址,这样的一份数 据可以是数组、字符串、函数,也可以是另外的一个普通变量或指针变量。
2、定义指针变量与定义普通变量非常类似,不过要在变量名前面加星号*,格式为:
 数据类型 * 变量名;
 数据类型 * 变量名 = 值 ;
 *表示这是一个指针变量,数据类型表示该指针变量所指向的数据的类型
3、定义指针变量时必须带*,给指针变量赋值时不能带*。
4、y=++*px; //px的内容加上1之后赋给y,++*px相当于++(*px)
      y=*px++; //相当于y=*(px++)
5、假设有一个 int 类型的变量 a,pa 是指向它的指针,那么*&a和&*pa分别是什么意思呢?
 *&a可以理解为*(&a),&a表示取变量 a 的地址(等价于 pa),*(&a)表示取这个地址上的数据(等价于 *pa),*&a仍然等价于 a。
 &*pa可以理解为&(*pa),*pa表示取得 pa 指向的数据(等价于 a),&(*pa)表示数据的地址(等价于 &a),所以&*pa等价于 pa。
6、不能对指针变量进行乘法、除法、取余等其他运算,除了会发生语法错误,也没有实际的含义
7、数组中的所有元素在内存中是连续排列的,如果一个指针指向了数组中的某个元素,那么加 1 就表示指向下一个元素,减 1 就表示指向上一个元素。加减1都是跳的字节长度取决指针前面的定义类型;
8、数组指针:
 int a[10];
 int *p; p=a; a是a[0]的地址,是数组a[0]的首地址;
 引入数组指针后,我们就有两种方案来访问数组元素了,一种是使用下标,另外一种是使用指针。
   1) 使用下标也就是采用 a[i] 的形式访问数组元素。如果 p 是指向数组 a 的指针,那么也可以使用 p[i] 来访问数组元素,它等价于 a[i]。
   2) 使用指针也就是使用 *(p+i) 的形式访问数组元素。另外数组名本身也是指针,也可以使用 *(a+i) 来访问数组元素,它等价于 *(p+i)。
 数组名是常量,它的值不能改变,而数组指针是变量(除非特别指明它是常量),它的值可以任意改变。也就是说,数组名只能指向数组的开头,而数组指针可以先指向数组开头,再指向其他元素。
9、字符串指针:
 C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中
 C语言还支持另外一种表示字符串的方法,就是直接使用一个指针指向字符串,例如:
 char *str = "hello";
 这种方法不能修改字符串中的字符,只能将指针重新指向另一个字符串;
 字符数组存储在全局数据区或栈区,第二种形式的字符串存储在常量区。全局数据区和栈区的字符串(也包括其他数据)有读取和写入的权限,而常量区的字符串(也包括其他数据)只有读取权限,没有写入权限。
10、二级指针:
 一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针。
11、指针数组:

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

int *a[10];

指针数组还可以和字符串数组结合使用,例:
#include <stdio.h>

int main()

{

char *str[3] = {

"helloworld!",      str[0]指向"helloword"

"I love c",        str[1]指向"I love c"

"C Language"       str[2]指向"C Language"

};

printf("%s\n%s\n%s\n", str[0], str[1], str[2]);

return 0;

}
12、二维数组指针:
 int (*p)[4] = a;
 括号中的*表明 p 是一个指针,它指向一个数组,数组的类型为int [4],这正是 a 所包含的每个一维数组的类型。
 对指针进行加法(减法)运算时,它前进(后退)的步长与它指向的数据类型有关,p 指向的数据类型是int [4],那么p+1就前进 4×4 = 16 个字节,p-1就后退 16 个字节,这正好是数组 a 所包含的每个一维数组的长度。也就是说,p+1会使得指针指  向二维数组的下一行,p-1会使得指针指向数组的上一行。
   1) p指向数组 a 的开头,也即第 0 行;p+1前进一行,指向第 1 行。
   2) *(p+1)表示取地址上的数据,也就是整个第 1 行数据
   3) *(p+1)+1表示第 1 行第 1 个元素的地址。*(p+1)单独使用时表示的是第 1 行数据,放在表达式中会被转换为第 1 行数据的首地址,也就是第 1 行第 0 个元素的地址,因为使用整行数据没有实际的含义,编译器遇到这种情况都会转换为指向该行第 0 个元素的指针;就像一维数组的名字,在定义时或者和 sizeof、& 一起使用时才表示整个数组,出现在表达式中就会被转换为指向数组第 0 个元素的指针。
   4) *(*(p+1)+1)表示第 1 行第 1 个元素的值。
 指针数组和二维数组指针的区别
   int *(p1[5]); //指针数组,可以去掉括号直接写作 int *p1[5];
   int (*p2)[5]; //二维数组指针,不能去掉括号
   指针数组和二维数组指针有着本质上的区别:指针数组是一个数组,只是每个元素保存的都是指针,以上面的 p1 为例在,32位环境下它占用 4×5 = 20 个字节的内存。二维数组指针是一个指针,它指向一个二维数组,以上面的 p2 为例,它占用 4 个字节的内存。
13、
       定义                       含义
       int *p;              p可以指向 int 类型的数据,也可以指向类似 int arr[n] 的数组
       int **p;               p为二级指针,指向 int * 类型的数据
       int *p[n];            p为指针数组。[ ] 的优先级高于 *,所以应该理解为 int *(p[n]);
       int (*p)[n];                  p是二维数组指针
       int *p();                 p是一个函数,他的返回值类型为 int *
       int (*p)();               p是一个函数指针,指向原型为 int func()的函数

14、指针总结:
 指针变量可以进行加减运算,例如p++、p+i、p-=i。指针变量的加减运算并不是简单的加上或减去一个整数,而是跟指针指向的数据类型有关。
两个指针变量可以相减。如果两个指针变量指向同一个数组中的某个元素,那么相减的结果就是两个指针之间的元素个数。
15、int *p; 4字节; char *p; 1字节; double *p; 8字节;
16、void *q 字节长度不确定,使用时要给出类型转换 a=(int) *q;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值