您的位置:首页 > 其它

关于动态存储分配函数的调用,在已经过排序的数组中查找及删除内容的操作,余数的分析,删除字符数组中的空格,对链表的逆置,在源字符串中查找子字符串的个数,函数指针以及函数的调用,循环赋值带来的问题以及插入

2012-08-16 20:11 1011 查看
其一:关于动态存储分配函数的调用

STU *fun(STU a[ ], int m) //主函数中调用函数语句:pOrder=fun(a,m);

{ //函数功能为查找结构体数组中前m名学生成绩,并输出

STU b
, *t;

int i,j,k;


// t=(STU *)calloc(m,sizeof(STU)); 这是一句被屏蔽的语句

t=(STU *)calloc(sizeof(STU),m); //实际上以上这两个语句都被运行成功,为什么?我想说明的问题是:calloc( , )函数中参数位置是否能调换?

for(i=0; i<N; i++)

b[i]=a[i];

for(k=0; k<m; k++)

{

for(i=j=0; i<N; i++) //i作为标记,一直向后移动,遍历整个结构体中数据

if(b[i].s > b[j].s)

j=i; //找出最大的数所在的结构体的序号

t[k]=b[j]; //实际上是在b
这个新建的数组中进行操作的,原来的数据并没有被破坏

b[j].s=0; //将前面的已经比较的分数赋予0值,不再参加比较

}

return t;

}

其二:在已经过排序数组中实现查找和删除功能(实际上还有改进的地方!)

int fun(int a[], int n) //for()语句的思想是使用了两个flag实现的

{ //函数功能是在数组中查找相同数据,并删除相同的,保留一个
int m=1;
for(int i=1,j=0;i<n;i++) //只用了一个for循环和一个if...else语句实现查找删除功能

if(a[j]==a[i]) //此处是为了判断i后面是否仍存在相同数据

; //这是一个空语句,最给力的就是这两个标志i和j

else
{
j++; //否则,将j向后移动,准备覆盖相同数据
a[j]=a[i];
m++; //将i++功能都放在了for语句的判断部分中

}
return m; //最后返回的是除去相同数值后,数组中剩余数的数目

}

其三:求余数,对余数的分析。

unsigned fun ( unsigned w ) //函数的功能是求n位数w的n-1位数w`,比如数1987,调用函数求出值为987

{
if(w>10000) w%=10000; //一个数对10000求余数,余数是小于10000

else if(w>1000)

w%=1000; //一个数对1000求余数,余数小于1000,依次类推,就能求出低n-1位数

else if(w>100)
w%=100;
else if(w>10)
w%=10;
return w ; //求出的数值就是所求的低n-1位数

} //我仅知道一个数能对10求余数,而不知道能对任何数求余数

其四:删除字符数组中的空格(这样写是有错误的!)

void fun(char *str) //函数调用语句:fun(str); 函数的功能是删除字符串中所有的空格字符

{

char a[81]; //重新定义了一个字符数组

int i=0,n=0;

for( ;*str!=NULL; )

a[n++]=*str++; //这里将原数组进行了赋值,运行最后指针指向的是字符串的末尾

a
=NULL;

for( n=0;a
!=NULL; )

if(a
==' ')

n++;

else

str[i++]=a[n++]; //虽然字符数组的指针使用可以和数组差不多,实际上这个程序是运行不出来的!程序很繁琐

str[i]=NULL;

}

下面的程序是正确的:

void fun(char *str)

{

int i=0,j=0;

for(;str[i]!=NULL&&str[j]!=NULL;) //证明了字符数组的指针可以当做数组来进行操作,而且这里所用到的判断很给力,很精确

{ //这里需要注意的是当str[j]==NULL时,将会结束

for( ;str[j]!=NULL; )

if(str[j]==' ')

j++;

else

{str[i++]=str[j++];break;} //此处跳出了循环,改变了j的取值

}

str[i]=NULL; //在逻辑上是没有任何问题的,思路方面都是用到了两个标志i和j

}

其五:对链表的逆置

void fun(NODE *h) //调用函数语句:fun(head); 函数的功能是对链表进行逆置

{

NODE *p, *q, *r;

p = h->next;

if (p==NULL)

return; //函数没有返回值,在书写return语句时,不能写返回0或是1

q = p->next;

p->next = NULL;

while(q)

{

r = q->next;

q->next = p;

p = q;

q =r;

}

h->next = p;

} //程序思路是将原链表中的每一个结点取出,在第一个结点的前面做添加结点操作

