精华内容
下载资源
问答
  • 2016-05-03 10:27:40

    今天偶然间看到一个问题,于是乎去学习了下,记录一下对数组名的一个知识点。

    数组名:是指针常量。

    出错代码:
    int aa[10] = {0};
    int num = 0;
    for(num = 0; num < 10; num ++)
    {
        aa[num] = num;
    }

    int *bb = (int *)malloc(40);
    memset((void *)bb, 0, 40);

    for(num = 0; num < 10; num ++)
    {
        printf("%d\n",aa[0]);
        ++aa;
    }

    编译就无法通过:error: lvalue required as increment operand

    正确代码:
    for(num = 0; num < 10; num ++)
    {
        printf("%d\n",bb[0]);
        ++bb;
    }

    原因:aa 数组名是指针常量,不可以进行自加运算。

    延伸拓展:
    (1) 数组名表示的就是一种数据结构,就是数组;

    (2) 数组名可以转换成一个指针常量;

    (3) 指向数组的指针则是指针变量,存放着的是数组的地址!

    下面又出现一个问题:

    void arrayTest(char str[])
    {
        printf("%d\n",sizeof(str));
    }
    int main()
    {
        char str1[10] = "I Love U";
        arrayTest(str1);
        return 0;
    }

    打印结果为4(32位系统)/8(64位系统)。

    原因分析 :当数组名作为形参传入时候,只是一个指针变量了,可以做自增、自减操作。
    形参char str[]等同于char *str

    补充说明:对于一个指针来说,char *aa = (char *)malloc(10);
    以下运算合法,与aa是不是数组无关。
    *(aa + n) = aa[n];  (n < 10)


    还有一点需要说明:

    对于上面例子中的bb指针来说,不需要做free(bb)操作,因为aa在结束时候会被干掉,bb要是free的话会造成二次free,这样就报错了。

    更多相关内容
  • 一、指向数组元素的指针变量的定义赋值 二、通过指针引用数组元素 三、数组作为函数参数 四、指向多维数组的指针和指针变量探究 五、指针数组和数组指针 一、指向数组元素的指针变量的定义赋值 数组...

    目录

    一、指向数组元素的指针变量的定义和赋值

    二、通过指针引用数组元素

    三、数组名作为函数参数

    四、指向多维数组的指针和指针变量探究

    五、指针数组和数组指针


    一、指向数组元素的指针变量的定义和赋值

    数组指针是指数组的开始地址(首地址),数组元素的指针就是数组元素的地址。

    a[3]=6;下标法引用数组元素,也可以用指针引用数组元素。

    int a[5]={5,6,7,8,9};能引用的是0--4,只要是数组,那么数组元素的内存一定是紧挨着的,从首地址开始以数据类型所占字节进行叠加。

    注意:数组名a代表的是数组的首地址,即数组名a等于数组中首元素的地址,a==&a[0]

    定义指针变量时也可以给指针变量赋初值:int *p=a或*p=&a[0];

    二、通过指针引用数组元素

    1. *p=19;等价于a[0]=19;

    2. p=p+1//增加了4,比如原来p=1000,p+1后p=1004,指针变量内保存的地址加上sizeof(类型)。
      dd133fc766da56dd159df4fba09f2235.png
    3. p+i 或者 a+i (i是数组元素的小标
      假如现在p指向数组首地址,a是数组名(代表数组首地址),那么p+i 或者 a+i 就是数组元素a[i]的地址,也就是她们指向了数组a的第i个元素。 相当于,p+3为&a[3]. 结论:p+i 或者 a+i 都是地址,可以赋给指针变量。
      ecb18a20a932c5e97458e6c60569fec8.pngff67405fb6e784b12aca859db8c22cb5.png9a3ba7b2d9107d56eadefde3d53e3888.png

    4. *(p+i)或者*(a+i):
      从第3条可得,这两个是p+i a+i所指向的数组元素,也就是a[i],比如说*(p+2)或者*(a+2)就是a[2].
      785b465aab9b392c1a216d091c94eb8e.png

    5. p[i]
      p[i] == *(p+i) == a[i]
      p[3]=19,则a[3]=19.
      引用数组元素有很多方法:a[i];p[i];*(p+i);*(a+i);
      0cf25defb34f5d1470076a7d75d374fc.png3d7e52c1148f424a44eb70297a855bdb.png

    6. *p++:
      优先级相同,并且都是从右到左的结合性,所以等价于*(p++)
      p++为先用后加,所以*(p++)整个作用是:得到p指向的变量的值(*p),然后再使p指针自增,指向下一个数组元素。
      printf("%d\n",*p++);先打印出a[0]的值,然后p指向了a[1]。
    7. *++p:
      相当于*(++p),和第六不同,++p是先加后用,p会先自增1,;然后再去用p值。
      printf("%d\n",*++p);p指向了a[1],打印a[1]的值。
    8. (*p)++:
      表示p所指向的元素加1,如果p指向数组首地址,那就等价于a[0]++;实际上是数组元素值+1,不是指针+1.

     

    三、数组名作为函数参数

    如果一个实参的数组,想在函数中改变此数组的元素的值,实参和形参的对应关系有4种:

    1. 实参和形参都是数组名
      a是实参数组首地址,那么ba是形参数组首地址,a和ba共用一段内存,也就是说,再调用changevalue期间,a和ba指的是同一个数组。
       

    2. 实参用数组名,形参用指针变量
      fd5428835e51e90c8b7697cfa5349b2a.png

    3. 实参和形参都用指针变量
      0b80c958a1c0e27efccafddb1c6b7cb5.png

    4. 实参为指针变量,形参为数组名。
      d9847f1fb0c38856146050b9dbff5349.png

    四、指向多维数组的指针和指针变量探究

    可以把二维数组名a看成一个一维数组,这个一维数组有三个元素:a[0],a[1],a[2],每个元素又是一个包含4个元素的一维数组。

    1ce440f856e94aedd658701de4da43f5.png 

    1. a:二维数组名,也是整个二维数组的首地址。 假设第0行的首地址是1000。
      int a[3][4];
      int *p;
      p=(int *)a;//有时将数组名赋给指针变量,系统不答应,那么就用强制转化符。
       
    2. a+1,a+2 分别代表 第一含首地址和第二行首地址。所以a+1跳过16个字节的,也就是a=1000,a+1=1016,a+2=1032.
    3. 这表示a[0], a[1], a[2]是一维数组名。C语言规定数组名代表数组的首地址,所以有如下:
      2d6e244a2b27c89de6f88916b3cd20f9.png

    4. 第0行第1列元素地址表示方法有:
      &a[0][1] a[0]+1 ----1004
      p=&a[0][1];等价于p=a[0]+1;
    5. 结论:
      a[0]等价于*a,都是地址1000, a==*a,都是地址;
      a[0]+1等价于*a+1,等价于&a[0][1],等价于1004;
      a[1] 等价于*(a+1),等价于1016;
      a[1]+2 ,等价于*(a+1)+2,等价于&a[1][2],等价于1024.注意不要把 *(a+1)+2写成*(a+3),那就变成了a[3];
    6. a[0]+1 等价于 *a+1,等价于&a[0][1] ,等价于 1004,这是个地址。
      *(a[0]+1)就代表 a[0][1] 的值;*(*a+1)也是a[0][1]的值
      也有:*(a[1]+2), a[1][2]的值,*(*(a+1)+2),都表示第1行第2列元素值。

    在二维数组中,a[i]和&a[i]地址值是一样的。

    实践:553f338d8daa9782ce7fc9a655c536e0.png

    五、指针数组和数组指针

    指针数组:

    首先这是个数组,数组中有10个元素,每个元素都是个指针,相当于定义了10个指针变量。

    int *p1[10];

     df62cb4e8833e14d08ca525c5e8226d3.png

    数组指针:

    int (*p)[10];这是一个指针变量,这个指针变量用来指向含有10个元素的一维数组。

    780d429fe47135989c75c56169b763f3.png2a5a35e6fe3684963c92b47931ddcbd8.pngcbde55ae88a6e9638f531f9fde33009a.png 

    展开全文
  • 数组名指针变量作函数参数的四种情况 2016年10月02日 13:43:49 阅读数:2154 函数的参数可以是变量,也可以是数组。当整个数组作为函数的参数时,实际上是数组的地址作为参数。由于实参可以是表达式,数组元素...

    数组名,指针变量作函数参数的四种情况

    2016年10月02日 13:43:49

    阅读数:2154

    函数的参数可以是变量,也可以是数组。当整个数组作为函数的参数时,实际上是数组的地址作为参数。由于实参可以是表达式,数组元素也可以是表达式的一部分,因此,数组元素可以作为函数的实参,这时对应的形参应该是变量,与变量作实参一样,数组元素把他的值传递到系统为形参变量分配的临时存储单元中,是单向的“值传递”。

    当数组名作函数的参数时,传递到是数组的起始地址,形参是用来接受从实参传递过来的实参数组的地址的。因此,形参应该是一个地址变量(只有指针才能存放地址)。数组名就是数组的首地址,实参向形参传递数组名实际上就是传送数组的地址,形参得到该地址后也指向同一数组。这就好像同一件物品有两个彼此不同的名称一样。同样,指针变量的值也是地址,数组指针变量的值即为数组的首地址,当然也可以作为函数的参数使用。

    归纳起来,如果要把一个实际参数的起始地址传递到另一个函数中,实参和形参的表示形式可以有如下4种情况:

     

    实参形参
    数组名数组名
    数组名指针变量
    指针变量数组名
    指针变量指针变量

     

    设计一个程序将n个数从大到小排序,主函数里的实参为数组名的情况为:

    int main()
    {
    int a[N],i;
    printf("input array a[%d]:\n",N);
    for(i=0;i<N;i++)
    scanf("%d",&a[i]);
    sort(a,N);
    for(i=0;i<N;i++)
    printf("%4d",a[i]);
    printf("\n");
    return 0;
    }

    实参用指针变量的情况为:

    int main()
    {
    int a[N],i,*pa=a;//这句的意思是定义了一个整形数组变量a,和一个变量i和一个指针*pa,*pa =a的意思是指针pa指向了数组a,

                               //也可以说指针pa指向了一个地址(譬如:把整型变量a 的地址赋予p可以有以下两种方式:
                               //(1)指针变量初始化的方法 int a;
                              //                                               int *p=&a;
                               //  (2)赋值语句的方法 int a;
                                //                                              int *p;
                                 //                                              p=&a;),因为这里的a 就是一个地址,它的意思是一个数组名,数组名本身就是代                                 //表数组首元素的首地址,
    printf("input array a[%d]:\n",N);
    for(i=0;i<N;i++)
    scanf("%d",pa++);//这里的pa是数组首元素的首地址,pa++就是首元素的下一个地址即第二个元素的地址,如果再执行pa++,

                                  //就表示指针指向了第二个元素的下一个地址即第三个元素的地址。
    pa=a;
    sort(pa,N);
    for(i=0;i<N;i++)
    printf("%4d",*pa++);
    printf("\n");
    return 0; 
    }

    外部子函数中的形参用数组名的情况为:

    void sort(int x[],int n)
    {
    int i,j,k,t;
    for(i=0;i<n-1;i++)
    {
    k=i;
    for(j=i+1;j<n;j++)
    if(x[k]<x[j])
    k=j;
    if(k!=i)
    {
    t=x[i];
    x[i]=x[k];
    x[k]=t;
    }
    }
    }

    形参用指针变量的情况为:

    void sort(int *p,int n)
    {
    int i,j,k,t;
    for(i=0;i<n-1;i++)
    {
    k=i;
    for(j=i+1;j<n;j++)
    if(*(p+k)<*(p+j))  //接下来就是调换这两个数的前后位置,p是指向数组的首元素的首地址,即第一个元素的地址,

                               //p+k就是指向数组的第k个元素的地址,*(p+k)就是数组第k个元素的值
    k=j;   //将后一个数(指数组中的元素)的序号(指数组元素的下标)赋值给变量K
    if(k!=i)  //这句的意思是判断k的值是不是两次赋值不一样,这句好像是废话。
    {
    t=*(p+i);
    *(p+i)=*(p+k);
    *(p+k)=t;
    }
    }
    }

    将上述2个外部函数和两个主函数任意各选一个组合起来,一共能得到4个不同的函数,4个函数都能实现程序的功能要求(将n个数从大到小排序)。运行结果如下:

    展开全文
  • 形参中的数组指针变量不是数值 #include<stdio.h> //void printf_array(int a[1000],int n) //void printf_array(int a[],int n) void printf_array(int *a,int n) //这三种写法等价 { int i = 0; for ...

    形参中的数组是指针变量不是数值

    
    #include<stdio.h>
    
    //void printf_array(int a[1000],int n)
    //void printf_array(int a[],int n)
    void printf_array(int *a,int n)
    //这三种写法等价
    {
        int i = 0;
        for (i = 0; i<n; i++)
        {
            printf("%d ",*(a+i));
        }
    }
    int main()
    {
        int a[] = {0,22,1,3,4,56,7};
        int n = sizeof(a)/sizeof(a[0]);
        printf_array(a,n);
    }
    

    在这里插入图片描述

    展开全文
  • 数组指针的意思即为通过指针引用数组,p先*结合,说明了p是一个指针变量,指向一个大小为5的数组。所以,int (*p)[5]即为一个数组指针。int *p[5]则是一个大小为5且存放整型指针的数组。 那么也可以理解为数组指针...
  • 数组名指针变量 作 函数参数 实参:数组名形参数组名 数列倒序排放 #include<stdio.h> int main() { void inv(int x[],int n); int i,a[10]={1,2,3,4,5,6,7,8,9,0}; inv(a,10);//实参:数组名 for...
  • C语言数组指针和向数组的指针变量—数组名作函数参数C语言数组指针和指向数组的指针变量—数组名作函数参数数组可以作函数的实参和形参。如:main(){int array[10];…………f(array,10);…………}f(int arr[],int ...
  • //用数组名和指针变量作为形参 //一般选择用指针型变量操作,而不用数组名作为形参。原因在数组名和指针变量的区别一文当中。 //实现所有元素加1 void fun1(int array[],int length) { int i=0; for(;i;i++) { ...
  • 因为,数组名作为参数传递之后,转换为指针。此时,通过sizeof关键字无法获取数组的长度,那么,在操作数据的时候,无法正确判断数组的长度,容易产生数组越界。 程序测试例子如下: 程序运行结果如下: ...
  • 首先是数组名做函数参数的例子。 #include<stdio.h> //数组名做参数,实际上是传递的数组的首地址 void reserve(int x[], int n); void main (){ int a[10] = {3,7,9,11,0,6,7,5,4,2}; int i; for (i = 0; ...
  • 传参时传数组名和普通变量名的区别 case 1: 当参数是数组时,数组名就是这些元素的首地址,其实数组相当于指针,所以相当于你传了一个指针!参数数组变化,也即原数组发生变化。 case 2: 而传一个普通的变量时,也即...
  • 实参和形参的四种结合方式 实参 形参 实例 数组名 数组名 1.1 数组名 指针变量 1.2 指针变量 数组名 1.3 指针变量 指针变量 1.4 本文以输入10个整数,然后对其进行排序,然后输出的程序为例: 形参数组名,...
  • 数组名指针变量的区别

    千次阅读 2010-06-03 16:24:00
    转载自:http://hi.baidu.com/thl53/blog/item/d6184010d36b7118b8127bc7.html 指针是C/C++语言的特色,而数组名指针有太多的相似,甚至很多时候,数组名可以作为指针使用。于是乎,很多程序设计者就被搞糊涂了。...
  • C语言数组指针指向数组的指针变量—数组名作函数参数C语言数组指针和指向数组的指针变量—数组名作函数参数数组可以作函数的实参和形参。如:main(){int array[10];…………f(array,10);…………}f(int arr[],int ...
  • 文章目录指针数组数组首元素数组的地址、空间大小数组指针和数组相同点使用上作为函数形参上不同点二维数组数组指针二维数组和数组指针相同点不同点一维数组和数组指针指针数组指针数组和数组指针二级指针总结 ...
  • 数组名和指针作为形参

    千次阅读 2014-09-15 15:43:04
    1.用数组名做函数参数 f(int arr[],int n)① 调用时采用:f(arr,10) 由于数组名代表的是数组的地址,所以用数组名做参数...在用指针变量形参以接受实参数组传递的地址时,有两种方法: ①采用一维数组相同的
  • 一、字符数组形参 有时候我们需要通过调用一个函数实现对一个传入的数组进行赋值,从而改变其值。当字符数组本质是上也是指针。 void change(char p[]) { strcpy(p, "efgh"); //p[0] = 'e'; //p[1] = 'r';...
  • 数组元素做实参时,向形参变量传递的是数组元素的值,而用数组名做函数实参时,向形参数组名指针变量)传递的是数组首元素的地址。 用数组名作函数参数,应该在主调函数被调用函数分别定义数组。 用数组...
  • 数组名指针、取地址 首先给出一个测试程序: int a[]={2,3,4,5}; cout<<"addr a "<<a<<endl;//数组名是一个常量,无法对其进行赋值操作;而指针是一个变量,可以修改指针指向的内存 cout<<...
  • 数组指针作为形参传递

    千次阅读 2019-04-17 00:02:59
    数组作为函数形参时,数组的地址可以用做函数调用的实参。 可以通过数组地址的传递,在函数内可以对该数组进行访问修改。 eg: #include <stdio.h> #define SIZE 10 /* 形式1 */ void func_1(const char ...
  • C++指针变量作函数参数接收数组地址 在C++中,用指针变量指向数组元素时要注意: 指针变量p可以指向有效的数组元素,实际上也可以指向数组 以后的内存单元。 int arrya[10];//指针变量p的初值为&array[0] *p=...
  • 形参中的数组,不是数组,是指针(对应数据首元素地址,用sizeof获取的是指针大小,而不是数组大小) 形参数组:int a[100], int[a], int *a 对编译器而言是一样的,都当做int *处理 */ void f(int a[100]){ cout...
  • 变量的内存地址与指针指针变量指针变量的赋值指针变量运算符及运算指针变量运算指针变量作为函数参数由数据变量改为指针变量指针变量传地址改为数据变量传数据数组与地址指针数组名作函数参数指向数组指针变量作...
  • 1.一维数组名作为函数参数传递一位数组名,就相当于该数组的首个元素的地址; 代码如下:int a[10];int *p;p=a;//p=a与p=&a[0]是等价的实例代码: 代码如下:#include<iostream>using namespace std;int main(){ int ...
  • #include #include #define MAXSIZE 10//数组名与一般指针变量的区别//数组名作为形参,(该数组名仅仅是一个普通的指针变量,不具有常量特性(可自增,自减),也不代表一个数据类型。),但是不影响实参,形参不改变实参...
  • 二维数组名 函数原型为 void PrintAr2(int arry[][3], int row); 第一个参数表示传递的二维数组指针,并规定了其列的数量,第二个参数规定了二维数组行的数量 void PrintAr2(int arry[][3], int row) { for (int...
  • C语言中数组指针和指针数组的区别
  • 字符串char a[]="abc";printf("%s",a);fgets(a,100, stdin) //安全的字符串输入函数printf("%s",a);scanf("%*[^\n]"); //两个scanf清空输入缓存scanf...int 值作为实参 指针作为形参void xchange1(int *n1,int *n2) ...
  • 数组名是不是指针

    千次阅读 多人点赞 2015-04-09 20:08:02
     指针是C/C++语言的特色,而数组名指针有太多的相似,甚至很多时候,数组名可以作为指针使用。于是乎,很多程序设计者就被搞糊涂了。而许多的大学老师,他们在C语言的教学过程中也错误得给学生讲解:"数组名就是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 68,825
精华内容 27,530
关键字:

形参数组名和指针变量

友情链接: 74hc-series-chip-.rar