C语言指针和数组

printf中:

12
%d整型输出
%ld长整型输出
%p指针变量地址,如果数处数据不够8位数,则左边补零;
%o以八进制数形式输出整数;
%x以十六进制数形式输出整数;
%u以十进制数输出unsigned型数据(无符号数);
%c用来输出一个字符;
%s用来输出一个字符串;
%f用来输出实数,以小数形式输出;
%e以指数形式输出实数;
%g根据大小自动选f格式或e格式,且不输出无意义的零。
#include <stdio.h>
int main()
{
	char str[]="ni hao ni hia";
	//%s是从首元素指向到结束符(\0) 
	//%s是操作指针所指向的内容 
	printf("str[] = %s\n",str);	
	 
	//打印str首元素地址%p %x %d %o 
	printf("str[] = %p\n",str);
	printf("str[] = %x\n",str);
	printf("str[] = %d\n",str);
	printf("str[] = %o\n",str);
	//*str代表第0个元素,是char类型
//	printf("str[] = %s\n",*str);//错误的格式打印 
	printf("str[] = %c\n",str);//空 
	printf("str[] = %c\n",*str);
	int i = 0;
	printf("str[] = ");
	while(str[i]!= '\0')//等价于while(*(ste+i)!= '\0') 
	{
		printf("%c",str[i++]);//价于*(ste+i)
		
	}
	printf("\n");
	return 0;
}

在这里插入图片描述
数组

  • 数组名是数组的首地址;
  • 数组名是常量,不允许修改;
  • 操作数组名等价于&数组名[0];
#include <stdio.h>
int main()
{
 int a[10];
 printf("a = %p ,&a[0] = =%p \n",a,&a[0]);
 return 0;
}

在这里插入图片描述
- 指向数组首元素的指针

#include <stdio.h>
int main()
{
	int a[10] = {1,2,3,4,5,6,7,8,9,10};
	int *p = NULL;
	p = &a[0];//p指针变量指向数组首元素地址 
	//p = a;等价于 	p = &a[0];
	int i = 0;
	for(i = 0;i < 10;i++)
	{
		printf("1->%d, ",a[i]);
		printf("2->%d, ",*(a+i));
		printf("3->%d, ",*(p+i));
		printf("4->%d, ",p[i]);
		printf("\n");
	}
	printf("\n");
	return 0;
 } 

在这里插入图片描述
- 通过指针加减法访问数组的元素

#include <stdio.h>
int main()
{
	int a[10] = {1,2,3,4,5,6,7,8,9,10};
	int n = sizeof(a)/sizeof(*a);//数组的总空间/单个空间 
	int i = 0;
	int *p = NULL;
	p = &a[0];//p指针变量指向数组首元素地址 
	//p = a;等价于 	p = &a[0] 
	for(i = 0;i < n; i++)
	{
		printf("a[%d] = %d,",i,*p++);
	}
	printf("\n");
	
	int *q = &a[n-1];//指向a[]最后一个元素地址 
//	q = a+n-1;
//	q = a+n-1;等价于 int *q = &a[n-1];
//减一 :a表示首地址,n表示有多少个元素(已经包括了首元素) 
	for(i = 0;i < n; i++)
	{
		printf("a[%d] = %d,",i,*q--);
	}
	printf("\n");
	return 0;
 } 

在这里插入图片描述

- 找出数组第二大的数
方法1:

#include <stdio.h>
int main()
{
	int a[10] = {10,8,15,4,19,12,14,20,50,60};
	int n = sizeof(a)/sizeof(*a);//数组的总空间/单个空间
	int max1 = 0;
	int max2 = 0;
	int i = 0;
	for(i = 0;i < n; i++)
	{
		if(a[i]>max1)
		 max1 = a[i];
	}
	printf("max = %d\n",max1);
	for(i = 0;i < n; i++)
	{
		if(a[i]==max1)break;
		if(a[i]>max2)max2 = a[i];
	}
	printf("max = %d\n",max2);
	return 0; 
 } 

在这里插入图片描述
方法2:

#include <stdio.h>
int main()
{
	int a[] = {12,85,11,215,212,45,212,510,36,12,35,14,24,80,100};
	//首先默认第一 二成员是第一大、第二大
	int n = sizeof(a)/sizeof(*a);//数组的总空间/单个空间
	int i = 0;
	int max  = 0;
	int smax  = 0;
	printf("a[]=");
	for(i = 0;i < n; i++)
	{
		printf("%d,",*(a+i));
	}

	if(*(a+0)>*(a+1))
	{
		max = *(a+0);
		smax = *(a+1);
		
	}
	else{
	 max = *(a+1);
	 smax = *(a+0);
	} 
	printf("\na[0],a[1]:max = %d, max1 = %d\n",max,smax);
	//从第三个成员开始找,如果找到比max更大,就max等于该成员,smax=max. 
	for(i = 2;i < n; i++)
	{
		if(*(a+i)>= max)
		{
			smax = max;
			max  = *(a+i);
		}
		else if(*(a+i)>smax)
	     {
			smax = *(a+i);
		 }	
	}
	printf("a[]:max = %d, max1 = %d\n",max,smax);
}

在这里插入图片描述
- 不使用库函数的方式,实现字符串的拷贝功能
方法1:

#include <stdio.h>
int main()
{
	char src[100]= "hello word !";
	char dst[100];
	int n = sizeof(src)/sizeof(*src);//数组的总空间/单个空间
	int i = 0;	
	for(i = 0;i < n; i++)
	{
	  if(src[i] == '\0')break;
	   dst[i]=src[i];
	}
	dst[i]= 0;//补结束符 
	printf("\nsrc[100] = %s\n",src);
	printf("dst[100] = %s\n",dst);
}