其六:在源字符串中查找子字符串的个数

int fun(char *s, char *t) //函数调用语句:m=fun(a, b);

{

int n;

char *p , *r;

n=0;

while(*s) //这里比较要从源字符串的每一个字符开始进行比较

{

p=s; //s指针的指向已经发生了改变

r=t;

while(*r) //循环比较

if(*r==*p)

{ r++; p++; }

else break; //break跳出所在的循环语句,去执行下面的语句,而不等到判断*r是否指向最后的空字符

if(*r==0) //如果r指向的是空字符,说明存在这个子字符串

n++;

s++; //实际上是从源字符串的每一字符开始比较的

}

return n; //函数返回相同字符串的个数

}

其七:分析函数指针,函数指针指向要调用的函数
double f1(double x)
{ return x*x; }

double f2(double x, double y)
{ return x*y; }

double fun(double a, double b) //函数调用语句:r = fun(x1, x2);
{
double (*f)( ); //定义了函数的指针
double r1, r2;
f=f1; /* point fountion f1 指针指向函数f1*/
r1=( *f )( a ); //调用函数f1
f=f2; /* point fountion f2 指针指向函数f2*/
r2 =( *f )( a , b ); //调用函数f2
return r1 + r2;
}
出现的问题:
“=”: 无法从“double (__cdecl *)(double)”转换为“double (__cdecl *)(void)”
1> 该转换要求reinterpret_cast、C 样式转换或函数类型转换
1>c:\documents and settings\administrator\my documents\visual studio 2008\c\c46\c46\c46.cpp(16) : error C2197: “double (__cdecl *)(void)”: 用于调用的参数太多
1>c:\documents and settings\administrator\my documents\visual studio 2008\c\c46\c46\c46.cpp(18) : error C2440: “=”: 无法从“double (__cdecl *)(double,double)”转换为“double (__cdecl *)(void)”
1> 该转换要求reinterpret_cast、C 样式转换或函数类型转换
1>c:\documents and settings\administrator\my documents\visual studio 2008\c\c46\c46\c46.cpp(19) : error C2197: “double (__cdecl *)(void)”: 用于调用的参数太多
P.S. 这些问题都是在调用函数时发生的,比如:r1=( *f )( a ); r2 =( *f )( a , b );
实际在定义这个函数指针时:double (*f)( ); 其中是没有参数的,所以会发生这样的错误,我想问的是这样的错误怎么解决?

其八:循环赋值带来的问题

int fun(char *str) //函数调用语句:fun(s) 这个函数是判断字符串是否为回文

{

int i=0;

char *p;

p=str;

for(;*p!=NULL;p++)

i++;

p=str+i-1; //p指向最后一个字符

for(i=1;str<=p;p--,str++) //i=0,i作为标致。通过指针来判断是否退出循环

{ //一个指针向前循环,一个指针向后循环,完成判断

if(*str!=*p)

{ i=0;break; } //break;语句退出循环,说明该字符串不是回文

else

; //i=1。这里会输出最后一次比较的结果,而不是其中的某一次,因此在这里不能够重复给i赋值

}

return i;

}

其九:插入排序算法的实现

void insert(char *aa) //函数调用语句:insert(a);

{

int i,j,n;

char ch;

n=strlen(aa);

for( i=1; i<n ;i++ )

{

ch=aa[i];

j=i-1;


while ((j>=0) && ( ch<aa[j] ))

{ aa[j+1]=aa[j]; //aa[j+1]==aa[i] 但是不能用i替换,j这个变量很重要

j--;

}

aa[j+1]=ch;

}

}

P.S.这是经典的插入排序算法,这个程序写地很精巧,真的应该好好的记住算法。

以上就是我这几天的成果了,一些好的算法我们应该仔细分析其精妙之处,一些不懂的地方还要好好琢磨。从实践中来到实践中去,将实践中的经验总结下来,供以后的自己看看,并有效地运用到工作中去。在以上几点中还透露出一些问题,这些问题后面在学习C Primer Plus过程中应该会遇到,希望自己以后能完全弄明白。我相信通过自己的努力能够精通C语言,还能够做到一通百通。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