c语言基础概念(3)



4.
void的意义
void修饰函数返回值和参数
   如果函数没有返回值,那么应该将其声明为void型
如果函数没有参数,应该声明其参数为void

void修饰函数返回值和参数仅为了表示无
不存在void变量
c语言没有定义void究竟是多大内存的别名。
void指针的意义
c语言规定只有相同类型的指针才可以相互赋值。
void* 指针作为左值用于“接收”任意类型的指针
void*指针作为右值赋值给其他指针时需要强制类型转换。 
#include <stdio.h>


void* memset_my(void* p,char v,int size)
{
	void *ret = p;
	char* dest = (char*)p;
	int i =0;
	for(i=0;i<size;i++)
	{
		dest[i] = v;
	}
	
	return ret;
}	 





     extern中隐藏的意义
 
extern用于声明外部定义的变量和函数
extern用于告诉编译器用c方式编译。
c++编译器和一些变种c编译器会按“自己”的方式编译函数和变量,通过
extern关键字可以命令编译器“以标准c方式进行编译”。

 sizeof是编译器的内置指示符,不是函数
 sizeof用于“计算”相应实体所占的内存大小
 sizeof的值在编译期就已经确定。 


5.const修饰变量
在c语言中const修饰变量是只读的,其本质还是变量
const修饰的变量会在内存占用空间
本质上const只对编译器有用,在运行时无用。

在c语言中const修饰的数组是只读的
const修饰的数组空间不可被改变。 

const修饰指针
const  int* p;    p可变,p指向的内容不可变
int  const* p;    p可变,p指向的内容不可变
int* const p;     p不可变,p指向的内容可变
const int* const p; p和p指向的内容都不可变。
 
口诀:左数右指
当const出现在*号左边时指针指向的数据为常量
当const出现在*后右边时指针本身为常量。 

 const 修饰函数参数和返回值
  const修饰函数参数表示在函数体内不希望改变参数的值
const 修饰函数返回值表示返回值不可改变,多用于返回指针的情形。
 
  深藏不漏的volatile
  
  volatile 可理解为“编译器警告指示字”
  volatile用于告诉编译器必须每次去内存中取变量值。
  volatile主要修饰可能被多个线程访问的变量。
  volatile也可以修饰可能被未知因数更改的变量
  
  问题:const 和 volatile是否可以同时修饰一个变量?
  
                                                                                                                                                                                                                            
6.struct和union分析


空结构体占用多大内存?

下面输出什么?
	
		strut D
		{
			
		};
		
		int main()
		{
			struct D d1;
			struct D d2;
			
			printf("%d\n",sizeof(struct D));
			printf("%d,%0X\n",sizeof(d1),&d1);
			printf("%d,%0X\n",sizeof(d2),&d2);
			return 0;	
		}	 
	  


 
 我的机器是: 0
  0,28FF20
0,28FF20 

由结构体产生柔性数组
柔性数组即数组大小待定的数组
在c语言中结构体的最后一个元素可以是大小未知的
c语言中可以由结构体产生柔性数组

struct SoftArray
{
int len;
int array[];
};

例子:
<pre name="code" class="plain">#include <stdio.h>
#include <malloc.h>


typedef struct _soft_array
{
    int len;
    int array[];
}SoftArray;


int main()
{  
    int i = 0;
    SoftArray* sa = (SoftArray*)malloc(sizeof(SoftArray) + sizeof(int) * 10);
    
    sa->len = 10;
    
    for(i=0; i<sa->len; i++)
    {
        sa->array[i] = i + 1;
    }
    
    for(i=0; i<sa->len; i++)
    {
        printf("%d\n", sa->array[i]);   
    }
    
    free(sa);
    
    return 0;
}


 


柔性数组的使用:  存储斐波拉次数列:

#include <stdio.h>
#include <malloc.h>


typedef struct _soft_array
{
    int len;
    int array[];
}SoftArray;


SoftArray* create_soft_array(int size)
{
    SoftArray* ret = NULL;
    
    if( size > 0 )
    {
        ret = (SoftArray*)malloc(sizeof(*ret) + sizeof(*(ret->array)) * size);
        
        ret->len = size;
    }
    
    return ret;
}


void fac(SoftArray* sa)
{
    int i = 0;
    
    if( NULL != sa )
    {
        if( 1 == sa->len )
        {
           sa->array[0] = 1;
        }
        else 
        {
            sa->array[0] = 1;
            sa->array[1] = 1;
            
            for(i=2; i<sa->len; i++)
            {
                sa->array[i] = sa->array[i-1] + sa->array[i-2];
            }
        }
    } 
}


void delete_soft_array(SoftArray* sa)
{
    free(sa);
}


int main()
{
    int i = 0;
    SoftArray* sa = create_soft_array(10);
    
    fac(sa);
    
    for(i=0; i<sa->len; i++)
    {
        printf("%d\n", sa->array[i]);
    }
    
    delete_soft_array(sa);
    
    return 0;
} 





union和struct的区别:
struct中的每个域在内存中都独立分配空间
union只分配最大域的空间,所有域共享这个空间。

struct A
{
int a;
int b;
int c;

} ;


union B
{
int a;
int b;
int c;
};


int main()
{
printf("%d\n",sizeof(struct A));
printf("%d\n",sizeof(union B));
return 0;
}
 
 
 union使用的注意事项:
 union的使用受系统大小端的影响:
                     int i = 1;
  大端模式    0x0  0x0  0x0 0x1
             低地址-->高地址
 
  int i = 1; 
小端模式: 0x0 0x0 0x0 0x1
高地址 <---- 低地址 
 
 
union C 
{
int i;
char c;
};

union C c;
c.i = 1;
printf("%d\n",c.c);

我的机器是1,表明是小端模式。 





7.枚举类型的使用方法
enum 是一种自定义类型
enum默认常量在前一个值的基础上依次加1
enum类型常量只能取定义时的离散值

  #define宏常量只是简单的进行值替换,枚举常量是真正意义上的常量
  #define 宏常量无法被调试,枚举常量可以
  #define 宏常量无类型信息,枚举常量是一种特定类型的常量。
  
   typedef用于给一个已经存在的数据类型重命名
   typedef并没有产生新的类型
   typedef重定义的类型不能进行unsigned和singned扩展。
   typedef是给已有类型取别名
   #define为简单的字符串替换,无别名的概念。
   
   typedef char* PCHAR
   PCHAR p1,p2;
   
   #define PCHAR char*
   PCHAR p3,p4;      这个不行? 
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值