㈠ 存在的变量为什么加下标
代表起始地址。
针经常与下标配合使用,形同数组。这才让很多人把数组与指针混淆了。而指针变量加上下标,代表的意义就是指针中的值就是起始地址,下标则是从指针中存储的地址作为起始地址开始偏移的。
㈡ 数组下标用变量
对于ANSI 标准C及C++,这都是标准没有定义的,也就是说,最好认为不可以用变量代入数组个数
C99标准中加入了这个特性,但C99标准还未流行。
对于C++编译器,gcc扩充了这个功能,但是它未被标准支持所以这样的程序是不具备编译可移植性的。早期的vc++6.0不支持此特性。
但是你若在c++中定义const int n = 5;
则可以int a[n];
因为c++中,const型变量是作为编译时常量的。
但在ANSI C中却不行,因为C中const型变量是作为只读的变量出现的,所以不能用其定义数组个数
虽然在汇编的角度看,int a[n];这种语句即使n是变量,也是很好实现的,但c/c++出于多种考虑(例如n的不确定性以及楼上提到的一点原因)拒绝了它
要模拟动态数组,最好使用new,malloc类似函数动态分配内存,这样的程序才是最安全的
-----------------------------------------------------------------
楼主,我看大师Steve Summit的书,他告诉我说去在意不同的编译器之间的对标准的支持程度的不同是没多大意义的。我们只需知道ANSI C/C++两者的标准定义行为,对未定义行为及不确定行为不同的编译器有不同的实现与扩展,也尽量不要去用,尽管某些编译器出于好意扩展了某些行为
-------------------------------------------------------------
这里看到了对宏的讨论。宏是预处理器管的范畴,而非编译器的范畴
要想真正理解以上所有这些,请看大师的书:《C Programming FAQs》与《C++ Primer》,前者对应C,后者对应C++。
单在这里讨论是理解不了的
㈢ C语言中每个变量或者元素都有下标,下标的作用是什么谢谢
C语言中变量或者元素都有下标,是因为表示数组的某个元素,比如a[4],表示数组的第5个元素,数组元素下标是从0开始的。
㈣ 在C语言中,数组定义时的下标不能用变量表示(即使它已经被赋值),如int [n];为什么能把变量的定义过程详...
在编译的时候,数组需要一个指定的大小。n必须是常数,而你说的赋值在编译的时候编译器并不知道n到底是多少,运行时候才知道,所以编译不通过。
若要动态开辟内存,可用malloc,用完之后用free释放即可。
㈤ 如何在C/C++中数组的下标使用变量
对于ANSI 标准C及C++,这都是标准没有定义的,也就是说,最好认为不可以用变量代入数组个数
C99标准中加入了这个特性,但C99标准还未流行。
对于C++编译器,gcc扩充了这个功能,但是它未被标准支持所以这样的程序是不具备编译可移植性的。早期的vc++6.0不支持此特性。
但是你若在c++中定义const int n = 5;
则可以int a[n];
因为c++中,const型变量是作为编译时常量的。
但在ANSI C中却不行,因为C中const型变量是作为只读的变量出现的,所以不能用其定义数组个数
虽然在汇编的角度看,int a[n];这种语句即使n是变量,也是很好实现的,但c/c++出于多种考虑(例如n的不确定性以及楼上提到的一点原因)拒绝了它
要模拟动态数组,最好使用new,malloc类似函数动态分配内存,这样的程序才是最安全的。
数组的引用下标可以是变量常量
㈥ 关于C语言编程 的下标是指什么
在C语言中,下标用于数组的访问(读或写)。
当定义一个数组时,形式为
TYPE array_name[NUM];
即定义一个元素类型为TYPE,共计NUM个元素的数组,名为array_name。
对于标准C语言(ANSI C), 数组长度NUM必须为常量,但是目前大多数编译器均扩展到可以支持变量。
当访问数组元素时,就需要使用下标,格式为
array_name[index]
其中[index]就是数组的下标,含义为数组array_name的第index元素。
在C语言中,index是从0开始计数的,所以对于NUM个元素的数组,合法下标范围为0~NUM-1。
㈦ 如何使用一个变量表达出三维数据的每一个下标
《C++语言程序设计》课程辅导二(2.1)
------数组和字符串
一、数组的概念
在程序设计中存储单个数据时,需要根据数据的类型定义相应的变量来保存。如存储一个整数时需要定义一个整数变量来保存,存储一个实数时需要定义一个单精度或双精度变量来保存,存储含有多个成分的一个记录数据时,需要定义该类型的一个结构变量来保存。
若在程序设计中需要存储同一数据类型的、彼此相关的多个数据时,如存储数学上使用的一个数列或一个矩阵中的全部数据时,显然采用定义简单变量的方法是不行的,这就要求定义出能够同时存储多个值的变量,这种变量在程序设计中称为数组。
在实际应用中,一组相关的数据之间可能存在着一维关系,也可能存在着二维关系,等等。一个数列中的数据若是一维关系,则它除第一个数据外,每个数据只有一个直接前驱;除最后一个数据外,每个数据只有一个直接后继。假定一个数列为(38,42,25,60),则每个数的后一个数就是它的直接后继,每一个数的前一个数就是它的直接前驱,如42的直接前驱为38,直接后继为25。一个矩阵中的数据若二维关系,则它除第一行和第一列上的所有数据外,每个数据在行和列的方向上各有一个直接前驱;除最后一行和最后一列上的所有数据外,每个数据在行和列的方向上各有一个直接后继。假定一个矩阵为:
2 6 9 12
8 4 7 3
5 1 6 8
则每一个元素均处于相应行和列的交点位置上,虽然有的元素值相同,但由于所处的位置不同,所以是不同的元素。
在程序设计中,用一维数组表示和存储一维相关的数据,用二维数组表示和存储二维相关的数据,用三维数组表示和存储三维相关的数据,等等。假定一个数列为a1,a2,...,an,则需要用一个一维数组来存储,假定仍用a作为数组名,则a中应至少包含有n个元素,每个元素用来存储数列中一个相应的数据。若a中正好包含有n个元素,则这n个元素依次表示为a[0],a[1],...,a[n-1],用a[0]存储数列中的第一个数据a1,用a[1]存储数列中的第二个数据a2,依次类推。假定一个矩阵为:
a11 a12 ... a1n
a21 a22 ... a2n
...
am1 am2 ... amn
则需要用一个二维数组来存储,假定二维数组名用b表示,则b中应至少包含mn个元素,也就是说,第一维尺寸至少为m,第二维尺寸至少为n,该数组b中的每个元素用来存储矩阵中的一个相应的数据。
二、数组的定义
2.1 一维数组
1. 定义格式
一维数组同简单变量一样,也是通过变量定义语句定义的。其定义格式为:
<类型关键字> <数组名> [<常量表达式>] [={<初值表>}];
<类型关键字>为已存在的一种数据类型,<数组名>是用户定义的一个标识符,用它来表示一个数组,<常量表达式>的值是一个整数,由它标明该数组的长度,即数组中所含元素的个数,每个元素具有<类型关键字>所指定的类型,<常量表达式>两边的中括号是语法所要求的符号,不是标明其内容为可选而使用的符号,<初值表>是用逗号分开的一组表达式,每个表达式的值将被赋给数组中的相应元素。
当数组定义中包含有初始化选项时,其<常量表达式>可以被省略,此时所定义的数组的长度将是<初值表>中所含的表达式的个数。
一个数组被定义后,系统将在内存中为它分配一块含有n个(n为数组长度)存储单元的存储空间,每个存储单元包含的字节数等于元素类型的长度。如对于一个含有10个int型元素的数组,它将对应10*4=40个字节的存储空间。
定义了一个数组,就相当于同时定义了它所含的每个元素。数组中的每个元素是通过下标运算符[]来指明和访问的,具体格式为:“<数组名>[<下标>]”,这与数组的定义格式相同,但出现的位置是不同的,当出现在变量定义语句时则为数组定义,而当出现在表达式中时则为一个元素。
对于一个含有n个元素的数组,C++语言规定:它的下标依次为0,1,2,...,n-1,因此全部n个元素依次为a[0],a[1],a[2],...,a[n-1],其中假定a为数组名。
2. 格式举例
(1) int a[20];
(2) double b[MS]; //假定MS为已定义的整型常量
(3) int c[5]={1,2,3,4,0};
(4) char d[]={'a','b','c','d'};
(5) int e[8]={1,4,7};
(6) char f[10]={'B','A','S','I','C'};
(7) bool g[2*N+1]; //假定N为已定义的整型常量
(8) float h1[5], h2[10];
(9) short x=1, y=2, z, w[4]={25+x, -10, x+2*y, 44};
(10) int p[];
第一条语句定义了一个元素为int型、数组名为a、包含20个元素的数组,所含元素依次为a[0],a[1],...,a[19],每个元素同一个int型简单变量一样,占用4个字节的存储空间,用来存储一个整数,整个数组占用80个字节的存储空间,用来存储20个整数。
第二条语句定义了一个元素类型为double、数组长度为MS的数组b,该数组占用MS*8个字节的存储空间,能够用来存储MS个双精度数,数组b中的元素依次为b[0],b[1],...,b[MS-1]。
第三条语句定义了一个整型数组c,即元素类型为整型的数组c,它的长度为5,所含元素依次为c[0],c[1],c[2],c[3]和c[4],并相应被初始化为1,2,3,4和0。
第四条语句定义了一个字符数组d,由于没有显式地给出它的长度,所以隐含为初值表中表达式的个数4,该数组的4个元素d[0],d[1],d[2]和d[3]依次被初始化为’a’,’b’,’c’,和’d’。注意若没有给出数组的初始化选项,则表示数组长度的常量表达式不能省略。
第五条语句定义了一个含有8个元素的整型数组e,它的初始化数据项的个数为3,小于数组中元素的个数8,这是允许的,这种情况的初始化过程为:将利用初始化表对前面相应元素进行初始化,而对后面剩余的元素则自动初始化为常数0。数组e中的8个元素被初始化后得到的结果为:e[0]=1, e[1]=4, e[2]=7, e[3]e[7]=0。
第六条语句定义了一个字符数组f,它包含有10个字符元素,其中前5个元素被初始化为初值表所给的相应值,后5个元素被初始化为字符’\0’,对应数值为0。
第七条语句定义了一个布尔型数组g,它的数组长度为2*N+1,每个元素没有被初始化。
第八条语句定义了两个单精度型一维数组h1和h2,它们的数组长度分别为5和10。在一条变量定义语句中,可以同时定义任意多个简单变量和数组,每两个相邻定义项之间必须用逗号分开。
第九条语句定义了三个短整型简单变量x,y和z,其中x和y被初始化为1和2,定义了一个短整型数组w,它包含有四个元素,其中w[0]被初始化为25+x的值,即26,w[1]被初始化为-10,w[2]被初始化为x+2*y的值,即5,w[3]被初始化为44。
第十条语句是错误的数组定义,因为它既省略了数组长度选项,又省略了初始化选项,使系统无法确定该数组的大小,从而无法分配给它确定的存储空间。
3. 数组元素的访问
通过变量定义语句定义了一个数组后,用户便可以随时使用其中的任何元素。数组元素的使用是通过下标运算符[]指明和访问的,其中运算符左边为数组名,中间为下标。一个数组元素又称为下标变量,所使用的下标可以为常量,也可以为变量或表达式,但其值必须是整数,否则将产生编译错误。
假定a[n]为一个已定义的数组,则下面都是访问该数组的下标变量的合法格式:
(1) a[5] //下标为一个常数
(2) a[i] //下标为一个变量
(3) a[j++] //下标为后增1表达式
(4) a[2*x+1] //下标为一般表达式
假定在上述每个变量的下标表达式中,所使用的变量i,j和x的值分别为2,3和4,则a[i]对应的数组元素为a[2],a[j++]对应的数组元素为a[3],同时j的值被修改为4,a[2*x+1]对应的数组元素为a[9]。
使用一个下标变量同使用一个简单变量一样,可以对它赋值,也可以取出它的值。如:
(1) int a[5]={0,1,2,3,8}; //定义数组a并进行初始化
(2) a[0]=4; //把4赋给a[0]
(3) a[1]+=a[0]; //把a[0]的值4累加到a[1],使a[1]的值变为5
(4) a[3]=3*a[2]+1; //把赋值号右边表达式的值7赋给a[3]
(5) cout<<a[a[0]]; //因a[0]=4,所以a[a[0]]对应的元素为a[4],
//该语句输出a[4]的值8
C++语言对数组元素的下标值不作任何检查,也就是说,当下标值超出它的有效变化范围0n-1(假定n为数组长度)时,也不会给出任何出错信息。为了防止下标值越界(即小于0或大于n-1),则需要编程者对下标值进行有效性检查。如:
(1) int a[5];
(2) for(int i=0; i<5; i++) a[i]=i*i;
(3) for(i=0; i<5; i++) cout<<a[i]<<’ ’;
第一条语句定义了一个数组a,其长度为5,下标变化范围为04。第二条语句让循环变量i在数组a下标的有效范围内变化,使下标为i的元素赋值为i的平方值,该循环执行后数组元素a[0],a[1],a[2],a[3]和a[4]的值依次为0,1,4,9和16。第三条语句控制输出数组a中每一个元素的值,输出语句中下标变量a[i]中的下标i的值不会超出它的有效范围。如果在第三条语句中,用做循环判断条件的<表达式2>不是i<5,而是i<=5,则虽然a[5]不属于数组a的元素,但也同样会输出它的值,而从编程者角度来看是一种错误。由于C++系统不对元素的下标值进行有效性检查,所以用户必须通过程序检查,确保其下标值有效。
4. 程序举例
(1) #include<iostream.h>
void main()
{
int i, a[6];
for(i=0;i<6;i++) cin>>a[i];
for(i=5;i>=0;i--) cout<<a[i]<<' ';
cout<<endl;
}
在程序的主函数中首先定义了一个int型简单变量i和一个含有6个int型元素的数组a,接着使数组a中的每一个元素依次从键盘上得到一个相应的整数,最后使数组a中的每一个元素的值按下标从大到小的次序显示出来,每个值之后显示出一个空格,以便使相邻的元素值分开。
若程序运行时,从键盘上输入3,8,12,6,20,15这6个整数,则得到的输入和运行结果为:
3 8 12 6 20 15
15 20 6 12 8 3
(2) #include<iostream.h>
void main()
{
int a[8]={25,64,38,40,75,66,38,54};
int max=a[0];
for(int i=1;i<8;i++)
if(a[i]>max) max=a[i];
cout<<"max:"<<max<<endl;
}
在这个程序的主函数中,第一条语句定义了一个整型数组a[8],并对它进行了初始化;第二条语句定义了一个整型变量max,并用数组a中第一个元素a[0]的值初始化;第三条语句是一个for循环,它让循环变量i从1依次取值到7,依次使数组a中的每一个元素a[i]同max进行比较,若元素值大于max的值,则就把它赋给max,使max始终保存着从a[0]a[i]元素之间的最大值,当循环结束后,max的值就是数组a中所有元素的最大值;第四条语句输出max的值。
在该程序的执行过程中,max依次取a[0],a[1]和a[4]的值,不会取其他元素的值。程序运行结果为:
max:75
(3) #include<iostream.h>
const int N=7;
void main()
{
double w[N]={2.6,7.3,4.2,5.4,6.2,3.8,1.4};
int i,x;
cout<<"输入一个实数:";
cin>>x;
for(i=0;i<N;i++)
if(w[i]>x) cout<<"w["<<i<<"]="<<w[i]<<endl;
}
此程序的功能是从数组a[N]中顺序查找出比x值大的所有元素并显示出来。若从键盘上输入的x值为5.0,则得到的程序运行结果为:
输入一个实数:5.0
w[1]=7.3
w[3]=5.4
w[4]=6.2
(4) #include<iostream.h>
const int M=10;
void main()
{
int a[M+1];
a[0]=1; a[1]=2;
int i;
for(i=2;i<=M;++i)
a[i]=a[i-1]+a[i-2];
for(i=0;i<M;++i)
cout<<a[i]<<',';
cout<<a[M]<<endl;
}
该程序首先定义数组a,并分别为数组元素a[0]和a[1]赋值1和2,接着依次计算出a[2]至a[M]的值,每个元素值均等于它的前两个元素值之和,最后按照下标从小到大的次序显示出数组a中每个元素的值。该程序运行结果为:
1,2,3,5,8,13,21,34,55,89,144
㈧ C语言下标和指针的关系
指针与数组是C语言中很重要的两个概念,它们之间有着密切的关系,利用这种关系,可以增强处理数组的灵活性,加快运行速度,本文着重讨论指针与数组之间的联系及在编程中的应用。
1.指针与数组的关系
当一个指针变量被初始化成数组名时,就说该指针变量指向了数组。如:
char str[20], *ptr;
ptr=str;
ptr被置为数组str的第一个元素的地址,因为数组名就是该数组的首地址,也是数组第一个元素的地址。此时可以认为指针ptr就是数组str(反之不成立),这样原来对数组的处理都可以用指针来实现。如对数组元素的访问,既可以用下标变量访问,也可以用指针访问。
2.指向数组元素的指针
若有如下定义:
int a[10], *pa;
pa=a;
则p=&a[0]是将数组第1个元素的地址赋给了指针变量p。
实际上,C语言中数组名就是数组的首地址,所以第一个元素的地址可以用两种方法获得:p=&a[0]或p=a。
这两种方法在形式上相像,其区别在于:pa是指针变量,a是数组名。值得注意的是:pa是一个可以变化的指针变量,而a是一个常数。因为数组一经被说明,数组的地址也就是固定的,因此a是不能变化的,不允许使用a++、++a或语句a+=10,而pa++、++pa、pa+=10则是正确的。由此可见,此时指针与数组融为一体。
3.指针与一维数组
理解指针与一维数组的关系,首先要了解在编译系统中,一维数组的存储组织形式和对数组元素的访问方法。
一维数组是一个线形表,它被存放在一片连续的内存单元中。C语言对数组的访问是通过数组名(数组的起始地址)加上相对于起始地址的相对量(由下标变量给出),得到要访问的数组元素的单元地址,然后再对计算出的单元地址的内容进行访问。通常把数据类型所占单元的字节个数称为扩大因子。
实际上编译系统将数组元素的形式a[i]转换成*(a+i),然后才进行运算。对于一般数组元素的形式:<数组名>[<下标表达式>],编译程序将其转换成:*(<数组名>+<下标表达式>),其中下标表达式为:下标表达式*扩大因子。整个式子计算结果是一个内存地址,最后的结果为:*<地址>=<地址所对应单元的地址的内容>。由此可见,C语言对数组的处理,实际上是转换成指针地址的运算。
数组与指针暗中结合在一起。因此,任何能由下标完成的操作,都可以用指针来实现,一个不带下标的数组名就是一个指向该数组的指针。
4.指针与多维数组
用指针变量可以指向一维数组,也可以指向多维数组。但在概念上和使用上,多维数组的指针比一维数组的指针要复杂一些。
例如,在一个三维数组中,引用元素c[i][j][k]的地址计算最终将换成:*(*(*(c+i)+j)+k)。了解了多维数组的存储形式和访问多维数组元素的内部转换公式后,再看当一个指针变量指向多维数组及其元素的情况。
1 指向数组元素的指针变量
若有如下说明:
int a[3][4];
int *p;
p=a;
p是指向整型变量的指针;p=a使p指向整型二维数组a的首地址。
*(*(p+1)+2)表示取a[1][2]的内容;*p表示取a[0][1]的内容,因为p是指向整型变量的指针;p++表示p的内容加1,即p中存放的地址增加一个整型量的字节数2,从而使p指向下一个整型量a[0][1]。
2 指向由j个整数组成的一维数组的指针变量
当指针变量p不是指向整型变量,而是指向一个包含j个元素的一维数组。如果p=a[0],则p++不是指向a[0][1],而是指向a[1]。这时p的增值以一维数组的长度为单位。
5.指针与字符数组
C语言中许多字符串操作都是由指向字符数组的指针及指针的运算来实现的。因为对于字符串来说,一般都是严格的顺序存取方式,使用指针可以打破这种存取方式,更为灵活地处理字符串。
另外由于字符串以′\0′作为结束符,而′\0′的ASCII码是0,它正好是C语言的逻辑假值,所以可以直接用它作为判断字符串结束的条件,而不需要用字符串的长度来判断。C语言中类似的字符串处理函数都是用指针来完成,使程序运行速度更快、效率更高,而且更易于理解。
㈨ C语言中数组元素的下标可不可以是数组元素,另外··
C语言程序运行时,数组的存在形式是内存中的一块连续地址空间。而访问数组元素时,计算机会将下标做为空间首地址的偏移量来进行寻址,所以当然可以是任何整形数。
比如int array[10],array的地址是0x7FFFFF00,那么在访问array[3]时,计算机是这样计算的:
每个整形数大小为4个字节,所以用array的地址加上3乘以4,得到0x7FFFFF0C,那么从0x7FFFFF0C到0x7FFFFF0F这4个字节的值就是array[3]的值。
所以无论传入的下标是什么,理论上都可以计算得到一个地址,但是这个地址不一定是有效的。如果地址无效,就会发生段错误(segmentation fault),也即数组越界/地址访问越界。现在的编译器会认为只要下标是个整型变量,就是可以的,但是执行的时候操作系统仍然会进行监测,否则会影响其他程序的运行。
比如说a = {1, 2, 4, 5, 7}, b = { 1, 2, 3, 4, 5, 6, 7, 8 },那么b[a[3]] = b[5]=6,这个是可以允许的。
㈩ 数组什么是下标变量
比如有一个数组:arr[5]={6,7,8,9,10};
当你要用到这个数组第二个元素时,你就可以用arr[1]来代表第二个元素7,这里的1就是下标变量。变量与下标变量的区别在于:下标变量只能是一个非负的整型值,而变量即可以表示正数也可以表示负数。第二,变量表示的数值可以很大,但下标变量表示的值是有一定范围的。比如说上面这个数组,它的下标的范围就只能是0-4,如果你要用6作这它的下标,就会出现错误。因为编译器在这个数组里找不到这个元素。记住:在C/C++里所有数组的下标都是从0开始的