---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Unity开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
今天学习了复杂数据类型中得指针,指针是关键中的关键
一、指针
1.基本使用
1>定义
#include <stdio.h>
void change(int);
int main(int argc, const char * argv[])
{
/*
int a = 90;
change(&a);
printf("a = %d\n",a);
*/
//指针的定义:
//变量类型 变量名
//格式:变量类型 *变量名; int *p
//指针变量只能存储地址
//指针就一个作用:能够根据一个地址值,访问对应的存储空间
//指针变量p前面的int:指针变量p只能指向int类型的数据
int *p;//这里的*只是定义这个指针
int a = 90;
//指针变量p指向了变量a
p = &a;
*p = 10;//这里的*是完成指向a地址的一个过程,即进入了a地址,修改a的值
a = 20;
printf("%d\n",*p);
return 0;
}
void change(int n)
{
n = 10;
}
2>配合定义作出的指针内存分析
2.利用指针修改a的值
//利用指针修改a的值
#include <stdio.h>
void change(int *n);
int main(int argc, const char * argv[])
{
int a = 90;
change(&a);
printf("%d\n",a);
return 0;
}
void change(int *n)
{
*n = 10;
}
3.关于指针的使用注意事项
#include <stdio.h>
int main(int argc, const char * argv[])
{
/*不建议的写法,int *p只能指向int类型的数据
int *p;
double d = 10.0;
p = &d;
*/
/*指针变量只能存储地址
int *p;
p = 200;
*/
/*
int *p;
printf("%d\n",*p);
*/
int a = 10;
/*
int a;
a = 10;
*/
/*
int *p;
p = &a;
*/
//定义变量时的*仅仅是一个象征,没有其他特殊含义
int *p;
//不正确的写法
//*p = &a;
p = &a;
//这个时候的*的作用:访问指向变量p指向的存储空间
*p = 20;
char c = 'Q';
char *cp = &c;//其实就相当于(char *)cp = &c;
*cp = 'D';
printf("%c\n",c);
return 0;
}
4.指向指针的指针
1>函数例子
#include <stdio.h>
int main(int argc, const char * argv[])
{
int a = 10;
int *p = &a;
int **pp = &p;
//a = 20;
//*p = 20;
/*
(*pp) == p;//这里pp储存的是p的地址,*pp指向p,获取p中存储的值
*(*pp) == *p = a;
**pp == *p = a
*/
**pp = 20;
printf("%d\n",a);
//int ***ppp = &pp;
/*
char a2 = 'A';
char *p2 = &a2;
*/
return 0;
}
2>指向指针的指针示意图
5.利用指针完成加减法
#include <stdio.h>
int sumAndMinus (int n1 ,int n2 ,int *n3);
int main(int argc, const char * argv[])
{
int a = 10;
int b = 7;
int he ,cha;
he = sumAndMinus(a, b, &cha);
printf("%d %d",he , cha);
return 0;
}
int sumAndMinus (int n1 ,int n2 ,int *n3)
{
*n3 = n1 - n2;
return n1 + n2;
}
6.关于指针的疑问
1>函数例子
/*
%d int
%f float/double
%ld long
%lld long long
%c char
%s 字符串
%zd unsigned long
*/
#include <stdio.h>
int main(int argc, const char * argv[])
{
//这里看内存分析图,如若不明白再看视频,讲解很详细
//0000 0000 0000 0000 0000 0000 0000 0010
int i = 2;
//0000 0001
char c = 1;
//char *p;
int *p;//这里定义的char c,指针却用int *p,内存图分析原因为什么不行
p = &c;
//*p = 10
printf("c的值是%d\n",*p);
return 0;
}
void test()
{
char c;//1字节
int a;//4字节
long b;//8字节
//任何指针都占用8个字节的存储空间
char *cp;
int *ap;
long *bp;
//因为这里返回默认是unsigned long的值,所以返回字符%zd
printf("cp=%zd , ap=%zd , bp=%zd\n",sizeof(cp),sizeof(ap),sizeof(bp));
//这里的返回值显示不管什么类型指针都占用8个字节
}
2>指针在内存中示意图
7.指针与数组
1>函数例子
#include <stdio.h>
/*
int ages[5];
int *p;
p = ages;
1.数组元素的访问方式
1>数组名[下标] ages[i]
2>指针变量名[下标] p[i]
3>*(p + i)
2.指针变量的+1究竟加多少,取决于指针的类型
int * 4字节
char * 1字节
double * 8字节
*/
void change(int array[]);
void test();
int main(int argc, const char * argv[])
{
//20个字节
int ages[] = {10 , 9 , 8 , 67 ,56};
change(ages);
test();
return 0;
}
//利用一个指针来接受一个数组,指针变量array指向了数组的首元素
void change(int *array)
{
printf("%d\n",array[2]);
//printf("%d\n",*(array + 2));
}
void test()
{
double d = 10.8;
double *dp;
dp = &d;
printf("dp = %p\n",dp);
printf("dp + 1 = %p\n",dp + 1);//这里dp + 1表示地址指向下一位
int ages[] = {10 , 9 , 8 , 67 ,56};
int *p;
//指针变量p指向数组首元素
p = &ages[0];
//数组名就是数组的地址,也是数组首元素的地址
//p = ages;
/*
p --->&ages[0]
p + 1 --->&ages[1]
p + 2 --->&ages[2]
p + i --->&ages[i]
*/
printf("%d\n",*(p+2));
printf("%d\n",p[2]);
/*
for (int i = 0; i < 5; i++) {
printf("ages[%d] = %d\n",i ,ages[i]);
}*/
}
2>指针遍历数组示意图
8.指针与字符串
#include <stdio.h>
/*
1.常量区
存放一些常量字符串,这里的字符串一般不能修改
2.堆
对象
3.栈
存放局部变量
*/
/*
1>利用数组
char name[] = "itcase";
*特点:字符串里面的字符是可以修改的
*使用场合:字符串的内容需要经常修改
2>利用指针
char *name = "itcase";
*特点:字符串其实是一个常量字符串,里面的字符是不嫩修改
*使用场合:字符串的内容不需要修改,而且这个字符串经常使用
*/
int main(int argc, const char * argv[])
{
char name[20];
printf("请输入名字:\n");
scanf("%s",name);
printf("刚才输入的字符串是:%s\n",name);
return 0;
}
//定义字符串数组
void test2()
{
char *name = "jack";
//int ages[5];
//指针数组(字符串数组)
char *names[5] = {"jack","rose","jake"};
//二维字符数组(字符串数组)
char names2[2][10] = {"jack","rose"};
}
//定义字符串
void test()
{
//字符串变量
char name[] = "it";
name[0] = 'T';
printf("%s\n",name);
//"it" == 'i' + 't' + '\0'
//指针变量name2指向了字符串的首字符
//字符串常量
char *name2 = "it";
char *name3 = "it";
// *name2 = 'T';
//printf(%c\n,*name2);
printf("%s\n",name2);
}
9.返回指针的函数
/*
只要求看懂
*/
#include <stdio.h>
char *test();
int main(int argc, const char * argv[])
{
char *name = test();
printf("name = %s\n",name);
return 0;
}
char *test()
{
return "rose";
}
10.指向函数的指针
#include <stdio.h>
/*
掌握:
1.看懂语法
2.定义指向函数的指针
double (*p)(double , char *,int);
p = haha;
或者
double (*p)(double ,char *,int) = haha;
3.如何间接调用函数
1>p(10.7 , "jack",10)
2>(*P)(10.7 , "jack",10);
*/
void test()
{
printf("调用了test函数\n");
}
int sum(int a ,int b)
{
return a + b;
}
int main(int argc, const char * argv[])
{
//定义指针变量指向sum函数
//左边的int:指针变量p指向的函数返回int类型的数据
//右边的(int ,int):指针变量p指向的函数有2个int类型的形参
int (*p)(int ,int);
p = sum;
//int c = p(10 ,11);
int c = (*p)(10 ,11);
printf("c is %d\n",c);
return 0;
}
void test1()
{
//(*p)是固定写法,代表指针变量p指向的函数没有返回值
//左边的void:指向变量p指向的函数没有返回值
//右边的():指针变量p指向的函数没有形参
void (*p)();
//指针变量p指向了test函数
p = test;
p();
//(*p)();//利用指针变量间接调用函数
//test();//直接调用函数
}
恩,今天学的比较多,需要好好消化
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Unity开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------