今天讲讲关于C语言里面的指针。那么指针是什么呢?指针和其他变量一样也是个变量,像char,short,int,long一样。既然是个变量那么这个变量里面装着什么呢!其实储存一个地址。
那么怎么来申明一个指针,如 int *p=NULL
是个指针,那么指向的地址是个NULL的地址也是0。
用一个例子来说明这个
#include <stdio.h>
int main(int argc, char *argv[])
{
int *p=NULL;
int i=5;
p=&i; //&这个是什么符号呢,是取地址符号。就把i的地址赋给P
printf("%d\n\r",*p);//*是个什么符号呢,是把地址上面的值取出来,也就是P的地址上面的值取出来。所以*就是个钥匙
return 0;
}
上面的一个例子就是通过P的指针来询问的i的值。也就像你一个朋友在宾馆里,你要去找他,你去这个宾馆的前台把你朋友最先的时候告诉你在多少号,你是通过这个号找到你的朋友,而不是你朋友的名字。
那么既然指针也是个变量,那么它就有大小,那么它有多大呢。我们再举个例子来看看它到底有多大。
#include <stdio.h>
int main(int *argc,char *argv[])
{
int *p=NULL; //我们定义一个int *类型
char *p1=NULL;//char *类型
short *p2=NULL;//short *类型
long *p3=NULL;//long *类型
printf("int *p: %d, char *p1:%d,short *p2:%d ,long *p3:%d\n\r",sizeof(p),sizeof(p1),sizeof(p2),sizeof(p3));//我们通过sizeof这个关键字得到大小,经过试验得到都是4字节。
return 0;
}
所以我们验证不管是什么类型的指针,那么都是4字节。
很多书上有这样的一个例子都是用指针来交替2个值,但是常常笔试题中出现的题目是你不能够用第3个变量。那么怎么办呢?我们学过加减就能够办的到。那么实现的代码是什么样的呢,就是a=a+b;b=a-b;a=a-b;那么还有没有其他的办法呢,也有,在嵌入式里面会经常遇到这个符号。那么自己去想想怎么实现。
我们在笔试题中经常会遇到堆和栈的这样的题目。那么今天稍微讲下,再举个例子来说明:
#include <stdio.h>
#include <string.h>
my_malloc(char *p)
{
char str[100];
p=str;
}
int main(void)
{
char *p;
my_malloc(p);
strcpy(p,"hello, world");
printf("%s\n\r",p);
return 0;
}
代码是这样的,那么这个时候P的值会不会把hello,world打印出来。通过运行来看会出现段错误。出现的段错误是你使用C语言不对,不是你逻辑的思维不对。那么为什么不对呢,因为在主函数里面调用my_malloc();这个函数之后。这个地址就在内存里面消失了。所以str这个字符串在栈里面。所以栈的地址是程序自己分配的。那么堆是我们程序员自己分配的,主管这个区域生老病死。那么怎么分配呢?用malloc();p=(char *)malloc(100);如果在my_malloc()里面改成这样,你认为OK了吗?是的,调用这个函数之后,是的已经分配了好这个区域,他是在那里了,但是运行之后,p这个指针没有指向这个区间了,但是那块内存在那里,你不知道在那里了,也就是内存泄露了。那么再怎么改呢,我们是不是要把这个地址保存好。那么具体的代码如下:
#include <stdio.h>
#include <string.h>
char *my_malloc(char **p)
{
//char str[100];
//p=str;
*p=(char *)malloc(100);
return *p;
}
int main(void)
{
char *p;
my_malloc(&p);
strcpy(p,"hello, world");
printf("%s\n\r",p);
return 0;
}
这样就能够把这一串字符串打印出来。既然说道字符串了,那么再来讲讲字符串。我们再写一个函数:
#include <stdio.h>
int main(int argc,char*argv[])
{
char *str="hello,word";
char str1[]="hello,word";
printf("str:%s\n\r",str);
printf("%d\n\r",sizeof(str));
*(str1+1)='w';
printf("str:%s\n\r",str1);
return 0;
}
我们来看看*str,和str1[]之间的不同。我在前面说了指针的大小,那么str为多大,也是4字节。且它是个字符常量。那么你认为*(str+1)=’w’,这样对吗,由于他只有4字节的大小。根本不能够改变。那么str1[];有多少字节呢?有10个字节,记住还有\0。很多面试题会一起考strlen和sizeof。以后再讲strlen怎么实现的。
这个是我刚刚创建的QQ群。 316317702,需要可以加下,一起讨论