C语言基础知识

1.计算数组中元素的个数 数组总大小/一个类型的大小

   

     int a[3];
    char b[3];

    printf("a数组里面有%d个元素\n",sizeof(a)/sizeof(a[0])); 
    printf("b数组里面有%d个元素\n",sizeof(b)/sizeof(b[0]));

2.数组名 等于数组首元素首地址  a=&a[0]

3. 指针赋值  指针变量存放地址的变量

    int a = 10;
    int b[5]={1,2,3};
    int *p;
    int *p1;
    p1= &a;          //p1指向a的地址
    p=b;             //等价于p=&a[0]
    printf("%d\n",p[0]);  //等价于*p 首地址内容
    printf("%d\n",*p1);  *p取地址的内容
    return 0;

4.数组指针赋值

     int a[3]={1,2,3};
     int *p;
     p=&a[0];   第一个元素的地址         *p=1;  

     p=a;          数组名就是地址            p[0]=1; 等于 a[0]=1          

5.指针数组  多个指针 每一项都是指针变量

int main()
{
   int a= 1 ;
   int b= 2 ;
   int c= 3 ;
    
   int* arm[3]; //多个指针 叫做指针数组数组中的每一项都是指针变量 存放地址

  arm[0] = &a;
  arm[1] = &b;
  arm[2] = &c;  //三个普通没有任何关系的整形变量的地址存入指针数组
  
  int i;
  for(i=0;i<3;i++)
  {
	printf(" %d",*(arm[i]));

  }
  printf("\n");
  
  system("pause");
  return 0;
}

6.数组指针  一个指针 指向整个数组


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


	int (*p)[3];  //数组指针  一个指针 指向整个数组 偏移值是偏移了这个数组的大小 12

    p = &a;

	int *p1;
	p1=a;
    
	printf(" 数组的地址数是: %p\n",a);    //0019ff24
	printf(" 数组的地址数是: %p\n",&a[0]);//0019ff24
	printf("p数组的地址数是: %p\n",p);    //0019ff24
	printf("p1数组的地址数是:%p\n",p1);  //0019ff24

    printf("****************************\n");
	      printf("p++的结果是:%p\n",++p);       //0019ff30-
		                                         //      24=12  数组指针偏移 得是整个数组

       	 printf("p1++的结果是:%p\n",++p1);     //0019ff28-
		                                        //      24=4     指针偏移  得是单个地址
	printf("\n")
    return 0;
}

7. 变量定义

int main()   
{
  int a;     //定义整数变量
  
  int *pa;  //定义pa为指向整数型的指针变量
 
  int a[5]; //定义数组a 有5个元素


  int *p[4];   //指针数组 p是由4个指向整数型数据的指针元素组成
               //p++偏移的是一个数组元素的大小 int为4个字节
  
  int (*p)[4];  //数组指针 p是指向包含4个元素的一维数组的指针变量
	            //p++偏移的是整个数组4*4(int)=16字节

  int f();      //f为返回整数型数值的函数
 
  int *p();     //p是返回一个指针的函数,该指针指向整形变量  下例 
/*  int *p( int *p1)
	{
	  return p1;
	}
    int main()
	{
     int a ;
	 int *p2;  //p2野指针 没有初值
	 p2=p(&a);   //函数指针赋值 
     
	}
*/  
   int (*p)();  //p为指向函数()的指针  函数指针与int f() 对比 该函数返回一个整形数据
   
   int **p    //p是一个指针变量 指向一个指向整形数据的指针变量
	    
   void *p;   //p是一个指针变量 类型为void(空类型) 不指向具体对象
  
}

8.字符串大小计算   

字符串的存储 在内存中除了有效字符以外 会自动在后面补一个'\0' 作为结束位 用sizeof就计算不准确

char a3[]="abc"  比如这个 虽然只有三个 但是系统会自动补充一个'\0'  所以数组的个数是:4

但是数组 int a[]={1,2,3} 就只有三个 数组的个数是3 

计算字符串的有效字符  必须是char型 字符串 strlen 计算字符串大小 遇到'\0' 则停止计数

	int a[]={1,2,3};
    printf("数组a的元素个数是:%d\n",sizeof(a)/sizeof(a[0]));

	char a2[100]="hello";//如果定义100 则数组元素为100 只是除了有效字符hello剩下的都是'\0' 
    printf("数组a的元素个数是:%d\n",sizeof(a2)/sizeof(a2[0]));

	printf("我们希望得到a2数组中真正字母个数用strlne为:%d\n",strlen(a2));

