一、指针
1.1 指针的概念
指针是一个变量,指针存放的内容是一个地址,该地址指向一块内存空间
1.2 指针变量的定义
int *p;//表示定义一个指针变量
*p;//代表指针所指内存的实际数据
注:指针变量只能存放地址,不能将一个int型变量直接赋值给一个指针。定义指针 int *p = 10;这种写法是不可以的
int main() { int a = 2; // int *p ; //定义一个指针变量,*p代表指针所指内存的实际数据 //p = &a; //这两句实现的功能=int *p = &a; int *p = &a; //将a地址中存的数据给指针 int b = *p; printf("b =%d\n", b); *p = 10;//将地址编号为XX里面的值改为10 printf("a = %d\n", a); return 0; }
1.3 &取地址运算符
&可以取得一个变量在内存当中的地址。
1.4 无类型指针
定义一个指针变量,但不指定它指向具体哪种数据类型。可以通过强制转化将void *转化为其他类型指针,也可以用(void*)将其他类型指针强制转化为void类型指针。
void *p;
1.5 NULL空指针
NULL在C语言中定义为(void *),相当于0。
int main() { int a = 10; int *p = &a; p = NULL; int *p = NULL; if (p) { printf("true\n"); } else { printf("fasle\n"); } return 0; }
1.6 野指针
int main () //野指针,不是空指针,只是没有指向具体的地址内存,所以显示不确定 { int a = 10; int *p; //避免使用野指针,更不能读写野指针指向的内存 //p = &a; *p = 1; printf("a = %d\n", *p); return 0; }
1.7 兼容性问题
指针间赋值比普通数据类型赋值检测更严格,例如:不能把一个int *赋值给char *类型。原则上一定是相同类型的指针指向相同类型的变量地址,不能用一种类型的指针指向另一种类型的变量地址。
int main()//指针的兼容性 { int a = 0x1310; char *d = &a; //int-char会导致数据丢失,因为d是一个字节的,所以显示最小的两位 char b = 2; int *p = &b; //p为整型,一个字节2位,所以2为02. printf("%x %x %x %x\n", a, b, *p, *d); return 0; }
1.8 指向常量的指针和指针常量
const char *p;//定义一个指向常量的指针
char *const p; //定义一个指针常量,一旦初始化后其内容不可以更改
int main()//常量指针 { int a = 10; int b = 4; const int *p = &a;//定义一个指向常量的指针 //*p = 20; // 不能将const int *作为左值使用 a = 20; p = &b; printf("*p = %d,a = %d\n", *p, a); return 0; }
int main()//指针常量:一旦定义之后就固定的指向一个地址,这个地址是不能在程序运行期间改变的 { int a = 10; int b = 4; int * const p = &a;//定义一个常量指针p,可通过它修改或读值一个变量的值 *p = 20; //a = 22; //p = &b; //错误,常量指针一旦定义,就不能修改其指向的变量 printf("a = %d %d\n", *p, a); return 0; }
1.9 指针与数组的关系
一个变量有地址,一个数组包含若干个元素,每个元素在内存中都有地址。
int a[10];
int *p = a;
此时p和&a[0]的地址相同
1.10 指针运算
1)指针运算不是简单的整数加减法,而是指针指向的数据类型在内存中占用字节数作为倍数的运算,
char *p;
p++; //表示一次移动了sizeof(char)这么多的字节数,即一次一位
int *p1;
p++; //表示一次移动了sizeof(int)这么多的字节数,即一次4位
2)求差值,p1 - p2,表示同一数组中两元素之间的距离。
1.11 给数组中某元素赋值
int main() { int buf[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int *p = buf; //法1:将数组中下标为3的成员赋值 *(p + 3) = 20; //法2:将数组中下标为5的成员赋值 p[5] = 10; //法3:将数组中下标为7的成员赋值 p += 7; *p = 30; //法一、二都没有改变p指向的内存地址,但法三修改了p指向的值 int i; for(i = 0; i <10; i++) { printf("buf[%d] = %d\n", i, buf[i]); }