C语言数组与指针

一维数组与指针

int a[10];
int *pa;

一维数组的数组名代表的就是该数组第一个元素的地址,所以复制语句pa=&a[0]等价于pa=a。对数组元素a[i]的引用等价于*(a+i)。在计算数组元素a[i]的值时,C语言实际上先将*(a+1)后再进行求值,所以用指针编写的程序比用数组下标编写的程序执行速度快。

数组名和指针之间有一个不同之处,指针是一个变量,pa=a和pa++都是合法的。但数组名不是变量,因此,类似于a=pa和a++形式的语句是非法的。

当把数组名传递给一个函数时,实际传递的是该数组第一个元素的地址。在被调用函数中,该参数是一个局部变量,因此,数组名参数必须是一个指针。

在函数定义中,形式参数char s[]和char *s是等价的。通常使用后一种形式,因为它比前者更直观地表明了该参数是一个指针。

字符数组和字符指针

char a[] = "Hello";
char *p = "Hello";

a是一个仅仅足以存放初始化字符串以及空字符’\0’的一维数组。数组中的单个字符可以进行修改,但a始终指向同一个存储位置。

p是一个指针,其初值指向一个字符串常量,之后它可以被修改以指向其他地址,但是不能修改字符串的内容。

char *p = “Hello”,”Hello”保存在静态数据区,该数据不能修改。由指针m指向,不能通过指针m来修改静态数据区的值。

char a[] = “Hello”,”Hello”保存在栈空间数组里。 数组名为a, 变量名为数组的首地址。可以通过a[i]=’a’或*(a+i)=’a’的形式来修改数组内容。

指针与多维数组

比较两个定义

int a[10][20];
int *b[10];

从语法角度讲,a[3][4]和b[3][4]都是对int对象的合法引用。但a是一个真正的二维数组,它分配了200个int类型长度的存储空间,并且通过常规的矩阵下标计算公式20*row+col计算得到元算a[row][col]的位置。

但是对b来说,该定义仅仅分配了10个指针,并且没有对它们初始化。假定b的每个元素都指向一个具有20个元素的数组,那么编译器就要为它分配200个int类型长度的存储空间以及10个指针的存储空间。

指针数组的优点

数组的每一行长度可以不同,b的每个元素不一定都指向一个具有20个元素的数组。

二维数组和二维指针

二维数组和二维指针的概念很容易混淆,请看下面这段代码。

#include <stdio.h>

void print_str(char** strs, int i)
{
    printf("strs[%d]=%s", i, strs[i]);
}

int main(int argc, char **argv)
{
    char strs[10][100] = {"Hello", "World"};
    print_str(strs, 0);

    return 0;
}

执行这段程序,会得出现Segmentation Fault。

Segmentation Fault是由于程序试图访问不该访问的内存,详细介绍见Wikipedia

https://en.wikipedia.org/wiki/Segmentation_fault

变量strs实际为一个类型为char (*)[100]的指针,指向二维数组的第一个元素,即一个包含100个char的数组,指针的值实际上也等于二位数组第一个char元素的地址。print_str函数的参数声明为char**,即二级指针,参数传递不会改变指针的值。所以strs的值跟main中定义的strs的值是一样的,不过print_str中的strs是二级指针。那么str[0]则是一级指针,strs[0]=*(strs+0),那么strs[0]的值为字符串“Hell”所占四个字节的值对应的地址,“Hell”对应的ASCII码为0x48 0x65 0x6C 0x6C, 组成的地址为0x6C6C6548(little endian),而此处内存禁止访问,所以出现了Segmentation Fualt。

时间: 2024-10-10 01:52:07

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

c语言数组与指针详解(上)

彻底搞懂c语言数组与指针 部分引用 c语言指针怎么理解 知乎 程序设计入门----c语言 (浙江大学翁恺) <c primer plus>第六版 基础知识 1. 指针基础 &:代表对变量取地址 int*或char*或者把这个星号紧贴着变量比如int *a = &b: 代表新建一个用来储存地址的变量,这也代表&b这个值的类型是int*. int *a, b 或 int* a, b 中只有a是int指针类型,b是int整型. 关于电脑大小端的讨论:大端是指是指数据的高字节,

