标签:style blog http color 使用 strong for 代码
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
一般形式:类名标识符 *指针变量名;
int *p; float *q;
指针变量是用来存放变量地址的,不要给它随意赋值一个常数。下面的写法是错误的
int *p; p = 200; // 这是错误的
1 char a = 10; 2 printf("修改前,a的值:%d\n", a); 3 4 // 指针变量p指向变量a 5 char *p = &a; 6 7 // 通过指针变量p间接修改变量a的值 8 *p = 9; 9 10 printf("修改后,a的值:%d", a);
当程序刚执行完第5行代码时,内存中大概的分布情况是这样的
,a值是10,p值就是变量a的地址ffc3。
指针运算符除了可以赋值之外,还可以用于取值
1 char a = 10; 2 3 char *p; 4 p = &a; 5 6 char value = *p; 7 printf("取出a的值:%d", value);
第6行中的*p的意思是:根据p值(即变量a的地址)访问对应的存储空间,并取出存储的内容(即取出变量a的值),赋值给value
在指针变量没有指向确定地址之前,不要对它所指的内容赋值。下面的写法是错误的
int *p; *p = 10; //这是错误的
1 // 定义一个int类型的数组 2 int a[2]; 3 4 // 定义一个int类型的指针 5 int *p; 6 7 // 让指针指向数组的第0个元素 8 p = &a[0]; 9 10 // 修改所指向元素的值 11 *p = 10; 12 13 // 打印第一个元素的值 14 printf("a[0] = %d", a[0]);
输出结果:,说明已经通过指针间接修改了数组元素的值,跟指向一个普通int类型变量是一样的。
由于数组名代表着数组的首地址,即a == &a[0],因此第8行代码等价于:
// 让指针指向数组的第0个元素 p = a;
内存分析图如下,一个指针变量占用2个字节,一个int类型的数组元素占用2个字节
1 // 定义一个int类型的数组 2 int a[4] = {1, 2, 3, 4}; 3 4 int i; 5 for (i = 0; i < 4; i++) { 6 printf("a[%d] = %d \n", i, a[i]); 7 }
1 // 定义一个int类型的数组 2 int a[4] = {1, 2, 3, 4}; 3 4 // 定义一个int类型的指针,并指向数组的第0个元素 5 int *p = a; 6 7 int i; 8 for (i = 0; i < 4; i++) { 9 // 利用指针运算符*取出数组元素的值 10 int value = *(p+i); 11 12 printf("a[%d] = %d \n", i, value); 13 }
p+i和a+i都可以表示元素a[i]的地址,它们都指向数组的第i个元素。a代表数组首地址,a+i也是地址,它的计算方法与p+i相同
*(p+i)和*(a+i)都表示数组元素a[i]
虽然p+i和a+i都指向数组的第i个元素,但二者使用时还是有区别的。因为作为指针变量的p可以改变自身值,如p++,使p的值自增。而数组名a是一个代表数组首地址的常量,它的值是不能改变的,即a++是不合法的
下标法: 如a[i]
指针法: 如*(p+i) 或 *(a+i)
1 void change(int b[]) { 2 b[0] = 10; 3 } 4 5 int main() 6 { 7 // 定义一个int类型的数组 8 int a[4] = {1, 2, 3, 4}; 9 10 // 将数组名a传入change函数中 11 change(a); 12 13 // 查看a[0] 14 printf("a[0]=%d", a[0]); 15 16 return 0; 17 }
change函数的形参是数组类型的,在第11行调用change函数时,将数组名a,也就是数组的地址传给了数组b。因此数组a和b占用着同一块内存空间。
输出结果:
也就是说,如果一个函数的形参类型是一个数组,调用函数时,你可以传入数组名或者指针变量;
1 void change(int b[]) { 2 b[0] = 10; 3 } 4 5 int main() 6 { 7 // 定义一个int类型的数组 8 int a[4] = {1, 2, 3, 4}; 9 10 int *p = a; 11 12 // 将数组名a传入change函数中 13 change(p); 14 15 // 查看a[0] 16 printf("a[0]=%d", a[0]); 17 18 return 0; 19 }
注意第1行的形参类型是个数组int b[],第10行定义了指针变量p,第13行将p当做实参传入函数
如果一个函数的形参类型是一个指针变量,调用函数时,你可以传入数组名或者指针变量。
1 void change(int *b) { 2 b[0] = 10; 3 // 或者*b = 10; 4 } 5 6 int main() 7 { 8 // 定义一个int类型的数组 9 int a[4] = {1, 2, 3, 4}; 10 11 // 将数组名a传入change函数中 12 change(a); 13 14 // 查看a[0] 15 printf("a[0]=%d", a[0]); 16 17 return 0; 18 }
注意第1行的形参类型是个指针变量int *b,第12行将数组名a当做实参传入函数。
由第2行可以看出,在很多情况下,指针和数组是可以相互切换使用的。但是,并不能说指针就等于数组。
1 // 定义一个指针p 2 char *p; 3 4 // 定义一个数组s存放字符串 5 char s[] = "mj"; 6 7 // 指针p指向字符串的首字符‘m‘ 8 p = s; // 或者 p = &s[0]; 9 10 for (; *p != ‘\0‘; p++) { 11 printf("%c \n", *p); 12 }
执行完第8行后,内存分布如右图:
1 #include <string.h> 2 3 int main() 4 { 5 // 定义一个字符串,用指针s指向这个字符串 6 char *s = "mj"; 7 8 // 使用strlen函数测量字符串长度 9 int len = strlen(s); 10 11 printf("字符串长度:%D", len); 12 return 0; 13 }
现在想将字符串"lmj"的首字符‘l‘改为‘L‘,解决方案是多种的
1 // 定义一个字符串变量"lmj" 2 char a[] = "lmj"; 3 4 // 将字符串的首字符改为‘L‘ 5 *a = ‘L‘; 6 7 printf("%s", a);
1 char *p2 = "lmj"; 2 *p2 = ‘L‘; 3 4 printf("%s", p2);
看起来似乎是可行的,但这是错误代码,错在第2行。首先看第1行,指针变量p2指向的是一块字符串常量,正因为是常量,所以它内部的字符是不允许修改的。
有人可能搞蒙了,这里的第1行代码char *p2 = "lmj";跟第一种方案中的第2行代码char a[] = "lmj";不是一样的么?这是不一样的。
注意:形式参数的变量名可以省略,甚至整个形式参数列表都可以省略
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
详细请查看:www.itheima.com
黑 马 程 序 员_视频学习总结<c语言>----03 指针,布布扣,bubuko.com
黑 马 程 序 员_视频学习总结<c语言>----03 指针
标签:style blog http color 使用 strong for 代码
原文地址:http://www.cnblogs.com/fqgl/p/3872024.html