一 数组的结构:顺序存储,看谭浩强中的图,牢记

1、数组名指代一种数据结构:数组
  现在可以解释为什么第1个程序第6行的输出为10的问题,根据结论1,数组名str的内涵为一种数据结构,即一个长度为10的char型数组,所以sizeof(str)的结果为这个数据结构占据的内存大小:10字节。
  再看:

. int intArray[];
. cout << sizeof(intArray) ;

  第2行的输出结果为40(整型数组占据的内存空间大小)。

  如果C/C++程序可以这样写:

. int[] intArray;
. cout << sizeof(intArray) ;

  我们就都明白了,intArray定义为int[10]这种数据结构的一个实例,可惜啊,C/C++目前并不支持这种定义方式。

  2、数组名可作为指针常量

  根据结论2,数组名可以转换为指向其指代实体的指针,所以程序1中的第5行数组名直接赋值给指针,程序2第7行直接将数组名作为指针形参都可成立。
  下面的程序成立吗?

. int intArray[];
. intArray++;

  读者可以编译之,发现编译出错。原因在于,虽然数组名可以转换为指向其指代实体的指针,但是它只能被看作一个指针常量,不能被修改。

  而指针,不管是指向结构体、数组还是基本数据类型的指针,都不包含原始数据结构的内涵,在WIN32平台下,sizeof操作的结果都是4。
顺便纠正一下许多程序员的另一个误解。许多程序员以为sizeof是一个函数,而实际上,它是一个操作符,不过其使用方式看起来的确太像一个函数了。语句sizeof(int)就可以说明sizeof的确不是一个函数,因为函数接纳形参(一个变量),世界上没有一个C/C++函数接纳一个数据类型(如int)为"形参"。

  3、数据名可能失去其数据结构内涵

  到这里似乎数组名魔幻问题已经宣告圆满解决,但是平静的湖面上却再次掀起波浪。请看下面一段程序:

. #include
. void arrayTest(char str[])
. {
.  cout << sizeof(str) << endl;
. }
. int main(int argc, char* argv[])
. {
.  char str1[] = "I Love U";
.  arrayTest(str1);
.  return ;
. }

  程序的输出结果为4。不可能吧?

  一个可怕的数字,前面已经提到其为指针的长度!

  结论1指出,数据名内涵为数组这种数据结构,在arrayTest函数体内,str是数组名,那为什么sizeof的结果却是指针的长度?这是因为:

  (1)数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;

  (2)很遗憾,在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。

  所以,数据名作为函数形参时,其全面沦落为一个普通指针!它的贵族身份被剥夺,成了一个地地道道的只拥有4个字节的平民。

  以上就是结论4。

以上转载自:http://blog.chinaunix.net/uid-21765995-id-1815661.html

二 二维数组

1 指针数组:元素都是指针的数组,本质是数组  *p[m][n]

例子:

int i,j;
int x[][]={{,,},{,,}};
int *p[]={x[],x[]};//声明一个含有2个元素的一维int指针数组p for(i=;i<;i++)
{
for(j=;j<;j++)
{
cout<<*(p[i]+j)<<endl;
}
}

输出语句为cout<<p[i][j]<<endl;也是可以的。

int i,j;
int x[][]={{,,},{,,}};
int *p=x[]; //x[0]不等价于x,经过程序已经验证。重要x与x[0]的区别,x是二级指针,x[0]一级指针
for(;p<x[]+;p++)
{
printf("%d\t",*p);
}

对比2中的例子,此时p加1是指向下一个元素,2中的例子p加1指向下一行元素的首地址。

2 数组指针:指向数组的指针 本质是数组 (*P)[m],指向还有m个元素的一维数组,p的增量以数组为单位

int i,j;
int x[][]={{,,},{,,}};
int (*p)[]=x;//声明一个指向具有3个元素的int型数组的指针p
//圆括号不可省略 for(i=;i<;i++)
{
for(j=;j<;j++)
{
cout<<p[i][j]<<endl; //或者cout<<*(*(p+i)+j)<<endl;
}
}

以上两种形式都紧扣数组在内存中存储的结构。指针数组比较好理解。数组指针没有理解呀,记住。。。。。。吼!!!

