C语言中的数组与指针

1、 数组的初始化

数组的初始化方法有很多,常用的方法有

定义时初始化 int arr[3]={1,2,3}; 或 int arr[3]={2}; //未初始化的元素全为0;

定义后遍历赋值初始化

         int arr[3];
         for(int i=0;i<3;i++)
            arr[i]=i;

  C99之后,出现了另一种十分方便的初始化方式。即利用元素位置来初始化该元素,使用方法如下 int arr[5]={[3]=1,3}

初始化后的结果 arr[5]={0,0,0,1,3}

此种方式的缺点是,后面的初始化后覆盖前面的初始化,即同一个初始化语句,最终的结果决定于靠后的语句。例如 arr[5]={1,2,3,4,[3]=0); 最后的结果是  arr[5]={1,2,3,0,0}

2、数组作为函数参数

数组作为函数参数的用法,是将数组名作为参数传递。因为数组名是数组的首元素的地址,所以这种方式传递的实际上是指向数组首字母的指针。此时,使用指针和数组名作为参数功能等价。

在函数的声明部分,以下四种声明方式等价:

1 int fun(int []);
2 int fun(int arr[]);
3 int fun(int *);
4 int fun(int *arr);

而在函数定义部分,由于不能省略参数,所以,上面的2,4两种方式等价。

因为数组作为函数参数传递的是指针,所以在函数中对数组做改变会影响到原数组的值,为避免这种情况(即在我们不希望函数对数组的值进行改变的时候),我们可以采用下面的函数定义方式

int fun(const int arr[]);

  用这种方是定义的函数会把指针定义为指向常量的指针,任何在函数内部试图对原数组的至进行改变的操作都会被编译器阻止。

3、其他一些指针小知识

指向常量的指针在上面的函数参数部分已经谈到了,即 const int *p; 定义了一个指向常量的指针,用这种方式定义的指针可以指向常量和普通变量,且不会改变指向对象的值。(普通指针不能指向常量 )

指针复制给指针时,有一点需要注意,虽然将普通指针赋值给常量指针是允许的,但这有一个前提,即只能进行一层间接运算,下面演示了如果允许两层间接运算带来的危险。

1 const int n=1;
2 int *p1;
3 const int * p2;
4 const int **p3;
5 p1=p2;                //非法,将const指针赋值给普通指针
6 p2=p1;                //合法,将普通指针赋值给const指针
7 p3=&p1;              //非法,将const指针赋值给普通指针,如果假设允许,看下会发生什么
8 *p3=&n;              //合法,const指针指向const,但p1指向n,即普通指针指向const值
9 *p1=3;                //合法,p1为普通指针,可以改变指向的变量值,后果是常量n的值改变

声明指向3个int值的指针的方法: int (*p)[3]; (*的运算优先级低于[],所以如果不加()会声明为指针数组。)这时p相当于于 int arr[2][3]; 中的arr、&arr[1],指向了三个int型变量组成的数组。

时间: 2024-12-07 16:00:06

C语言中的数组与指针的相关文章

【示例】C语言中利用数组存放函数指针

C语言中利用数组存放函数指针,增加函数使用的灵活性.使用时只需提供数组索引,即可调用不同函数. 预备知识: 1.指向函数的指针 一个函数在编译时被分配一个入口地址,这个地址就被称为函数的指针. 例如: int max(int,int); // 声明函数,比较两数大小 int (*p)(); //声明指向函数的指针变量 p=max; //将函数max的入口地址赋给指针变量p int c=(*p)(a,b); //调用函数 2.函数指针作为函数参数 该例子中每次给process函数不同实参(函数名)

C语言中字符数组和字符串指针分析

这几天搞Unix上的C程序,里面用到了很多字符数组和字符串指针,我记得在学完C语言后相当一段时间里,对指针这个东西还是模模糊糊,后来工作也没怎么 用到过C,虽然网上这类的文章也有很多,还是决定自己在这做个小总结,也算加深下自己的印象,写了下面的测试程序: #include <stdio.h> int main(int argc, char *argv[]){ char day[15] = "abcdefghijklmn";  char* strTmp = "opq

