C语言指针笔记2

一.字符指针

在C语言中,字符串数组可以用字符数组表示
字符串是以\0即空字符结尾的字符数组

const char* pstr = "hello bit.";
  1. 提问

这里是把一个字符串放到pstr指针变量里了吗?
nonono
其实是将字符串 hello bit. 的首字符h的地址放到了pstr中。

  1. char*str="hello"char str[ ]="hello"有什么区别?
    可修改性:

char*str="hello"中,str指向的是只读内存区域,所以不能修改字符内容。 如,将str[0]=‘l’;可能会导致程序崩溃

sizeof操作符的结果

对char*str="hello"使用sizeof(str)将返回指针大小,通常为4或8位字节
对char str[ ]="hello"使用sizeof(str)将返回字符数组大小,即6个字节

3.思考以下代码输出结果

#include <stdio.h>
int main()
{
    char str1[] = "hello ";
    char str2[] = "hello ";
    const char *str3 = "hello ";
    const char *str4 = "hello ";
    if(str1 ==str2)
 printf("str1 and str2 are same\n");
    else
 printf("str1 and str2 are not same\n");
       
    if(str3 ==str4)
 printf("str3 and str4 are same\n");
    else
 printf("str3 and str4 are not same\n");
       
    return 0;
	}

结果为
str1 and str2 are not same
str3 and str4 are same

这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域,当
几个指针。指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化
不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4不同。

二 数组名与&数组名

数组名表示数组首元素的地址,那&数组名表示什么?

#include<stdio.h>
int main(){
	int ptsr[6]={0};
	printf("%p\n", ptsr);
    printf("%p\n", &ptsr);
    return 0;

} 

结果在这里插入图片描述
可以看到ptsr与&ptsr输出结果一样,难道数组名与&数组名是相同的?

#include<stdio.h>
int main(){
	int ptsr[6]={0};
	printf("%p\n", ptsr);
   printf("%p\n", ptsr+1);
   
    printf("%p\n", &ptsr);
    printf("%p\n", &ptsr+1);
    return 0;

} 

结果在这里插入图片描述

根据上面的代码我们发现,其实&ptsr和ptsr,虽然值是一样的,但是意义应该不一样的。

实际上: &ptsr 表示的是数组的地址,而不是数组首元素的地址。 本例中 &ptsr 的类型是: int(*)[6] ,是一种数组指针类型
数组的地址+1,跳过整个数组的大小,所以 &ptsr+1 相对于 &ptsr 的差值是24.

三.数组指针的使用

1.把数组arr的地址赋值给数组指针变量p

int arr[10] = {1,2,3,4,5,6,7,8,9,0};
    int (*p)[10] = &arr;

2.看代码



#include<stdio.h>
void jja1(int a[4][3],int row ,int bol){
	int i=0;
	for(i=0;i<row;i++){
		for(int j=0;j<bol;j++)
		{
			printf("%d",a[i][j]);
		}
		printf("\n");
	}
}
int main(){
	int a[4][3]={1,2,3,4,5,6,7,8,9,0};
	jja1(a,4,3);
	return 0;
}

也可以这么写
void jja1(int a[4][3],int row ,int bol)改为void jja1(int (*a)[5] ,int row ,int bol)
4.数组参数
a. 一维数组传参

注意:一维数组传参时,形参既可以是数组形式,也可以是指针形式

假设有以下代码

int arr[10]={0};
int *arr2[10]={0};
test(arr);
test2(arr2);

传参方式
1.void test(int arr[ ])
因为实参只是arr,即数组首元素的地址,所以接受的时候并非整个数组传过去,因此可以省略大小,这里的arr [ ]本质上是一个指针
2.void test(int arr[ 10])
无论是10 100 1100都可以,因为它本质上test函数接收的并非整个数组,而是数组首元素的地址,所以不会根据数据大小去创建真的数组。
3.void test(int *arr)
形参为首元素地址,固用指针接受可以
4.void test2(int *arr[ ])
同一类型指针数组接受
5.void test2(int *arr)
arr2为一个指针数组类型,里面放的是指针。arr2代表这个指针数组的首元素的地址(这一内容的理解可以去标题二二【数组名与&数组名】)。arr2这个地址,存放的是一个int
类型的指针。存放指针的地址,就是一个二级指针。因此实参本质上是一个二级指针,那形参我用一个二级指针接受当然可以。
b. 二维数组传参

注意:二维数组首元素的地址为第一行的地址,即整个一维数组的地址

假设有以下代码

int arr[3][2]={{1,2},{3,4},{4,5}};

test(arr);

二维数组传参方式
1.void test(int arr[3][2])
2.void test(int arr[ ][2])
二维数组行可以省,列不能。注意:2要和形参的数组列相同。
原因:形参二维数组的首地址,即整个一维数组的地址,因此需要知道地址结束的地方。
3.void test(int (*p)[2])
首先arr代表首元素的地址,是二维数组的第一行(即例子中的{1,2,}的地址!)
既然实参是一个一维数组的地址,所以我只能用一个数组指针类型去接收。数组指针指的是指向数组的指针,依然为一个指针,存放的是整个数组的地址。

四 一级指针传参

1.了解一级指针传参

一级指针传参,改变不了原指针的地址,尽管t++,改变了地址,一旦此函数运行结果,就会被释放,不会影响到main函数的地址

可参考一下代码进行理解

int arr[3][2]={{1,2},{3,4},{4,5}};



#include<stdio.h>
void test(int *t){
	t++;
	printf("t=%p\n",t);
}
int main (){
	int arr[4]={1,2,3,4};
		int *p=arr;
		test(p);//p表示一个指针变量的名字,至此指针变量指向的内存地址
		printf("p=%p\n",p);
		printf("%d %d %d %d\n",arr[0],arr[1],arr[2],arr[3]);
		return 0;
}

在这里插入图片描述
2.用一级指针传参改变指针指向的内容
举例:改变arr[0]的值

int arr[3][2]={{1,2},{3,4},{4,5}};



#include<stdio.h>
void test(int *t){
	*t=2;
	
}
int main (){
	int arr[4]={1,2,3,4};
		int *p=arr;
		test(p);
		printf("p=%p\n",p);
		printf("%d %d %d %d\n",arr[0],arr[1],arr[2],arr[3]);
		return 0;
}

在这里插入图片描述

五 二级指针传参

改变一级指针指向的内容或者一级指针地址

void test(int **t){
	**t=2;
	
}
int main (){
	int arr[4]={1,2,3,4};
		int *p=arr;
		test(&p);
		printf("p=%p\n",p);
		printf("%d %d %d %d\n",arr[0],arr[1],arr[2],arr[3]);
		return 0;
}

结果:在这里插入图片描述

以上是改变一级指针指向内容举例
另外

函数形参是二级指针,可以传入的参数——二级指针变量本身和一级指针变量的地址

传参方式:

#include<stdio.h>
void test(int **t){
	
	
}
int main (){
	int n=1 
		int *p=&n;
		int**pp=&p;
		int*arr[10];//数组元素是指针 
		test(pp);//正确· 
		test(&p);//正确 
		test(arr);//正确(数组名是首元素地址,即指针地址) 
		
		return 0;
}

C语言指针笔记1 https://editor.csdn.net/md/?articleId=134108935

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值