总的来说:二维数组中x代表行地址,x[0]代表元素地址。把握这个原则。

*p[]={x[],x[]};//*(p[0]+i)  return p;

*p=x[];//*(p+i)    return p;

(*p)[]=x;//*(*(p+i)+j)    return p[0];

还是有点乱。。不断修改中。

三 数组的传参问题

经测试:

int a[];
function(int *a) 传参形式为 function(a)
funcition(int a[]) 传参形式为function(a) int a[][]
function(int a[][])传参形式为function(a)
function(int **a)传参形式为function(a) //二维指针的经测试打印错误

二维数组的传参问题:

转载自:http://blog.csdn.net/liuzhanchen1987/article/details/7712640

第一种方式是直接传递二维数组,但是必须标明第二维的值,因为如果只是传递a[][],编译器无法分配这样的数组,所以要这样传int a[][3]

第二种方法是传递指针数组方式,即int (*a)[3]
第三种是传递指针方法。

具体实施见代码:

//二维数组传参问题示例
#include<iostream>
using namespace std;
//方法1:传递数组,注意第二维必须标明
void fun1(int arr[][],int iRows)
{
for(int i=;i<iRows;i++)
{
for(int j=;j<;j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
//方法二:一重指针
void fun2(int (*arr)[],int iRows)
{ for(int i=;i<iRows;i++)
{
for(int j=;j<;j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
//方法三:指针传递,不管是几维数组都把他看成是指针,
void fun3(int*arr,int iRows,int iCols)
{
for(int i=;i<iRows;i++)
{
for(int j=;j<;j++)
{
cout<<*(arr+i*iRows+j)<<" ";
}
cout<<endl;
}
cout<<endl;
}
int main()
{
int a[][]={{,,},{,,}};
fun1(a,);
cout<<endl;
fun2(a,);
cout<<endl;
//此处必须进行强制类型转换,因为a是二维数组,而需要传入的是指针
//所以必须强制转换成指针,如果a是一维数组则不必进行强制类型转换
//为什么一维数组不用强制转换而二维数组必须转换,此问题还没解决,期待大牛!
fun3((int*)a,,);
cout<<endl;
}

方法四:

int sum(int *a)
{
int i,j;
int he=;
for(i=;i<;i++)
{
for(j=;j<;j++)
{cout<< *(a+j+i)<<"**"<<endl;
cout<<i+j<<endl;}
} return he;
} int main()
{
int i,j; int a[][];
int b[]={,,}; for(i=;i<;i++)
{
for(j=;j<;j++)
a[j][i]=i+j;
} cout<<sum(a[])<<endl;
return ;
}

 四 二维数组动态分配内存

方式一:

int (*p)[];
p=new int[][];
或者
int (*p)[]=new int[][];

方式二:

int **p;
int i;
p=new int*[3];
for(i=;i<;i++)
p[i]=new int[];

 

c指针与数组,传参问题,指针数组与数组指针的区别,二维数组动态内存分配的更多相关文章

  1. php将一个二维数组按照某个字段值合并成一维数组,如果有重复则将重复的合并成二维数组

    版权声明:本文为博主原创文章,未经博主允许不得转载. 最近工作中碰到一个问题,用PHP将一个二维数组按照二维数组中的各个项中的某个特定字段值合并成一维数组,如果有重复则将重复的合并成二维数组,生成的二 ...

  2. 存在一个足够大的二维数组,每个数组中的值都是整数,使用javascript如何实现按每个数组中的平均值,从大到小排序这个二维数组?

    这是牛客网上的一道题~ 题意:对数组排序,顺序是按照数组的平均值,即按照一个元素和平均值相减的绝对值的大小来排序...本例按这个绝对值递增排序 解题思想:先求出这个数组的平均值,如果 a<b,那 ...

  3. (一)二维数组&&指针数组与数组指针

    一.首先我们从字面意思理解一下什么是指针数组什么是数组指针 1.指针数组:本质是一个数组,数组中的每一个元素是一个指针. 2.数组指针:本质是一个指针,而指针指向一个数组. 二.我们该怎么区分指针数组 ...

  4. C语言 二维数组(指针)动态分配和释放(转)

    C 二维数组(指针)动态分配和释放 先明确下概念: 所谓32位处理器就是一次只能处理32位,也就是4个字节的数据,而64位处理器一次就能处理64位,即8个字节的数据.如果我们将总长128位的指令分别按 ...

  5. php 二维数组传递给 js 问题解决记录

    需求: php从数据库中读取到二维数组.传递到js中 实现步骤: php:json_encode  →   json  →  js:eval 即在php中使用json_encode()将php的二维数 ...

  6. C语言学习笔记 (005) - 二维数组作为函数参数传递剖析

    前言 很多文章不外乎告诉你下面这几种标准的形式,你如果按照它们来用,准没错: //对于一个2行13列int元素的二维数组 //函数f的形参形式 f(int daytab[2][13]) {...} / ...

  7. C语言中将二维数组作为函数参数来传递

    c语言中经常需要通过函数传递二维数组,有三种方法可以实现,如下: 方法一, 形参给出第二维的长度. 例如: #include <stdio.h> void func(int n, char ...

  8. C语言传递二维数组

    方法一, 形参给出第二维的长度. 例如: #include <stdio.h> ] ) { int i; ; i < n; i++) printf("/nstr[%d] = ...

  9. c 二维数组动态分配和释放

    c动态语言 函数声明的头文件在<stdlib.h>里 使用malloc函数为字符串分配内存 -->记得释放内存 free() #include <stdio.h> #in ...

  10. C++二维数组的动态声明

    int **a  =  new int* [m]   //分配一个指针数组,将其首地址保存在a中   . for(int i = 0; i < m; i++)   //为指针数组的每个元素分配一 ...

随机推荐

  1. [HDU 4549] M斐波那契数列

    M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Sub ...

  2. [POJ 1155] TELE

    TELE Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3787   Accepted: 2007 Description ...

  3. (转载)SQL Server 2005 日志文件过大处理

    由于安装的时候没有计划好空间,默认装在系统盘,而且又没有做自动备份.截断事务日志等,很快LDF文件就达到十几G,或者几十G ,此时就不得不处理了. 备份和计划就不说了,现在就说下怎么把它先删除吧: 1 ...

  4. Java之 AtomicInteger

    AtomicInteger,一个提供原子操作的Integer的类.在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字.而AtomicIn ...

  5. HTTP分段下载

    现代WEB服务器都支持大文件分段下载,加快下载速度,判断WEB服务器是否支持分段下载通过返回头是否有 Accept-Ranges: bytes 字段.分段下载分为两种,一种就是一次请求一个分段,一种就 ...

  6. HDU-3706 Second My Problem First

    http://acm.hdu.edu.cn/showproblem.php?pid=3706 Second My Problem First Time Limit: 12000/4000 MS (Ja ...

  7. chm 字体修改

    今天打开从网络下载的“[MSDN]Csharp编程指南+参考手册.chm”文件,以为看看里面所提供的一些知识点,但是发现文件显示的字体觉得有点别扭,以为能够像网页那样ctrl键+鼠标滚轮就能进行字体的 ...

  8. makefile 中 $@ $^ %< 使用

    这篇文章介绍在LINUX下进行C语言编程所需要的基础知识.在这篇文章当中,我们将会学到以下内容: 源程序编译 Makefile的编写 程序库的链接 程序的调试 头文件和系统求助 1.源程序的编译 在L ...

  9. POJ 1904 King's Quest 强联通分量+输入输出外挂

    题意:国王有n个儿子,现在这n个儿子要在n个女孩里选择自己喜欢的,有的儿子可能喜欢多个,最后国王的向导给出他一个匹配.匹配有n个数,代表某个儿子和哪个女孩可以结婚.已知这些条件,要你找出每个儿子可以和 ...

  10. Spark在集群中的安装

    今天由于所以要安装spark做一些实验.我已有的环境是: 操作系统:CentOS6.5 hadoop:hadoop2.4.1 JDK:1.7 集群环境:四个节点   闲话不说,以下是我的安装步骤: 说 ...