9.字符串与数组的区别

数字是整形int 字符是char          字符串用strlen求大小  若使用sizeof 则是sizeof(a)/sizeof(a[0]) 求大小   数组用sizeof()直接求大小

C语言中没有字符串这种数据类型,可以通过char的数组来代替
字符串一定是一个char的数组,但char的数组未必是字符串
数字0(和字符'\0'等价) 结尾的字符数组就是一个字符串,但如果字符数组没有以数字0结尾,那么就不是一个字符串,只是普通字符数组,所以字符串是一种特殊的字符串数组。

1.%s是打印一个字符串,%c是打印一个字符

   

2.不指定数组长度以'\0'或数字0结尾的字符数组是字符串     否则就是字符数组

 

3.指定长度:后面没有赋值的元素,自动补0

 

4.%s遇到'\0'自动结束输出

  

5.若输入的字符串含有空格,scanf默认遇到空格结束输入

                      

改正后                         

若将正则表达式改成[^1-9],则表示遇到1-9的任意数字结束输入                       

                                                                    

10.输出

     puts(str);               //把一个字符串写入到标准输出 stdout,直到空字符,但不包括空字符。自动添加换行符\n
     printf("%s\n",str);  //作用相同     

11.输入

scanf("%s",pstr);

gets(pstr);                         作用相同  只能是字符串 整型不行

12.指针定义

              char *pstr;                     //定义函数       

             pstr=(char *)malloc(10);      //开辟空间           如过定义数组则不需要开辟空间 只需要memset清空空间

              memset(pstr,'\0',10);           //空间清零     

             free(pstr);                              //使用完后清楚malloc申请的空间           

13. 结构体中的 字符串赋值必须用strcpy 拷贝

struct student
{
 int fenshu;
 char name[20];
};
     struct student test;
    test.fenshu= 100;
    strcpy(test.name,"zhangsan"); 

14.结构体偏移

                //结构体大小必须是所有成员大小的整数倍   对其浪费空间 但是提高效率
struct s1       // 结构体成员的偏移量必须是当前成员大小的整数倍 
{
   char a;       //偏移1
   char b;       //偏移1
   int  c;       //逻辑偏移2, 按照对其的规则 要偏移4
};               //{}  {}  {}{}{}{}          逻辑偏移  6
                 //{} {} {} {}  {}{}{}{}      实际偏移 要对齐8 
struct s2       
{
   
   char b;       //1  {}
   int  c;       //{}  {}{}{}   {}{}{}{} 1+3+4 
   char a;       //1+3+4+1       所以是9 但是因为对齐   所以增加到12
}; 

struct s3
{
    char in;          //1
	int i;            //1+3+4
	char sa[10];      //1+3+4+10=18  对齐 所以增加到20
};


struct s4
{
   char k;               //1
   int i;                //4+3+1
     struct s            //16
	 {
	    char q;          //1 
		int a;           //1+3+4
		double o;        //8
	 }temp;              //定义结构体变量才会开辟空间
	 float x;            //4   4+3+1 +8+8 +4=28  
                         //对齐的话 不需要是子结构体的整数倍 但是需要是所有个体的整数倍   32 
};



#pragma pack(10)  
struct s6{
		char ch;             //1
		int i;               //1+3+4
		float f;             //1+3+4+4
		double d;            //1+3+4+4+8=20   24    
};                           //如果单个元素大小没有超过对齐数10 则按照结构体最大数对齐 8对齐

#pragma pack(4)  //指定向4对齐 

struct s5{
	char ch;
	int i;
	float f;
	double d;         //如果单个元素大小超过对齐数4 则最小对齐 4对齐  所以就是20而不是24
};

int main()
{

	printf("int   :%d\n",sizeof(int));   //2的32次 
    printf("char  :%d\n",sizeof(char));  //2的8次
	printf("float :%d\n",sizeof(float)); 
	printf("double:%d\n",sizeof(double));

    printf("s1:%d\n",sizeof(struct s1));
    printf("s2:%d\n",sizeof(struct s2));
	printf("s3:%d\n",sizeof(struct s3));
	printf("s4:%d\n",sizeof(struct s4));
	printf("s5:%d\n",sizeof(struct s5));
	printf("s6:%d\n",sizeof(struct s6));

	system("pause");
	return 0;

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值