C语言 二维数组与指针笔记

今天分析了C语言二维数组和指针的基本理解,感觉有点懵...代码记录一下,如果有大神临幸发现哪里有误,欢迎指正~~~ #include <stdio.h> #include <stdlib.h> #include <string.h> //void func(int p[][]) //这样写等同于void func(int **p) p++移动了四个字节,(*p)++移动了四个字节,不符合二维数组规律 //{ //} //列优先输出的函数(即竖着输出) void func

C语言中的sizeof中的数组和指针

1.引子 今日在看动态规划的0-1背包问题,看完后还是打算自己写着试试,毕竟实践才能出真知嘛.动态规划的结果是个二维数组dp,我copy书上的例子进行初始 memset(dp,0,sizeof(dp)),考虑到程序的健壮性,对于数组我都是用的动态申请,自然二维数组也不例外[动态二维数组的建立可参见本blog的延伸]. 程序写完后,但是却不能运行,开始单步调试,当进行到dp的赋值时老是报指针的错误!!!开始我以为是指针越界什么的,仔细才发现dp的数组维数确实要多申请一个用来存放初始情况的值(全是0

c语言中的数组名代表的意义

数组名是数组的首地址,就是数组中的第一个元素的地址,是常量.常量是不能值在=的左边的.数组和指针的区别在于,指针是变量,是用来存储指向数据的地址的变量,而数组名是常量.一般情况下申明一个数组,比如char  a[10]; 之后  数组名a都是数组的首地址,是一个地址常量.但是在函数申明的形参列表中除外,比如: int  fo(char []); 在这种情况下的申明与 int  fo(char a[]); int  fo(char *a); 是等价的,就是说在这种情况下,就算你写的是数组的形式,编

C语言学习_数组与指针2

数组其实是一种变相的指针,数组名同时也是指针,eg: CODE == &CODE[0]; 数组的加法: #include<stdio.h> #define SIZE 4 int main(void) { shortdates[SIZE]; short* pti; shortindex; doublebills[SIZE]; double* ptf; pti= dates;//把数组地址付给指针 ptf= bills; printf("%23s  %10s\n", &

C语言之不规则数组和指针

不规则数组是每一行的列数不一样的二维数组. 在了解不规则数组之前,先了解一下用复合字面量创建的二维数组.复合字面量是一种C构造,前面看起来像是类型转换操作,后面跟的是花括号括起来的初始化列表. (const int) {100} (int[3]) {1,2,3} 下面的声明把数组声明为整数指针的数组,然后用复合字面量语句块进行初始化,由此创建了数组arr. int (*(arr[])) = { (int[]) {0,1,2}, (int[]) {3,4,5}, (int[]) {6,7,8}};

《C语言中动态数组的创建及引用》

C语言中动态数组的创建及引用 动态数组是相对于静态数组而言的,静态数组的长度是预定义好的,在整个程序中,一旦给定了数组大小后就无法改变,,而动态数组则不然,它可以根据程序需要重新指定数组的大小.动态数组的内存空间是由堆动态分配的,通过执行代码为其分配储存空间,只有程序执行到分配语句时,才为其分配储存空间. 对于动态数组,其创建比静态数组更麻烦一些,使用完必须由程序员自己释放,否则将引起内存泄漏,但是其使用非常灵活,能根据程序需要动态分配大小,因此相对于静态数组来说,使用动态数组的自由度更大. 对

Java语言中的----数组

day07  Java语言中的--数组 一.数组的概述: 什么是数组?数组是干什么用的?为啥要学数组?这些都是疑问.再你学完数组以后就知道了,数组是存储在相邻内存位置的单一数据类型的元素集合.什么是单一数据类型?就是在你定义数组的时候的数据类型,就只能存储这一个类型的数组.那么我们访问他的时候就直接通过指定数组的名字和下标就可以直接访问数组元素了. 二.数组: 1.定义数组         数据类型 数组名[] = new  数据类型[内存数据大小]         int a[] = new