C语言数组遇见问题了(50分)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言数组遇见问题了(50分)相关的知识,希望对你有一定的参考价值。
我想通过排序然后找到相同元素,用后面的元素替代前者,可是不知道哪里错了!请改正!
//我想实现的功能是输入一组数据,将他们相同的元素剔除掉,只保留一个,然后排序输出!
#include <stdio.h>#include <stdlib.h>
int main() int i; scanf("%d",&i);
int j; int num[20]; int save[20]; for(j=0;j<i;j++) scanf("%d",&num[j]); save[j]=num[j]; int as,sd;//排序 int t; for(as=0;as<i;as++) for(sd=0;sd<i;sd++) if(num[as]<num[sd]) t=num[sd]; num[sd]=num[as]; num[as]=t;
int xc;//剔除相同元素 int cv; for(xc=0;xc<i;xc++) for(cv=xc+1;cv<i;cv++) if(num[xc]==num[xc+1]) num[cv]=num[cv+1]; continue;
int zx;//把数据打印出来 检查结果 for(zx=0;zx<i;zx++) if(num[zx]!=0) printf("%d\t",num[zx]);
return EXIT_SUCCESS;
这段代码写的有点糟糕! 当然初学者难免会这样..
建议有个错误处理机制 ,用户的操作是无法预测的, 所以你要确保数组不会越界;
你的排序写法完全是错误的,尽管它运行的结构是正确的,但是那只是因为多了一个比较级产生的,和你的代码想表达的意思完全相反;(你比较了2^n 次 ) 建议把 选择 插入 冒泡排序认真看一遍;
剔出相同的元素那个for 循环完全是错误的; 首先 它 造成了数组越界,其实 你 弄错了 continue 关键词的意思(这里的continue 完全多余) ,再次 num[cv]=num[cv+1]; 这句代码有很大的问题 首先 它可能导致越界;(cv=xc+1,当xc 是最后一个元素时,数组就越界了),第二它造成了新的重复元素; 好的方式 是用另一个数组来存放 单一的元素,或者用list vector 等容器,这样就可以删除重复元素而不引入新的重复元素;
1 2 2 3 4 4 5 7 8
当判断到xc=1的时候判断 if(num[xc]==num[xc+1])成立,执行代码,数组变成
1 2 3 3 4 4 5 7 8
之后的判断就不成立,
当xc=2时,数组变成
1 2 3 4 4 4 5 7 8
当xc=3时,此时if(num[xc]==num[xc+1])每一次内循环都会成立数组变成
1 2 3 4 4 5 7 8 0
关键问题就出在这里,你的xc值是4了,即指向第五个数组元素4,此后所有的判断都不会成立了,所以输出的数组就为上述这样了,所以你每次碰到三个以上相同的数时候就不能剔除完全,所以你应该在循环里面加一个判断,如果判断if(num[xc]==num[xc+1])没有成功的时候xc++,执行判断以后不要直接xc++。
我没写代码,没有时间写,你自己测试一下吧。 参考技术B #include <stdio.h>
#include <stdlib.h>
int main()
int i;
int j;
int num[20];
int save[20];
int as,sd;//排序
int xc;//剔除相同元素
int t;
int cv;
int zx;//把数据打印出来 检查结果
scanf("%d",&i);
for(j=0;j<i;j++)
scanf("%d",&num[j]);
save[j]=num[j];
for(as=0;as<i;as++)
for(sd=0;sd<i;sd++)
if(num[as]<num[sd])
t=num[sd];
num[sd]=num[as];
num[as]=t;
for(xc=0;xc<i-1;xc++)
if(num[xc]==num[xc+1])
for(cv=xc+1;cv<i-1;cv++)
num[cv]=num[cv+1];
i--;
xc--;
for(zx=0;zx<i;zx++)
printf("%d\t",num[zx]);
return EXIT_SUCCESS;
参考技术C 剔除相同元素部分程序修改一下:
int n;
n=i;
for ( xc=i-1;xc>0;xc-- )
if ( num[xc]==num[xc-1] )
for ( cv=xc;cv<i;cv++ )
num[cv-1]=num[cv];
i--;
追问
麻烦你能不能解释得详细一下,这样改的原因!我理解起来有点晦涩!谢谢你了!
追答这段程序的思路是:
从最后一个数开始到第2个数进行判断
如果当前数与前面一个数相等,则之后的数顺序向前移动一位,并且总数减1
比如:1 2 3 4 4 5 7 8,如果循环到当前数是第5个数4时,进行判断前面的第4个数也是4,那么从第5到最后一个数顺序向前移动一位:1 2 3 4 5 7 8 8并且总数减1,即1234578是有效数
c语言数组在内存中是怎么分配的?
比如int a[10]
比如我的栈区的内存栈底是高地址,char i,a【10】是怎么分配的呢
我是用vc6调试的,看来结果跟大家的一样,char[9]和i相差了3个地址,也就是他们之间空了两个地址,
我就想知道这是怎么回事,内存对齐的话为什么是空两个地址呢?
i和数组都是字符型的,为什么会牵扯到内存对齐的问题呢?
C语言使用的内存是虚拟内存。按照功能的不同在C语言中又将虚拟内存为分三类:栈区、堆区、静态数据区,不管是单一变量还是数组,其内存分配都是这样分的。
在栈区、静态数据区、堆区会有编译器负责分配、操作系统负责管理,程序员可以在堆区使用malloc()来动态分配堆内存的问题。
扩展资料
内存的分配和释放注意事项:
1、malloc和free是库函数,不是系统调用
2、malloc实际分配的内存可能会比请求的多---有些编译器分配时是以4字节为单元的
3、不能依赖于不同平台的下的malloc
4、当请求的动态内存无法满足时malloc返回的是NULL
5、当free的参数为NULL时,函数直接返回
参考资料来源:百度百科—数组
参考资料来源:百度百科—c语言
参考技术AC语言使用的内存是虚拟内存。按照功能的不同在C语言中又将虚拟内存为分三类:栈区、堆区、静态数据区,不管是单一变量还是数组,其内存分配都是这样分的。
虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。目前,大多数操作系统都使用了虚拟内存,如Windows家族的“虚拟内存”;Linux的“交换空间”等。
扩展资料:
如果有过用其它语言编程的经历,那么想必会熟悉数组的概念。由于有了数组,可以用相同名字引用一系列变量,并用数字(索引)来识别它们。在许多场合,使用数组可以缩短和简化程序,因为可以利用索引值设计一个循环,高效处理多种情况。数组有上界和下界,数组的元素在上下界内是连续的。因为 Visual Basic对每一个索引值都分配空间,所以不要不切实际声明一个太大的数组。
此处数组是程序中声明的变量数组。它们不同于控件数组,控件数组是在设计时通过设置控件的 Index 属性规定的。变量数组总是连续的;与控件数组不同的是,不能从一个数组的中部加载或卸载数组元素。
参考技术BC语言中内存为分三类:栈区、堆区、静态数据区。
局部变量在栈上分配,函数调用前的栈指针,要和函数返回后的栈指针一样,否则就会出错。
void test(void)
char i,a[10];
printf("0x%x", &i);
printf("0x%x", a);
printf("0x%x", a+1);
printf("0x%x", a+2);
printf("0x%x", a+3);
扩展资料
c语言数组在内存分配
示例:
#include<stdio.h>
int main()
int a[4] = 11,12,13,14;
int b[4] = 21,22,23,24;
int *pa = &a;
int i = 0;
while(i<8)
i++;
printf("now *p value = %d and",*pa);
printf("p addr value = %d \\n",pa);
pa++;
return 0;
参考技术C使用C语言编程,实际上使用的内存只有一种——虚拟内存。根据功能的不同在C语言中又将虚拟内存为分三类:栈区、堆区、静态数据区,无论单一变量还是数组,其内存分配都是如此。其中,栈区、静态数据区、堆区都会有编译器负责分配、操作系统负责管理,程序员可以在堆区使用malloc()来动态分配堆内存。
1、栈区:一般每一个函数对应一个栈区,在编译原理中称为栈帧。比如下面的代码:
int main()//定义一个有20个int元素的数组。此时数组a分配的虚拟内存称为栈区,有编译器自行分配。
int a[20] = 0;
return 0;
2、静态数据区:这实际上对应于生成的可执行文件的.data区段,因为这个区段在生成的可执行文件中,因此是“静态的”。比如下面的代码:
//定义一个20个int元素的全局数组,此时数组分配的虚拟内存称为静态数据区,有编译器自行分配。int g_a[20];
int main() return 0;
3、堆区:堆区是最复杂的,有操作系统负责堆管理,但是当用C语言编译器生成一个可执行文件并且运行时,它会默认建立一些堆。拿Windows来说,每一程序运行,它会建立至少两个堆,一个是默认堆,一个是new堆。比如下面的代码:
int main()int *pa = (int*)malloc(sizeof(int)*20);//分配20个int元素大小的堆空间。
return 0;
参考技术D
关于多个变量一起定义的时候分配内存,是和具体的编译环境有关的。这里举VC++6.0和TC2.0为例,这段源代码是以.c扩展名保存的。#include <stdio.h>
int main()
char i,a[10];
printf("%x\\t%x\\t%x\\n",&i,&a[0],&a[9]);
return 0;
运行结果如图。左侧为TC2.0编译出来的,右侧为VC++6.0编译出来的。可以看出在栈区数组下标是向高地址方向增长的,这一点没有疑问。但是i和数组a的前后关系却有差异。在TC2.0中i位于低地址端而在VC++6.0中i却位于高地址端。
楼主如果有其他的编译环境也可以试试看。
以上是关于C语言数组遇见问题了(50分)的主要内容,如果未能解决你的问题,请参考以下文章