c语言的指针
1、 指针前奏
指针是C语言中非常重要的数据类型,如果你说C语言中除了指针,其他你都学得很好,那你干脆说没学过C语言。
1 #include <stdio.h> 2 int main() 3 { 4 int a = 10; 5 6 int *p; 7 8 p = &a; 9 10 printf("%d",*p ); 11 12 return 0; 13 }
*p = 9;
int a = 10;
int *p = &a;
(*pp) == p
*(*pp) == *p = a
**pp == *p = a = 20
1 #include <stdio.h> 2 void swap(int *v1, int *v2); 3 4 int main() 5 { 6 int a2 = 90; 7 int b2 = 89; 8 9 swap(&a2, &b2); 10 11 printf("a2=%d, b2=%d\n", a2, b2); 12 return 0; 13 } 14 // 完成两个整型变量值的互换 15 void swap(int *v1, int *v2) 16 { 17 int temp = *v1; 18 *v1 = *v2; 19 *v2 = temp; 20 }
1 #include <stdio.h> 2 int sumAndMinus(int n1, int n2, int *n3); 3 4 int main() 5 { 6 int a = 10; 7 int b = 7; 8 9 // 存储和 10 int he; 11 // 存储差 12 int cha; 13 14 he = sumAndMinus(a, b, &cha); 15 16 printf("和是%d, 差是%d\n", he, cha); 17 18 return 0; 19 } 20 21 // 返回值是 22 int sumAndMinus(int n1, int n2, int *n3) 23 { 24 *n3 = n1 - n2; 25 26 return n1 + n2; 27 }
1 #include <stdio.h> 2 int main() 3 { 4 // 0000 0000 0000 0000 0000 0000 0000 0010 5 int i = 2; 6 // 0000 0001 7 char c = 1; 8 9 int *p; 10 p = &c; 11 printf("c的值是%d\n", *p); 12 13 return 0; 14 }
int *p=&c; 本应该是char类型的,写成了int类型
Printf(“c的值是%d\n”,*p); 打印结果为513,而非1
Printf(“c的值是%d\n”,c); 值为1
因为0000 0001
0000 0010
0000 0000
0000 0000
-----> 0000 0000 0000 0000 0000 0010 0000 0001
1)数组元素的访问方式
int ages[5];
int *p;
p = ages;
1> 数组名[下标] ages[i]
2> 指针变量名[下标] p[i]
3> *(p + i)
2)指针变量+1,地址值究竟加多少,取决于指针的类型
int * 4
char * 1
double * 8
3)void change(int array[])等价于void change(int *array)
array[2] = *(array+2)
4) 元素的地址:
第一个元素的地址 p &ages[0]
第二个元素的地址p+1 &ages[1]
第三个元素的地址p+2 &ages[2]
第i个元素的地址 p + i &ages[i]
元素的值:
*p ages[0]
*(p+1) ages[1]
*(p+2) ages[2]
1 #include <stdio.h> 2 3 void change(int *array) 4 { 5 printf("%d\n", array[2]); 6 //printf("%d\n", *(array+2)); 7 } 8 9 10 int main() 11 { 12 // 20个字节 13 int ages[5] = {10, 11, 19, 78, 67}; 14 15 change(ages); 16 17 return 0; 18 }
char s[] = “mj”;
char *s = “mj”;
或者
char *s;
s = “mj”;
1.常量区
存放一些常量字符串
2.堆
对象
3.栈
存放局部变量
掌握:
定义字符串的2种方式
1> 利用数组
char name[] = "itcast";
* 特点:字符串里面的字符是可以修改的
* 使用场合:字符串的内容需要经常修改
2> 利用指针
char *name = "itcast";
* 特点:字符串其实是一个常量字符串,里面的字符是不能修改
* 使用场合:字符串的内容不需要修改,而且这个字符串经常使用
1 #include <stdio.h> 2 int string_len(char *s); 3 4 int main() 5 { 6 int size = string_len("sdtrgfgds56"); 7 8 printf("%d\n", size); 9 return 0; 10 } 11 12 int string_len(char *s) 13 { 14 // 1.定义一个新的指针变量指向首字符 15 char *p = s; 16 17 /* 18 while ( *s != '\0' ) 19 { 20 s++; 21 }*/ 22 23 while ( *s++ ) ; 24 25 return s - p - 1; 26 } 27 28 /* 29 int string_len(char *s) 30 { 31 // 记录字符的个数 32 int count = 0; 33 34 // 如果指针当前指向的字符不是'\0' 35 // 首先*s取出指向的字符 36 // 然后s++ 37 while ( *s++ ) 38 { 39 // 个数+1 40 count++; 41 42 // 让指针指向下一个字符 43 //s = s + 1; 44 //s++; 45 } 46 47 return count; 48 } 49 */ 50 51 /* 52 int string_len(char *s) 53 { 54 // 记录字符的个数 55 int count = 0; 56 57 // 如果指针当前指向的字符不是'\0' 58 while ( *s != '\0') 59 { 60 // 个数+1 61 count++; 62 63 // 让指针指向下一个字符 64 //s = s + 1; 65 s++; 66 } 67 68 return count; 69 }*/
1 #include<stdio.h> 2 3 char *test(); 4 5 int main() 6 7 { 8 9 char *name=test(); 10 11 printf("name=%s\n",name); 12 13 return 0; 14 15 } 16 17 18 19 char *test() //返回指针的函数 20 21 { 22 23 return "rose"; 24 25 }
函数作为一段程序,在内存中也要占据部分存储空间,它也有一个起始地址,即函数的入口地址。函数有自己的地址,那就好办了,我们的指针变量就是用来存储地址的。因此,可以利用一个指针指向一个函数。其中,函数名就代表着函数的地址。
定义的一般形式:函数的返回值类型 (*指针变量名)(形参1, 形参2, ...);
• 调用函数
• 将函数作为参数在函数间传递
指针总结
一、指针变量的定义
1. 格式:变量类型 *指针变量名;
2. 举例:int *p; char *p2;
3. 注意:定义变量时的*仅仅是指针变量的象征
二、利用指针变量简单修改其他变量的值
1.指向某个变量
int a;
int *p;
p = &a;
或者
int *p = &a;
2.修改所指向变量的值
*p = 10;
3.在函数内部修改外面变量的值
int a = 10;
change(&a);
void change(int *n)
{
*n = 20;
}
三、指针与数组
1.将数组当做函数参数传入时,会自动转为指针
四、指针与字符串
1.定义字符串的2种方式
1> 利用数组
char name[] = "itcast";
* 特点:字符串里面的字符是可以修改的
* 使用场合:字符串的内容需要经常修改
2> 利用指针
char *name = "itcast";
* 特点:字符串其实是一个常量字符串,里面的字符是不能修改
* 使用场合:字符串的内容不需要修改,而且这个字符串经常使用
2.定义字符串数组
1> 利用二维字符数组
char names[2][10] = {"jack", "rose"};
2> 利用指针数组
char *names[2] = {"jack", "rose"};
作业1
1 /* 2 编写一个函数,判断某个字符串是否为回文。 3 回文就是从左边开始读 和 从右边开始读 都是一样的,比如"abcba" 4 */ 5 6 #include <string.h> 7 #include <stdio.h> 8 int isHuiwen(char *str); 9 10 int main() 11 { 12 printf("%d\n", isHuiwen("abcdcba")); 13 return 0; 14 } 15 16 /* 17 返回1代表是回文 18 返回0代表不是回文 19 */ 20 int isHuiwen(char *str) 21 { 22 // 1.定义一个指向变量left指向字符串的首字符 23 char *left = str; 24 // 2.定义一个指向变量right指向字符串的末字符 25 char *right = str + strlen(str) - 1; 26 27 while (left < right) 28 { 29 // 如果左边和右边的字符不一样 30 if (*left++ != *right--) 31 { 32 return 0; 33 } 34 } 35 36 return 1; 37 }
作业2
1 /* 2 编写一个函数void strlink(char s[], char t[]) 3 将字符串t连接到字符串s的尾部 4 */ 5 #include <stdio.h> 6 7 void strlink(char s[], char t[]); 8 9 int main() 10 { 11 char s1[20] = "michael "; 12 char s2[] = "jackson"; 13 14 strlink(s1, s2); 15 16 printf("%s\n", s1); 17 18 return 0; 19 } 20 21 void strlink(char s[], char t[]) 22 { 23 int i = 0; 24 25 // 判断s[i]是否为字符串的尾部 26 while ( s[i] != '\0' ) 27 { 28 i++; 29 } 30 31 int j = 0; 32 // 拷贝t的内容到s的后面 33 while ( (s[i] = t[j]) != '\0' ) 34 { 35 i++; 36 j++; 37 } 38 } 39 40 /* 41 更加精简的写法,仅作为参考(会有警告信息) 42 void strlink2(char s[], char t[]) 43 { 44 int i = -1; 45 46 // 判断s[i]是否为字符串的尾部 47 while (s[++i]) ; 48 49 int j = 0; 50 // 拷贝t的内容到s的后面 51 while (s[i++] = t[j++]) ; 52 }*/