(C语言)数组与指针的区别

以前常常听过这种说法,说数组和指针这两者比较像,但是不能混淆,可是一直没能理解.刚刚在李云的<专业嵌入式软件开发>中,看了讲述数组与指针区别的一章,似乎有所领悟.本着知乎上看到的这张图,我试着将自己的理解写一些. 首先需要了解数组和指针的工作模式. 数组: char name[] = {'T', 'o', 'n', 'y', '\0'}; 此时,这个数组的地址是这样的.其中name指向数组的开头: 指针: char name[] = {'T', 'o', 'n', 'y', '\0'}; ch

C语言关于数组与指针内容小结

数组的基本概念 什么是数组:数组就是:数组是相同类型的元素的一个集合       类型说明符 数组名 [常量表达式]: 其中,类型说明符是任一种基本数据类型或构造数据类型.数组名是用户定义的数组标识符.方括号中的常量表达式表示数据元素的个数,也称为数组的长度.例如: int a[10]; /* 说明整型数组a,有10个元素 */ float b[10], c[20]; /* 说明实型数组b,有10个元素,实型数组c,有20个元素 */ char ch[20]; /* 说明字符数组ch,有20个元

C语言中的指针与数组的关联1

在C语言中,指针是一种类型,存放的是地址,例如char*p,这里p存放的是字符型数据的地址,int*p,p存放的是整形数据的地址,我们可以通过解运用*来获取该地址所指向的内容.而数组则是一种数据类型的集合,如int arr[]={1,2,3,4,5,6,7,8,9,10};这里声明与定义了一个整形数组,而char arr[]="hello world";则是声明与定义了一个字符类型的数组,这个数组内存放的是一个字符串. C语言规定,在大多数情况下数组名其实质就是数组元素的首地址,所以我

C语言中数组与指针

数组是内存空间的一片连续的区域,用于存贮一组相同数据类型元素的集合. 指针变量中存放的是变量的地址,通过指针取得地址,再通过地址提取数据. 在大多是C语言书中,都有这样的说法,“数组和指针是相同的”.其实,数组与指针,只能在特定的情况下才是相同的,在大多书情况下,他们并不相同. C语言中每个表示变量的符号都代表一个地址,而每个变量的值就是该地址里所存储的内容. 定义一个字符数组 char a[]="asdfghjkl";现在来访问第i个字符a[i],编译器符号表中具有一个符号,它代表的

C语言之数组与指针(一)

---恢复内容开始--- 数组:内存连续的,同类型元素的集合: 从最基础的数组声明,数组初始化,数组赋值,数组遍历,到二维数组,再到指针数组,数组指针,以及数组和指针关系无疑都证明了数组在c语言中的重要地位:我们将一 一对其说明. 1.数组声明:float a[size] ; int b[size]; char c[size];(size是数组元素个数,必须为正整数 : #define  size 10   ) 这样我们就声明了一个数组:但是在下面代码中我们可以看出了一个问题:没有初始化的数组中

读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组

原文链接:C语言结构体里的成员数组和指针 复制如下: 单看这文章的标题,你可能会觉得好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Laruence同学出了一个关于C语言的题,微博链接.微博截图如下.我觉得好多人对这段代码的理解还不够深入,所以写下了这篇文章. 为了方便你把代码copy过去编译和调试,我把代码列在下面: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <stdio.h>

程序猿之--C语言细节13(二维数组和指针,&amp;*a[i][0]的理解,数组1[e]和e[1]很可能你没见过)

主要内容:二维数组和指针,&*a[i][0]的理解.数组1[e]和e[1] #include <stdio.h> #define NUM_ROWS 10 #define NUM_COLS 10 int main(int argc, char **argv) {     int a[NUM_ROWS][NUM_COLS], *p, i = 0; // a理解为指向整数指针的指针 即int **     int c, d=2,*test, e[2] = {4,5},f[2][2] = {{

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

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