尽可能用函数实现!
1.定义长度为10的数组
输入9个数字
然后:随机生成一个100以内的数字
把随机生成的这个数字插入到数组中,使数组保持有序
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void sort(int arr[],int len){
int i,j;
for(i=0;i<len-1;i++){
int min = i;//最小数下标
for(j=i+1;j<=len-1;j++){
if(arr[min]>arr[j]){
min = j;
}
}
if(min != i){
int t = arr[min];
arr[min] = arr[i];
arr[i] = t;
}
}
}
int main(){
srand(time(NULL));
int n = rand()%100;
int i;
int arr[10] = {0};
arr[9] = n;
int len = sizeof(arr)/sizeof(arr[0]);
for(i=0;i<len-1;i++){
printf("请输入第%d个数字:",i+1);
scanf("%d",&arr[i]);
printf("\n");
}
sort(arr,len);
for(i=0;i<=len-1;i++){
printf("%d ",arr[i]);
}
return 0;
}
2.输入第一个数组长度
并依次从小到大有序输入这个数组的元素
输入第二个数组长度
并依次从小到大有序输入这个数组的元素
把上面两个有序数组中的元素合并到第三个数组中,使数组依然有序
#include<stdio.h>
void readarr(int arr[],int len){
printf("请从小到大输入%d个元素:",len);
int i;
for(i=0;i<len;i++){
scanf("%d",&arr[i]);
}
}
//arr升序,brr升序,合并放到crr
void mergerasc(int arr[],int len1,int brr[],int len2,int crr[]){
int i=0,j=0,k=0;
while(i<len1 && j<len2){
if(arr[i]<brr[j]){
crr[k++] = arr[i++];//因为k++是后操作
//k++
//i++
}else{
crr[k++]=brr[j++];
//k++
//i++;
}
}
//arr,brr 有一个数组已经无元素,剩下直接放
while(i<len1){//剩下arr
crr[k++]=arr[i++];
}
while(j<len2){//剩下brr
crr[k++]=brr[j++];
}
}
void showarr(int arr[],int len){
int i;
for(i=0;i<len;i++){
printf("%d ",arr[i]);
}
printf("\n");
}
int main(){
printf("请输入第一个数组的长度:");
int len1;
scanf("%d",&len1);
int arr[len1];
readarr(arr,len1);
printf("请输入第二个数组的长度:");
int len2;
scanf("%d",&len2);
int brr[len2];
readarr(brr,len2);
int crr[len1+len2];
mergerasc(arr,len1,brr,len2,crr);
showarr(crr,len1+len2);
return 0;
}
//或者
#include<stdio.h>
void myscanf(int *arr,int len){
int i;
printf("请输入%d个数字",len);
for(i=0;i<len;i++){
scanf("%d",&arr[i]);
}
}
void mysort(int *arr,int len){
int i;
int j;
for(i=0;i<len;i++){
int min=i;
for(j=i+1;j<len;j++){
if(arr[min]>arr[j]){
min=j;
}
}
if(min!=i){
int t=arr[i];
arr[i]=arr[min];
arr[min]=t;
}
}
}
void mergerasc(int *arr,int len1,int *brr,int len2,int *crr){
int i;
int j=0;
for(i=0;i<len1;i++){
crr[j++]=arr[i];
}
for(i=0;i<len2;i++){
crr[j++]=brr[i];
}
}
void show(int *arr,int len){
int i;
for(i=0;i<len;i++){
printf("%d ",arr[i]);
}
printf("\n");
}
int main(){
int i;
int arr[10];
int brr[10];
int crr[20];
myscanf(arr,10);
myscanf(brr,10);
mergerasc(arr,10,brr,10,crr);
mysort(crr,20);
show(crr,20);
return 0;
}
3.随机生成100个[10,100]之间的元素 并输出
求生成重复次数最多的那个元素 并判断有没有一样多的情况
#include<stdio.h>
#include<stdio.h>
#include<time.h>
int main(){
srand(time(NULL));
//用下标标识法
int i;
int arr[100] = {0};
for(i=0;i<100;i++){
arr[i] = rand()%91+10;//10~100区间
}
for(i=0;i<100;i++){
printf("%d ",arr[i]);
}
printf("\n");
int brr[101]={0};//brr[num]来标识num这个数字出现的次数
for(i=0;i<100;i++){
brr[arr[i]]++;
}
//重复次数最多的那个元素,就是brr中数值最大的
int maxi = 0;
int same = 0;//假设没有一样的
for(i=0;i<101;i++){
if(brr[i]>brr[maxi]){
maxi = i;
same =0;//第一次出现最多的情况,暂时还没有
}else if(brr[i] == brr[maxi]){
same =1;
}
}
printf("重复次数最多的是%d,一共出现%d次\n",maxi,brr[maxi]);
if(same){
printf("出现重复\n");
}else{
printf("没有出现重复\n");
}
return 0;
///因为范围是10~100
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void chick(int *arr,int len,int *brr){
int i;
for(i=0;i<len;i++){
brr[arr[i]-10]++;
}
}
void mymax(int *brr,int len){
int i;
int maxi=0;
int same=0;
for(i=0;i<len;i++){
if(brr[maxi]<brr[i]){
maxi=i;
same=0;
}else if(brr[maxi]==brr[i]){
same=1;
}
}
printf("%d %d",maxi+10,brr[maxi]);
printf("\n");
if(same){
printf("有");
}else{
printf("无");
}
printf("\n");
}
int main(){
int i;
srand(time(NULL));
int arr[100];
int brr[91]={0};
for(i=0;i<91;i++){
arr[i]=rand()%91+10;
}
chick(arr,100,brr);
for(i=0;i<91;i++){
printf("%d ",brr[i]);
}
printf("\n");
mymax(brr,91);
return 0;
}
4. 输入一个整数,把该整数的二进制(补码) 存储到数组中 并输出
#include<stdio.h>
#include<math.h>
void bin(int num,int arr[]){
int i;
for(i=0;i<32;i++){
arr[i]=(num>>(31-i))&1;//因为计算机中保存的就是补码,所以把计算机中保存的32为补码从头开始和1&,即保存至数组中就是答案
}
}
int main(){
printf("请输入一个数字:");
int num;
scanf("%d",&num);
int arr[32]={0};
bin(num,arr);
int i;
for(i=0;i<32;i++){
printf("%d",arr[i]);
}
printf("\n");
return 0;
}
5. 不用%x格式占位符,输出一个整数的十六进制
#include<stdio.h>
//十六进制,4个二进制位对应一个16
void hex(int num,char brr[]){
int i;
for(i=0;i<8;i++){
int n = (num>>4*i) & 0xf;//n[0,15],0xf只保留了最低的四个二进制位,0000 0000 0000 0000 0000 0000 0000 0000,因为16进制4个字节字节一位,所以判断完最后的4位后,向右移动4位判断下一组
if(n<10){//因为16进制要考虑是1~10,'A'~'F'
brr[7-i] = n+'0';//48'0',49'1',7-i是因为最先计算出的是最后输出的
}else{
brr[7-i]=n-10+'A';//14-10+'A'='E'
}
}
}
int main(){
char brr[8] = {0};//因为有ABC所以用char类型
int num;
scanf("%d",&num);
hex(num,brr);
printf("0x:");
int i;
for(i=0;i<8;i++){
printf("%c",brr[i]);
}
printf("\n");
return 0;
}
6.先输入数列长度n,然后再输入n个整数,求n个数中的最大子串和
7 : 1 3 -2 7 -8 6 -2 最大和子串为 1+3-2+7=9
6 : -1 3 -2 4 -5 4 3-2+4 = 5
4 : -1 -2 -3 -4 -1 = -1
#include<stdio.h>
int max(int arr[],int len){
int max = arr[0];//记录最大值不能是0,因为有可能最大子串和是负数
int sign = 0;//用来一直加
int i;
for(i=0;i<len;i++){
if(sign>0){
sign += arr[i];
}else{
sign = arr[i];
}
if(sign>max){
max = sign;
}
//或者
//sign += arr[i];
//if(sign>max){
//max = sign;//max永远保留历史相加最大值
//}
//if(sign<0){
// sign=0;//前面加起来为负数,这直接置0重新加
//}
}
return max;
}
int main(){
int n;
printf("数字长度为:");
scanf("%d",&n);
int arr[n];
int i;
for(i=0;i<n;i++){
scanf("%d",&arr[i]);
}
printf("%d:",n);
for(i=0;i<n;i++){
printf("%d ",arr[i]);
}
printf("\n");
int m = max(arr,n);
printf("最大子串和是:%d\n",m);
return 0;
}
7.输入第一个数组长度
并依次输入这个数组的元素
输入第二个数组长度
并依次输入这个数组的元素
(1)输出在两个数组中都存在中的元素
(2)输出在第一个数组但不在第二数组中的元素
(3)合并两个数组 并 去除重复的元素 输出
#include<stdio.h>
int same(int arr[],int len1,int brr[],int len2,int crr[]){
int i,j,k=0;
for(i=0;i<len1;i++){
for(j=0;j<len2;j++){
if(arr[i]==brr[j]){
crr[k++]=arr[i];
break;
}
}
}
return k;
}
int xor(int arr[],int len1,int brr[],int len2,int crr[]){
int i,j,k=0;
for(i=0;i<len1;i++){
int have =0;
for(j=0;j<len2;j++){
if(arr[i]== brr[j]){//第一组和第二组的元素全部比较后,确定没有则不执行这个if,即have还是0,有一个相同则have=1,并不再继续看第二组后面的数,开始第一组的下一个元素判断
have = 1;
break;
}
}
if(!have){
crr[k++]=arr[i];
}
}
return k;
}
void readarr(int arr[],int len){
int i;
for(i=0;i<len;i++){
scanf("%d",&arr[i]);
}
}
void showarr(int arr[],int len){
int i;
for(i=0;i<len;i++){
printf("%d ",arr[i]);
}
printf("\n");
}
int main(){
printf("请输入第一个数组的长度:");
int len1;
scanf("%d",&len1);
int arr[len1];
readarr(arr,len1);
printf("请输入第二个数组的长度:");
int len2;
scanf("%d",&len2);
int brr[len2];
readarr(brr,len2);
int crr[len1+len2];
int ret = same(arr,len1,brr,len2,crr);
printf("两组相同的:");
showarr(crr,ret);
ret = xor(arr,len1,brr,len2,crr);
printf("第一组有第二组没有的:");
showarr(crr,ret);
int res = xor(brr,len2,arr,len1,crr+ret);
printf("两组集合,除去相同的:");
showarr(crr,ret+res);
return 0;
}
8.八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法,并显示每一种摆法
#include <stdio.h>
int attack(int queens[],int row,int col){
int i;
for(i=0;i<row;i++){//row和col都是下标 和对应的第几行第几列少了1
if(col == queens[i]){//在col该列上之前有一个皇后
return 1;
}
if(row-i == col-queens[i] || row-i == queens[i]-col){//在对角线上有皇后
return 1;
}
}
return 0;
}
void show(int queens[],int num){
int i;
for(i=0;i<num;i++){
printf("%d ",queens[i]+1);
}
printf("\n");
}
//要摆放num个皇后
int queen(int num){
int res = 0;//用于记录摆放方法的种数 num表示总共有多少个皇后需要摆放
//记录皇后摆放的位置只需要一维数组
int queens[num];//用于保存8个皇后的位置 行和列 每一行只能摆放一个皇后
int i;
for(i=0;8<num;i++){//init
queens[i] = 0;
}
int row = 0;//目前成功摆放了几个皇后
int col = 0;//每一行 都是从第一列是试探
//不断去摆放 直到成功 成功之后探索下一种方法 什么时候探索结束
while(1){
//相当于在第row+1行的col+1列摆放一个皇后
if(!attack(queens,row,col)){//在row+1行,col+1列摆放皇后并不会和之前的冲
queens[row] = col;//在这一行摆放一个皇后
row++;//下一行
col = -1;//下一行从第1列开始尝试摆放
if(row == num){//所有的皇后都已摆放完成
show(queens,num);
res++;//是一种摆法
//重新去最后一行尝试 得从当前列的下一列开始
col = queens[row-1];
row--;
}//这里是在最后一行进行多次尝试
}
col++;//这一列不能摆放 继续尝试下一列
while(col>=num){//表示最后一行的列判断已经到了最后一个位置,这时候就要用回溯法
col = queens[row-1]+1;
--row;
if(row<0){//连第一行都无法摆放
return res;
}
}
}
}
int main(){
//保存皇后的位置 int board[8][8] = {}; 不需要
//queens[0] 是第一行皇后摆放的列位置
//queens[5] 是第六行皇后摆放的列位置
int res = queen(8);
printf("一共有%d种摆放方法!\n",res);
return 0;
}
9.模拟斗地主
洗牌之后 ,显示每个玩的17张牌(需要显示JQKA 花色 或者 大王 小王)
最后显示 三张底牌
如:
红A 黑A 花K 方J 红10 黑7 ....
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void cash(int card[],int num){
int i;
for(i=0;i<num;i++){
int k = rand()%num;
int tmp = card[i];
card[i] = card[k];
card[k] = tmp;
}
}
void show(int card[],int num){
int i;
for(i=0;i<num;i++){
if(card[i] == 52){
printf("小王 ");
}else if(card[i] == 53){
printf("大王 ");
}else{
switch(card[i]%4){
case 0:printf("黑");break;
case 1:printf("红");break;
case 2:printf("梅");break;
case 3:printf("方");break;
}
switch(card[i]/4){
case 0://A
printf("A ");break;
case 10://J
printf("J ");break;
case 11://Q
printf("Q ");break;
case 12://K
printf("K ");break;
default:
printf("%d ",card[i]/4+1);break;
}
}
}
printf("\n");
}
void deal(int card[],int num,int palyer[3][17],int di[]){
int i;
for(i=0;i<num-3;i++){
palyer[i%3][i/3] = card[i];
}
di[0] = card[51];
di[1] = card[52];
di[2] = card[53];
}
int main(){
//表示一副扑克牌
//表示 A 2 J Q K 大小王 数值
//0-53 0 1 2 3 'A' 4 5 6 7 '2' 8 9 10 11 '3'
srand(time(NULL));
int card[54] = {0};//一副扑克牌54张 A-10 JQK 13*4=52+2=54
int i=0;
//初始化一副新牌
for(i=0;i<54;i++){
card[i] = i;
}
//52 53 小王 大王
//card[i] card[i]/4 == 1 A 2 2 10 11 J 12 Q 13 K
//黑 红 梅 方 card[i]%4 0 1 2 3
//显示一下
show(card,54);
//洗牌
cash(card,54);
show(card,54);
int palyer[3][17] = {};
int di[3] = {};
deal(card,54,palyer,di);
for(i=0;i<3;i++){
printf("玩家%d:",i+1);
show(palyer[i],17);
}
printf("底牌:");
show(di,3);
return 0;
}
10.卡拉兹:
#include <stdio.h>
//unsigned int === size_t
size_t callatz(size_t num){
if(num == 0){
return 0;
}
size_t cnt = 0;
while(num != 1){
if(num&1 == 1){
num = (3*num + 1)/2;
}else{
num = num/2;
}
cnt++;
}
return cnt;
}
int main(){
size_t num = 0;
printf("请输入一个正整数:");
scanf("%u",&num);
printf("%u \n",callatz(num));
return 0;
}
11.本题要求实现一个对数组进行循环右移操作
如输入:6
数组元素为: 1 2 3 4 5 6
循环右移位数:2
输出:5 6 1 2 3 4
#include <stdio.h>
void move(int arr[],size_t len,size_t bit){
bit = bit%len;//10%8=2,这是实际要移动的长度=移动位数%数组长度
int brr[bit];
int i;
for(i=0;i<bit;i++){
brr[bit-1-i] = arr[len-1-i];//右移10位相当于右移2位,所以把最后两位保存下来
}
for(i=0;i<len-bit;i++){//范围是数组长度-实际要移动的长度
arr[len-1-i] = arr[len-1-bit-i];//把除了上面保存到brr中的元素都往后复制
}
for(i=0;i<bit;i++){
arr[i] = brr[i];//把brr中的元素存入arr空缺位置中
}
}
int main(){
int arr[] = {1,2,3,4,5,6,7,8};
size_t len = sizeof(arr)/sizeof(arr[0]);
move(arr,len,10);
int i;
for(i=0;i<len;i++){
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
指针:c语言灵魂
普通的变量传递到函数中,对其进行赋值操作并不会影响原来实参的值
数组作为函数传递到函数中,如果对数组中的内容进行修改会影响到实参数组元素的值
c语言中参数的传递其实是值复制传递
在函数调用时,实参把值赋值给形参,修改形参并不会影响实参的值
变量的地址:内存地址 (变量存储在内存中的位置 编号)
可以用%p显示一个变量的地址 返回十六进制的数字
任意类型变量取地址运算符& 内存地址
int a=10
double d=3.14
char c= ‘a’
//取址运算符 内存地址
printf(“%p”,&a)
printf(“%p”,&b)
printf(“%p”,&c)//默认返回十六进制
scanf(“%p”,&a)//从控制台读取数据时 对变量取址
printf(“%p”,&10)//这样是不行的,&取址运算符的操作数必须是左值,就是变量名
int x = &a;这样会出警告 本质上是int,但是其实不是int
内存地址是一个十六进制的数值,可以用变量来保存变量的地址,即函数中return p,p是地址,在主函数中,可以用int dest=p来接收地址
内存地址即指针
定义指针变量来保存内存地址
一个程序(进程)有4G的虚拟内存,4G用数值表示[0,0xffffffff]
4G的内存编号是从0开始,到0xffffffff=4*1024MB=4 * 210 * 210kb=4 * 220 * 210 Bit=4 * 230 byte=232字节(byte)一个字节一个内存编号[0,2^32-1]
1024=210;
指针变量
即保存内存地址的变量
一块内存用于保存什么数据,决定了该内存的大小
char 1byte
…
char a = ‘a’;
int b = 3;//4字节
char *pa = &a;
int *pb = &b;
pa,pb都是指针变量,用于存储指针(内存变量)对普通变量取&
//定义指针变量:数据类型 *指针变量名;
void func(int a){
printf(%p,&a)
}
int main(){
int a=10
printf(%p,&a)
func(a)
}//输出的答案是不一样的
虽然值都是10,但是变量在不同函数中,所以位置不同,
数据类型 * 这一个整体称为指针变量的类型
int * p1,p2;//这个p1的类型是int* ,p2的类型是int,若是要把两个都定为指针变量,必须都加* ,
这种情况是 p1指针,p2整型
所以 int * p1.*p2这是定义两个指针
*和旁边两个之间有没有空格都行
指针变量的初始化
int a = 0;//一般来说,会定义变量时对其初始化”零”
int *p = null;
当一个指针定义之后,如果不确定存储什么数据,一定要初始化为null
空指针 null 悬空指针 本质上是编号为0的地址
int a=10
int *p=&a;//有确切的值的时候的初始化
int a=10,b=20;
printf(%p%p,&a,&b0)
printf(%d%d,*&a,&*b)//这种就是取地址所指向的值,*和&是相互抵消的
int *p=&a//这个*是指针类型的一部分,不是取值运算符的作用,定义的时候类型名和*是一个整体,都是指针定义的部分
printf(%p,p);//取a地址
print(&d,*p)//这个就是取a的值,因为*p=*&a
p=&b;//修改指针变量的值
printf(%p,p)
printf(“%d”,*p)//这个就是取b的值
取值运算符
*取内存地址中存储数据的数值
*操作数 操作数必须是指针运算
*&a == a; //&a是取地址,*(&a)取地址中的数值
void func(int *p)//指针变量用于存储内存地址
printf(%p,p)//地址
func函数中 得到了main:a的内存地址
*p=1111;//修改内存中的数值 *(&a(从main函数中来的)) main:a=1111
int main(){
int a=10
printf(%p,&a)
func(&a);//传a的地址,因为形参是指针变量
printf("%d",a);//查看a的值是否改变
}
写一个函数交换两个变量的值
//下面一个例子是错误示例,只是地址交换
int a=10,b=20
swap2(&a,&b)//这个也达不到交换的目的
void swap(int *pa,int *pb){//!这个*只是指针类型的必要要素,不是取值运算符的判断!!
int *pt = pa; //将pa即&a即a的地址赋给pt这个指针变量
pa=pb;//b的地址给pa,即将a的地址改为b的地址
pb=pt;
} //始终停留在交换地址层面
//这个例子是正确的
void swap(int *pa,int *pb){
int tmp=*pa; //*(&a) 即a的值放到tmp中过渡
*pa=*pb //*(&b)即b的值放到*(&a)即a的值中
*pb=tmp;//你要交换值,就要到值这个层面去
}
野指针:
我们无法确定一个指针是否是野指针,因为随机给的垃圾值可能是正确的,也可能是错误的
void swap4(int *pa,int *pb){
int *pt;//定义了一个指针变量pt,pt没有初始化,所以里面是一个垃圾值
//这个垃圾值就被当做内存地址,后面值就赋在这个垃圾地址上,有可能该地址不能使用,也有可能访问没有权限 这种称为野指针,非常危险,
*pt=*pa//因为一级指针*pa是=a,是值不是地址,后面会接触二级指针,二级指针是*ppa=*&p=p=&a是地址,不是指值,是指地址
*pa=*pb
*pb=*pt
}//会出现 段错误(核心已转储)
所以建议指针初始化为null
在判断一个指针是否可以进行*运算时
if(p!=NULL){
*p;//意味着可以运算,就能排除野指针
}//后面一般用一个头文件
#include<assert.h>
assert(p!=NULL));
数组名 即内存地址
数组是一片连续的内存,数组名就是这片内存的首地址
int arr[5]={1,2,3,4,5};
printf(%p,arr);//会打印数组内存的首地址=首元素的地址
printf(%p,&arr[0])//首元素的地址,arr[0]是首元素,&arr[0]是首元素地址
printf(%p,&arr)也和上面一样
func(arr,5)//所以数组传递就是传了地址过去,所以在函数中改变值能影响到main中
void func(int *arr,int len){
arr[0]=119;
printf(%d,arr[0]);
printf(%d,0[arr])//两个都行
}
int mian(){
int arr[5]={1111,9527,1314,520,8888};
func(arr,5);//传数组时一般带数组长度,
int i;
for(i=0;i<5;i++)
printf(%d,arr[i]);
printf(%d,i[arr]);
return 0;
}
[ ]运算符:
arr[i] <====> *(arr+i) <====> i[arr]
数组名[下标]=[下标]数组名
为啥呢,*(arr+i)=arr[i] *(i+arr)=i[arr] ;// 因为仅arr时,就是数组名,返回的是首 元素的地址,*(arr+i) 首先arr是首地址地址+i就是首元素的后面第i个元素的地址,最后 加上个*, 地址符号&和* 相互抵消,最终达到arr。
同理*(p+i)=p[i] *(i+p)=i[p];//func(int *p,int len)//传递数组到函数中
&arr[0] 首元素地址 <===> &(arr[0]) <===> &(*(arr+0)) <===> &(*arr) <==> arr
也都是一样的
printf(%p,arr)是个地址
int *p=arr//可以保存,arr类型为 int
printf(%p,p)
printf(%d,*p)
int *p = null;
p=arr;//两个都是存了地址
for(i=0;i<5;i++){
printf(%d,p[i])
}
&arr 值和arr,&arr[0]相等,但是类型不同
&arr// 是一个数组的地址
p = &arr; // p是一个整数类型的地址
指针大小
我们的系统的sizeof(指针)是恒等于4的,但是不同操作系统可能为8
内存是个数值,上面说过,在我们的系统里意味着只需要4个字节就可以保存任意一个内存
地址,指针变量的字节大小恒为4,
linux i386 cpu 32位 恒为4
linux x64 cpu 64位 sizeof(指针) 8
printf(%u,sizeof(char*))
printf(%u,sizeof(int*))
printf(%u,sizeof(doule*))
//答案都是4,%u是无符号整数
char arr[5]={'a','b','c','d','e'}
int *p =NULL;
p= arr;
printf(%u,sizeof(arr))求数组所占内存大小 5*4=20
printf(%u,sizeof(p)) p是一个指针变量4
void func(int arr[5]){
printf(%u,sizeof(arr))
}//函数中为4,Int arr[5] 和 int arr[] 和 int *arr 没有区别,都表示数组元素首地址(在形参中)
Void bar(int *arr){
Printf(%u,sizeof(arr))
}//4
为啥要实参传形参时同时传递数组的长度
因为数组名作为实参传递时,退化为首元素地址(指针)
所以在形参表中,int arr[10] == int arr[ ] === int *arr
所以传递时一定要传数组的长度,因为在函数中你求不出数组的长度,要人为传递
在函数中Sizeof(arr)/sizeof(arr[0])=1 因为两个都是指针的长度,求不出数组的长度
如果没有传参的要求,可以不使用指针,但是要求函数中修改参数,就必须要用指针
Int arr[5] ={119,120,9527,1314,520}
&arr+1 //加整个数组的长度4*5=20个字节,数组加1加整个数组
Int * p=arr
for(i=0;i<5;i++){
printf(“%p+%d=%p”,p,i,p+i)
}//指针地址+1加4字节
Double+8byte
Char+1byte
指针+1:指针偏移一个单位内存大小