在这里插入图片描述
- 指针数组
本身是数组,其中每个元素都是指针。

#include <stdio.h>
int main()
{
	int a[3] = {0,1,2};
	int *p[3]; 
	//指针数组,他还是数组,每个元素都是指针 
//	p[0] = &a[0];//p[0] = a;
//	p[1] = &a[1];//p[1] = a+1;
//	p[2] = &a[2];//p[2] = a+2;	
	int n = sizeof(p)/sizeof(p[0]);	
	int i = 0;
	for(i = 0;i < n;i++)
	{
		p[i] = &a[i];//a+i
	}
	for(i = 0;i < n;i++)
	{
		printf("地址:%d",(p[i]));
		printf("  数据:%d",*(p[i]));
		printf("    %d\n",*(*(p+i)));
	}//p[i] 等价于 *(p+i)
	return 0;
 } 

在这里插入图片描述 - 数组指针
数组指针,它是指针,指向数组的指针。
- 通过函数交换两个变量

#include <stdio.h>
void swap(int n,int m)
{
  n = n+m;
  m = n-m;
  n = n-m;
  printf("1:n = %d, m = %d\n",n,m);
  n = n^m;//异或  异出1 1011 ^ 110 1111 
  m = n^m;//
  n = n^m;//
  printf("2:n = %d, m = %d\n",n,m);
  n = n+m -(m=n);
  printf("3:n = %d, m = %d\n",n,m);
}
void swap1(int *n,int *m)
{
  *n = *n+*m;
  *m = *n-*m;
  *n = *n-*m;//可以转换 
  printf("5:n = %d, m = %d\n",*n,*m);
  *n = *n^*m;//异或  异出1 1011 ^ 110 1111 
  *m = *n^*m;//
  *n = *n^*m;//   //可以转换
  printf("6:n = %d, m = %d\n",*n,*m);
  *n = *n+*m -(*m=*n);//可以转换
  printf("7:n = %d, m = %d\n",*n,*m);
}
int main()
{ 
	int a = 11;
	int b = 22;
	printf("0:a = %d, b = %d\n",a,b);
	printf("\n");
	swap(a,b);//值传递,不管这个变量什么类型,变量本身传递,就是值传递。 
	printf("4:a = %d, b = %d\n",a,b);
	printf("\n");
	swap1(&a,&b);//地址传递,变量的地址 
	printf("8:a = %d, b = %d\n",a,b);
	return 0;
}

在这里插入图片描述形象中的数组
分函数形式(冒泡法)

#include <stdio.h>
void print_array(int a[],int n) 
//void print_array(int *a,int n)
{
	int n1 = sizeof(a)/sizeof(a[0]);
	printf("%d\n",n1);
	printf("%d\n",sizeof(a));//64为系统所以是8 
	printf("%d\n",sizeof(a[0]));//int 4直接
	/*
	所以数组的空间大小不能再这里计算,
	这里只是指针数组,不是数组本身。
	*/ 
	int i = 0;
	for(i = 0;i < n;i++)
	{
		printf("%d, ",a[i]);
	}
	printf("\n");
} 
void paixu(int *a,int n)
{	
	int j = 0;
	int i = 0;
	int temp;
	for(i = 0;i < n-1;i++)
	{
		for(j = 0;j < n-1-i;j++)
		{
			if(a[j] > a[j+1])
			{
				temp = a[j];
		        a[j] = a[j+1];
				a[j+1] = temp; 
			}	
		}		
	}
}

在这里插入图片描述返回值是指针类型函数

  • 在编写代码时不可以返回局部变量的地址(不同编译器可能结果不同)
#include <stdio.h>
int *fnu()
{
	int a;
	//不可以返回局部变量的地址(不同编译器可能结果不同) 
    printf("%d\n",a);
	return &a; 
}
int main()
{
  int *p = NULL;
  p = fnu();//接收函数返回的地址 
  *p = 100;//操作指针所指向的内存 
  printf("%d\n",*p);
  return 0;	
}

a.DEV C++ 软件编译报错
在这里插入图片描述b.Ubuntu系统gcc编译没有问题
在这里插入图片描述
注:正确的操作是不可以返回局部变量的地址的;此时的指针 它是一个野指针(地址随机的);不同编译器得到的结果有所不同,但是这种做法是错误的。

  • 可以写返回全局变量的地址
  1. 在{}外定义的变量,就是全局变量,它可以任意地方使用;
  2. 全局变量只有在整个程序结束后,才能释放(main()结束后。
  3. 此时任何编译器都能够完成。
#include <stdio.h>
int a;//全局变量a; 
int *fnu()
{
	return &a; 
}
int main()
{
  int *p = NULL;
  p = fnu();//接收函数返回的地址 
  *p = 100;//操作指针所指向的内存 
  printf("*p = %d\n",*p);
  return 0;	
}

在这里插入图片描述在这里插入图片描述

  • 换个方式使用带返回地址函数
#include <stdio.h>
int a;//全局变量a; 
int *fnu()
{
	return &a; 
}
int main()
{
  int *p = NULL; 
  p = fnu();//接收函数返回的地址 
  *p = 100;//操作指针所指向的内存 
  printf("*p = %d\n",*p);
  printf("a = %d\n",a);
  
  *(fnu()) = 111;
   printf("a = %d\n",a);
  return 0;	
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值