0x00 指针
内存中字节的编号称为地址(Address)或指针(Pointer)。地址从 0 开始依次增加,对于 32 位环境,程序能够使用的内存为 4GB,最小的地址为 0,最大的地址为 0XFFFFFFFF。
0x01
#include <stdio.h>
int main(){
int a = 100;
char str[20] = "c.biancheng.net";
printf("%#X, %#X\n", &a, str);
return 0;
}
1、CPU 访问内存时需要的是地址,而不是变量名和函数名
2、变量名和函数名只是地址的一种助记符,当源文件被编译和链接成可执行程序后,它们都会被替换成地址。编译和链接过程的一项重要任务就是找到这些名称所对应的地址。
3、变量名表示本身。数组名、字符串名、函数名表示内存数据块的首地址
0x02 定义指针
int *p = &a;
*p == a;
0x03 指针的加减和比较运算
指针的加减与数据类型有关
int a = 1 ,*p=&a;
假设 &a = 0x1B04
p+1 = 0x1B08 增长多少取决于int占多少字节
char b = '1',*pb = &b;
&b = 0x1B00
pb + 1 = 0x1B01
0x04
数组长度 sizeof(arr)/sizeof(int)
*(arr+i) == arr[i]
指针数组 int *p = arr
0x05 字符数组与字符串常量
在内存中的存储位置不同,使得字符数组可以读取和修改,而字符串常量只能读取不能修改。(,字符数组存储在全局数据区或栈区,第二种形式的字符串存储在常量区)
char *p1 = "i wanna to learn C"
char str[] = "i wnanno to learn Java"
char *p2 = str
0x05 指针作为参数
参数传递的本质,内存的拷贝,指将一块内存上的数据拷贝到另一块内存上。对于简单的数据类型char、float、int 等占用的字节数不会太多,拷贝数据块,不太会影响效率。对于数组等数据集合,它的长度、大小是不可控的。太大的话,拷贝极其影响效率。所以不可做参数进行传递。
int max(int *intArr,int len)
int max(int intArr[],int len){}
0x06 指针作为函数返回值
指针函数
char *p1(char *str1,char *str2)
return &n
函数结束,会销毁其内变量,(其实是弃之不用,如果没有其它因素影响,能够及时使用,也能够的到正确的数据,如果有其它函数被调用,就会将该块内存覆盖。)
0x07 二级指针
指向指针的指针
int a = 9
int *p1 = &a
int **p2 = &p1
0x08 指针数组
int *arr[] = {&a,&b,&c}
int **p1 = arr
指针数组与字符串数组结合
char *str[] = {"caa","fef","df"}
str[0] str[1]
二维数组指针
int a[3][4]={0}
int(*p)[4]= a
p是一个指针,指向一个数组 数组的类型int[4] -> a所包含的每一个一维数组的类型
使用加减法时,p+1 前进4*4=16个字节
*(*(p+i)+j)每个元素的值
指针数组与二维数组指针区别
int *p1[5]
int (*p2)[5]
指针数组是一个数组,他的元素存放的的指针
二维数组指针是一个指针,指向二维数组
p1 占用20个字节的内存
p2 占用4个字节的内存
函数指针
int max(int x,int y){
printf("%d%d",x,y)
}
int (*p1)(int ,int) = max
(*p1)(3,4)
补
什么时候用什么样类型的指针,刚学,还是晕晕的,咋用啊。