C语言数组与指针的问题

最近学数据结构,在学数组与指针之间的关系的时候,发现以前一直没理解的一个问题。

首先我们看看数组与指针的一些关系吧。如果我们定义一个数组int a[ ] = {1,1,2,3,5,8,},再把一个指针int *p = a;这句话我们该怎么理解呢?其实很简单,我们只要知道这个语句是定义了一个指向整型数组的指针变量p,并且p指向数组的首地址,后面的就迎刃而解了。而a代表的是数组的第一个元素的地址,我们假设是内存的1000H,那么p指向的就是1000H这个内存地址,那么(a+1)在内存中是什么值呢?是1001H吗?当然并不是这样的,而是1004H,因为我们知道int型变量在内存中占4个字节,那么(a+i)实际指的是a的地址加上i*sizeof(int),所以(a+1)内存中的地址时1004H。

我们知道(a+i)代表第i个元素的地址,同样的道理(p+i)代表的也就是数组第i个元素的地址,*(p+i)就代表数组第i个元素a[i],当然有的书上把*(p+i)写成p[i],另外我们还要知道数组的长度怎么计算,声明的时候我们并没指定数组的长度,但是初始化的时候我们给出了数组的元素,我们可以通过计算得出元素的个数,这里和字符串数组又有些区别,一会我们再看字符串数组的长度怎么计算。有了这些基础知识,我们来具体看一个程序,输出一个数组的所有元素,用函数实现。

#include <stdio.h>

void Show_Array(int * p,int len)
{
	int i = 0;
	for(i=0;i<len;i++)

		printf("%d\n",*(p+i));//*(p+i)=>p[i]=>a[i]
}

int main(void)
{
	int a[5] = {1,2,3,4,5};

	//int *p = a;
	Show_Array(a,5); //a是数组首地址,5是数组长度。<span style="white-space:pre">	</span>

	return 0;
}
输出结果是:

1

2

3

4

5

因此我们得出一个结论,一旦我们要输出一个数组中的元素,我们只要知道数组首地址和数组的长度就够了。

我们在来讨论字符串数组与指针的关系。首先我们知道字符串在内存中是以'\0'作为结束的标识符的。因此我们看看下面几种字符串数组声明,长度计算有什么规则。

1.char a[] = {'a', 'b', 'c'};结果是:声明了一个字符数组,长度为3不会自动添加'\0'。

2.char a[] = "abc";结果是:用字符串去初始化a,要知道,C语言将字符串当做字符数组来处理,所以"abc"本身是有结束字符'\0'的,所以字符数数组长度为4,因为要加上结束字符'\0'。

3.char a[5] = {'a', 'b', 'c'};属于使用“不完全初始化列表”来初始化 a,因为只给出了三个初始化字符,而数组长度为5,最后两个字符自动赋值为0,也就是'\0'。

4.char a[5] = "abc";和上面一个样,长度为5,字符数组(或称为字符串)"abc"将字符数组p的前4个元素赋值,(之所以是4个,因为"abc"本身是包括最后的'\0',会赋值给a),然后最后一个自动赋值为0,也就是'\0'。

5.char  a[5] ="abcde";这样声明一个数组在C语言中存在一个异常即数组越界,但是编译器并不报错,但是我们观察输出的结果是abcde烫烫烫这样的乱码。因为abcde加上'\0'总共6个字符,而数组长度只有5,就超过长度了,计算机处理方式以乱码处理。

那么我们怎么输出一个字符串数组呢?我们用程序来说明吧

#include <stdio.h>

void Show_String(char * p)
{
	printf("%s\n",p);
	while(*p != '\0')
	{
		//printf("%s\n",p);
		p++;
		printf("%s\n",p);
	}

}
int main(void)
{
	char ch[6] = "12345";

	printf("%s\n",ch);	//%s 输出格式,用于字符串,要求给 字符串的首地址
	Show_String(ch);
	return 0;
}
输出结果为:

12345
12345
2345
345
45
5

在C语言中%s 输出格式,用于字符串,要求给 字符串的首地址。为什么输出结果是上面的结果呢?
printf("%s\n",ch);在主函数中就输出一次12345
在子函数Show_String()中又输出一次,后面判断有没有到字符串结束标识符,没有到,p自增1,即指向下一个内存地址,因此后面输出的字符都比前面要少一个。所以输出上述结果。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

king110108

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值