------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、指针
1、指针变量的定义
a、格式:变量类型*变量名;举例:int *p; char *p2;注意:定义变量时的*仅仅是指针变量的象征
b、指针的作用:能够根据一个地址值,访问对应的存储空间;
c、指针变量的作用:只能存储地址;指针变量在64bit操作系统下占据8个字节。
例如:int *p =200;这是不合理的,地址都是很大的数,用十六进制表示。
d、指针变量未经过初始化,不要拿来间接访问其他存储空间
e、指针变量p前面的int代表指针变量p只能指向int类型的数据;
f、指针变量只能指向同类型的数据,不能乱用类型;
例如,int *p; double d=10.0;p=&d;这样*p意味着从地址开始找4个字节的空间,而d拥有8个字节的空间。
2、利用指针变量简单修改其他变量的值
a、指向某个变量
int a;
int *p;// 定义一个指针变量p
p = &a;//指针变量p指向了变量a
或者
int *p = &a; //定义一个指针变量p,指针变量p指向了变量a(定义的同时赋值)
注意:*p=&a; //这个是将&a这个地址存入了*p所指向的存储空间,也就是自己存自己地址。
b、修改所指向变量的值
*p = 10; // *p访问指针变量p所指向的存储空间。
c、在函数内部修改外面变量的值
int a = 10;
change(&a);
void change(int *n)
{
*n = 20;
}
3、利用指针实现两个整形变量的互换的函数:
void swap(int *v1,int *v2)
{
int temp = *v1;
*v1 = *v2;
*v2 = temp;
}
a、不能交换外面实参的值,仅仅是交换了内部指针的指向
void swap(int *v1, int *v2)
{
int *temp;
temp = v1;
v1 = v2;
v2 = temp;
}
b、交换的只是内部v1、v2的值
void swap(int v1, int v2)
{
int temp = v1;
v1 = v2;
v2 = temp;
}*/
二、指向指针的指针
#include <stdio.h>
int main()
{
int a =10;
int *p = &a;
int **pp = &p;//指向p的指针
int ***ppp = &pp;//指向pp的指针
a=20; *p=20; *(*pp)=20; ***ppp=20;这四个是一样的
return 0;
}
指针可以做到,一个函数可以有无限个返回值。
实例:利用函数实现求两个数的和、差、积、商、以及余数;
void count(int num1,int num2, int *sum,int *minus, int *ji,int *shang, int *yuShu)
{
// 和
*sum = num1 + num2;
// 差
*minus = num1 - num2;
// 积
*ji = num1 * num2;
// 商
*shang = num1 / num2;
// 余数
*yuShu = num1 % num2;
}
// 调用处理函数
count(a,b,&sum,&minus,&ji,&shang,&yuShu);
三、指针与数组
1、 #include <stdio.h>
int main()
{
int a[] ={1,2,3,4};
//指针变量p指向了数组的首元素
int *p = a;//int *p = &a[0]; // 数组名就是数组的地址,也是数组首元素的地址
*p == &a[0];
*(p+1) == &a[1];//p+1是意味着指针的地址值+类型所占字节数
*(p+2) == &a[2];
return 0;
}
2、数组元素的访问方式
a、数组名[下标]; a[ i ]
b、指针变量名[下标]; p[ i ]
c、*(指针变量名+下标) *(p + i)
指针变量+1,地址值究竟加多少,取决于指针的类型
int * 4
char * 1
double * 8
#include <stdio.h>
void change( int *arr) //获取的是数组的首元素
{
printf(“%d\n”,arr[2]);
printf(“%d\n”,*(arr+2));
}
int main()
{
int a[] ={1,2,3,4};
change(a);
return 0;
}
四、指针与字符串
1、定义字符串的2种方式:
a、利用数组char name[]="abcd";
(1)、特点:字符串里面的字符是可以修改的;
(2)、使用场合:字符串的内容需要经常修改;
b、利用指针char *name="abcd";
(1)、特点:字符串其实是一个常量字符串,里面的字符是不能修改的;
(2)、使用场合:字符串的内容不需要修改,而且这个字符串经常使用;
2、实例:编写一个int string_len(char *s),返回字符串s的字符长度(不包括\0)
// 定义一个函数返回s指向字符串的字符长度
int string_len(char *s)
{
// 遍历字符串数组,'\0'的ASCII码值是0,'\0'可以用0替换
int i = 0;
while (s[i] != '\0') {
i++;
}
// 返回字符串长度
return i;
}
二维字符数组(字符串数组):char name[4][8]={"abc","hello", "hi", "ok"};
五、返回指针的函数
#include <stdio.h>
char *test()
{
return "jack";
}
int main()
{
char *name = test();
printf("name = %s\n", name);
return 0;
}
六、指向函数的指针
1、void (*p)();//定义指向函数的指针
(*p)是固定写法,代表指针变量p将来肯定是指向函数;
左边的void:指针变量p指向的函数没有返回值
右边的():指针变量p指向的函数有没有形参
函数名代表函数地址
2、不带形参实例
#include <stdio.h>
char test()
{
printf("调用了test函数\n");
}
int main()
{
void (*p)();
p = test;// 指针变量p指向了test函数
// 调用函数三种方式
(*p)();// 利用指针变量间接调用函数
p();// 因为p = test
test();// 直接调用函数
return 0;
}
3、带形参实例
#include <stdio.h>
char sum( int a, int b)
{
return a+b;
}
int main()
{
int (*p)(int, int);
p = sum
int sum = p(10,15);
int sum1 = (*p)(10,15);
int sum2 = sum(10,15);
printf("sum=%d\nsum1=%d\nsum2=%d\n",sum,sum1,sum2);
return 0;
}