指针你可以别再困扰我了吗?
从开始学C语言的时候我就被指针给困扰住了,好不容易过了计算机二级我们已经好长时间没有打交道了,本以为从此脱离苦海,可是此次实习您的再次光临让我更加畏惧了。可以更你作揖膜拜求饶吗?但是拿唯物主义眼光来看这是不可以的,面对困难我们绝对不能低头妥协,而是要和谐这些难题让它迎着对我们有利的方向发展。今天梁老师给们讲的主要知识点就是指针。
其实数组和指针一样都是C语言中最难攻克的难点,组名的值是一个指针常量,也就是数组第一个元素的地址。
如:a是数组元素的首地址 &a是数组的首地址。在一数组中定义字符串有两种方法,char str[10] = "Hello";还
有一个是char *str= "Hello";其区别是后者是只读数据段,不可修改其值。
指针是把一个变量所在的内存单元的地址保存在另外一个内存单元中,保存地址的这个内存单元称为指针,通过指针和间接寻址访问变量。指针变量的定义形式:
基类型 *变量名( int *p1 ; double y, z ,*p2=&z)
v *p2=&z表示在定义指针变量p2的同时对其初始化,将z的存储地址赋予它,使p2指向了变量z的存储单元。&:表示取紧跟在&后面的变量的存储地址,*:表示从紧跟在*后面 的地址开取类容。p=a: 使p指向的a数组的首元素a[0],*p+1:a[0]+1,p++:使指针p后移一个存储单元,指向a[1],p=NULL:此时p不指向任何对象。*p++,*(p++):先取*p参加运算,再使p后移一个存储单元。*(++p):先使p后移一个存储单元,再取*p参加运算,(*p):先取*p参加运算,再使*p的值加1,即*p=*p+1,**pp:取p所指向内存空间的地址,称为指向指针的指针。要注意的是,用一个指针给另一个指针赋值时要注意,两个指针必须是同一类型的。编程时经常需要一种通用指针,可以转换为任意其它类型的指针,任意其它类型的指针也可以转换为通用指针,最初C语言没有void *类型,就把char 当通用指针,需要转换时就用类型转换运算符(),ANSI在将C语言标准化时引入了void 类型,void 指针不其它类型的指针之间可以隐式转换,而不必用类型转换运算符
函数指针是指向函数的指针变量,函数指针在使用前必须按照下面形式给出定义:
基类型 (*指针名)() 今天所课上所举的例子是(*f)(const char *)=say_hello.
C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上一致的。函数指针有两个用途:调用函数和做函数的参数。
函数指针的说明方法为:
数据类型标志符(指针变量名)(形参列表);
不过注意,指向函数的指针变量没有++和-- -运算,用时要小心。
再有还学习了内存分配方式,其方法有三种:
(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static 变量。
(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。常见的内存错误及其对策:
v 内存分配未成功,却使用了它。
v 编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。常用解决办法是,在使用内存之前检查指针是否为NULL。如果指针p 是函数的参数,那么在函数的入口处assert(p!=NULL)进行检查。如果是用malloc 或new 来申请内存,应该用if(p==NULL)或if(p!=NULL)进行防错处理。
v 内存分配虽然成功,但是尚未初始化就引用它。
v 犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值错误(例如数组)。
v 内存分配成功并且已经初始化,但操作越过了内存的边界。
v 例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for 循环语句中,循环次数很容易搞错,导致数组操作越界
今天的练习有:1、#include<stdio.h>
void swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
int main()
{
int a=6;
int b=7;
printf("a=%d\t,b=%d\n",a,b);
swap(&a,&b);
printf("a=%d\t,b=%d\n",a,b);
return 0;
}
2、#include<stdio.h>
void swap(int *a,int *b)
{
}
int main()
{ char str[10];
double k=1.00000;
strcpy(str,"hello");
int *p=&a;
char *ptr="hello worle!\n";
double *kk=&k;
int a=6;
int b=7;
printf("a=%d\t,b=%d\n",a,b);
swap(&a,&b);
printf("a=%d\t,b=%d\n",a,b);
printf("int= %d\n char=%d\t double = %d\n",sizeof(p),sizeof(ptr),sizeof(kk);
return 0;
3、#include<stdio.h>
void say_hello(const char *str)
{
printf("Hello %s\n",str);
}
int main(void)
{
void (*f) (const char *) = say_hello;
f("Guys");
return 0;
}
4、#include<stdio.h>
#include<malloc.h>
#include<string.h>
void GetMemory(char **p,int num)
{
*p=(char *)malloc(sizeof(char) * num);
}
int main(void)
{
char *str=NULL;
GetMemory(&str,100);
strcpy(str,"hello");
}
5、#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void my_strcpy(char *dest, char *src,int num)
{
while(num)
{
while(*(dest++)=*(src++)!='\0')
num--;
}
*dest = '\0';
}
int continumax(char *outputstr,char *inputstr)
{
int max=0;
int count=0;
while(*inputstr !='\0')
{
while(*inputstr >='0'&& *inputstr<='9'&& *inputstr !='\0')
{
count++;
inputstr++;
}
if(max < count)
{
max = count;
my_strcpy(outputstr,inputstr-count,count);
}
count=0;
inputstr++;
}
return max;
}
int main()
{
int num;
char out_str[100];
char *in_str[100];
if(in_str==NULL)
{
printf("mallco error!\n");
}
scanf("%s",in_str);
num = continuemax(out_str,in_str);
printf("the of num is %d\n",num);
printf("the max num_str is %s\n",out_str);
return 0;
}
经过了这一天的学习,我对与指针、数组、指针函数还有很多迷糊,但比之前好多了希望在这之后的几天能够彻底弄清楚,还有希望明天的考试大家都有好运!