您当前的位置:首页 > IT编程 > C++
| C语言 | Java | VB | VC | python | Android | TensorFlow | C++ | oracle | 学术与代码 | cnn卷积神经网络 | gnn | 图像修复 | Keras | 数据集 | Neo4j | 自然语言处理 | 深度学习 | 医学CAD | 医学影像 | 超参数 | pointnet | pytorch | 异常检测 | Transformers | 情感分类 | 知识图谱 |

自学教程:C++ BcAssert函数代码示例

51自学网 2021-06-01 19:54:47
  C++
这篇教程C++ BcAssert函数代码示例写得很实用,希望能帮到您。

本文整理汇总了C++中BcAssert函数的典型用法代码示例。如果您正苦于以下问题:C++ BcAssert函数的具体用法?C++ BcAssert怎么用?C++ BcAssert使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。

在下文中一共展示了BcAssert函数的21个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: sizeof

//////////////////////////////////////////////////////////////////////////// onDataLoadedvoid CsFileReaderRPC::onDataLoaded( void* pData, BcSize Size ){	// Chunk index is fed in as we can't simply match pointers here.	BcU32 ChunkIdx = *(BcU32*)pData;		pData = ((BcU32*)pData) + 1;	Size -= sizeof( BcU32 );		// Find the chunk that data matches to.	if( ChunkIdx < Header_.NoofChunks_ )	{		CsFileChunk* pChunk = &pChunks_[ ChunkIdx ];		CsFileChunkProps* pChunkProps = &pChunkProps_[ ChunkIdx ];				BcAssert( pChunk->Size_ == Size );			// Copy data and cache pointer.		BcU32 TotalHeaderSize = sizeof( CsFileHeader ) + sizeof( CsFileChunk ) * Header_.NoofChunks_;		void* pInternalData = pData_ + ( pChunk->Offset_ - TotalHeaderSize );		BcMemCopy( pInternalData, pData, Size );		BcAssert( (BcU8*)pInternalData < ( pData_ + TotalDataSize_ ) );				pChunkProps->Status_ = CsFileChunkProps::STATUS_LOADED;		ChunkDelegate_( this, ChunkIdx, pChunk, pInternalData );	}}
开发者ID:kolhammer,项目名称:Psybrus,代码行数:29,


示例2: Lock

//////////////////////////////////////////////////////////////////////////// addChunkBcU32 CsPackageImporter::addChunk( BcU32 ID, const void* pData, BcSize Size, BcSize RequiredAlignment, BcU32 Flags ){	std::lock_guard< std::recursive_mutex > Lock( BuildingLock_ );	BcAssert( BuildingBeginCount_ > 0 );	BcAssert( Size > 0 );	BcAssert( BcPot( RequiredAlignment ) );	BcAssert( RequiredAlignment <= 4096 );	const BcU8* pPackedData = reinterpret_cast< const BcU8* >( pData );	size_t PackedSize = Size;	BcBool HaveCompressed = BcFalse;	// If we need to compress, do so.	if( ( Flags & csPCF_COMPRESSED ) != 0 )	{		if( BcCompressData( static_cast< const BcU8* >( pData ), Size, pPackedData, PackedSize ) )		{			HaveCompressed = BcTrue;		}		else		{			// On failure, strip compressed flag.			Flags &= ~csPCF_COMPRESSED;		}	}		// Generate header.	CsPackageChunkHeader ChunkHeader;	ChunkHeader.ID_ = ID;	ChunkHeader.Offset_ = 0;	ChunkHeader.Flags_ = Flags;	ChunkHeader.RequiredAlignment_ = static_cast< BcU32 >( RequiredAlignment );	ChunkHeader.PackedBytes_ = static_cast< BcU32 >( PackedSize );	ChunkHeader.UnpackedBytes_ = static_cast< BcU32 >( Size );	ChunkHeader.PackedHash_ = BcHash( (BcU8*)pPackedData, PackedSize );	ChunkHeader.UnpackedHash_ = BcHash( (BcU8*)pData, Size );	// Generate data.	CsPackageChunkData ChunkData;	ChunkData.Status_ = csPCS_NOT_LOADED;	ChunkData.Managed_ = BcFalse;		// Store as packed data.	ChunkData.pPackedData_ = new BcU8[ PackedSize ];	ChunkData.pUnpackedData_ = NULL;	BcMemCopy( ChunkData.pPackedData_, pPackedData, PackedSize );	if( HaveCompressed )	{		delete [] pPackedData;	}	// Push into lists.	ChunkHeaders_.push_back( ChunkHeader );	ChunkDatas_.push_back( ChunkData );	return static_cast< BcU32 >( ChunkHeaders_.size() - 1 );}
开发者ID:Psybrus,项目名称:Psybrus,代码行数:60,


示例3: BcAssert

//////////////////////////////////////////////////////////////////////////// onResourceHeadersLoadedvoid CsPackageLoader::onResourceHeadersLoaded( void* pData, BcSize Size ){	// Check we have the right data.	BcAssert( pData == pResourceHeaders_ );	BcAssert( Size == sizeof( CsPackageResourceHeader ) * Header_.TotalResources_ );	// This callback is complete.	--PendingCallbackCount_;}
开发者ID:wdmchaft,项目名称:Psybrus,代码行数:11,


示例4: requestChunk

//////////////////////////////////////////////////////////////////////////// fileChunkReadyvoid ScnModel::fileChunkReady( BcU32 ChunkIdx, BcU32 ChunkID, void* pData ){	// If we have no render core get chunk 0 so we keep getting entered into.	if( RsCore::pImpl() == NULL )	{		requestChunk( 0 );		return;	}	if( ChunkID == BcHash( "header" ) )	{		pHeader_ = (ScnModelHeader*)pData;	}	else if( ChunkID == BcHash( "nodetransformdata" ) )	{		pNodeTransformData_ = (ScnModelNodeTransformData*)pData;	}	else if( ChunkID == BcHash( "nodepropertydata" ) )	{		pNodePropertyData_ = (ScnModelNodePropertyData*)pData;		// Mark up node names.		// TODO: Automate this process with reflection!		for( BcU32 NodeIdx = 0; NodeIdx < pHeader_->NoofNodes_; ++NodeIdx )		{			ScnModelNodePropertyData* pNodePropertyNode = &pNodePropertyData_[ NodeIdx ];			markupName( pNodePropertyNode->Name_ );		}	}	else if( ChunkID == BcHash( "vertexdata" ) )	{		BcAssert( pVertexBufferData_ == NULL || pVertexBufferData_ == pData );		pVertexBufferData_ = (BcU8*)pData;	}	else if( ChunkID == BcHash( "indexdata" ) )	{		BcAssert( pIndexBufferData_ == NULL || pIndexBufferData_ == pData );		pIndexBufferData_ = (BcU8*)pData;	}	else if( ChunkID == BcHash( "vertexelements" ) )	{		pVertexElements_ = (RsVertexElement*)pData;	}	else if( ChunkID == BcHash( "meshdata" ) )	{		pMeshData_ = (ScnModelMeshData*)pData;		RsVertexElement* pVertexElements = pVertexElements_;		for( BcU32 Idx = 0; Idx < pHeader_->NoofPrimitives_; ++Idx )		{			pMeshData_->VertexElements_ = pVertexElements;			pVertexElements += pMeshData_->NoofVertexElements_;		}				markCreate(); // All data loaded, time to create.	}}
开发者ID:Psybrus,项目名称:Psybrus,代码行数:59,


示例5: BcAssert

//////////////////////////////////////////////////////////////////////////// addvoid ScnAnimationPose::add( const ScnAnimationPose& Reference, const ScnAnimationPose& A, const ScnAnimationPose& B, BcF32 T ){	BcAssert( A.NoofTransforms_ == NoofTransforms_ );	BcAssert( B.NoofTransforms_ == NoofTransforms_ );	for( BcU32 Idx = 0; Idx < NoofTransforms_; ++Idx )	{		pTransforms_[ Idx ].add( Reference.pTransforms_[ Idx ], A.pTransforms_[ Idx ], B.pTransforms_[ Idx ], T );	}}
开发者ID:Dezzles,项目名称:Psybrus,代码行数:12,


示例6: BcAssert

//////////////////////////////////////////////////////////////////////////// interpolatePosevoid ScnAnimationTreeTrackNode::interpolatePose(){	if( AnimationQueue_.size() > 0 )	{		BcAssert( pPoseFileDataA_ != nullptr );		BcAssert( pPoseFileDataB_ != nullptr );		const BcF32 TimeLength = pPoseFileDataB_->Time_ - pPoseFileDataA_->Time_;		const BcF32 TimeRelative = Time_ - pPoseFileDataA_->Time_;		const BcF32 LerpAmount = TimeRelative / TimeLength;			pWorkingPose_->blend( *pPoseA_, *pPoseB_, LerpAmount );	}}
开发者ID:Psybrus,项目名称:Psybrus,代码行数:15,


示例7: BcAssert

//////////////////////////////////////////////////////////////////////////// recreatevoid ScnViewComponent::recreateFrameBuffer(){	if( RenderTarget_.isValid() || DepthStencilTarget_.isValid() )	{		BcAssert( RenderTarget_.isValid() && DepthStencilTarget_.isValid() );		BcAssert( RenderTarget_->getWidth() && DepthStencilTarget_->getWidth() );		BcAssert( RenderTarget_->getHeight() && DepthStencilTarget_->getHeight() );		RsFrameBufferDesc FrameBufferDesc( 1 );		FrameBufferDesc.setRenderTarget( 0, RenderTarget_->getTexture() );		FrameBufferDesc.setDepthStencilTarget( DepthStencilTarget_->getTexture() );		FrameBuffer_ = RsCore::pImpl()->createFrameBuffer( FrameBufferDesc );	}}
开发者ID:Psybrus,项目名称:Psybrus,代码行数:17,


示例8: BcAssert

//////////////////////////////////////////////////////////////////////////// typevoid MdlNode::type( BcU32 NodeType ){	if( NodeType != eNT_COLMESH && NodeType != eNT_ENTITY )	{		BcAssert( ( NodeType_ & ~NodeType ) == 0 );	}	if( ( NodeType_ & NodeType ) == 0 )	{		NodeType_ |= NodeType;		switch( NodeType )		{		case eNT_EMPTY:			break;		case eNT_MESH:			pNodeMeshObject_ = new MdlMesh();			break;		case eNT_SKIN:			pNodeSkinObject_ = new MdlMesh();			break;		case eNT_COLMESH:			// Naughty.			//pNodeColMeshObject_ = new MdlMesh();			BcAssert( pNodeMeshObject_ != NULL );			break;		case eNT_MORPH:			pNodeMorphObject_ = new MdlMesh();			break;		case eNT_ENTITY:			pNodeEntityObject_ = new MdlEntity();			break;		case eNT_LIGHT:			pNodeLightObject_ = new MdlLight();			break;		case eNT_PROJECTOR:			pNodeProjectorObject_ = new MdlProjector();			break;		}	}}
开发者ID:kolhammer,项目名称:Psybrus,代码行数:50,


示例9: PSY_LOG

//////////////////////////////////////////////////////////////////////////// importResourceBcBool CsPackageImporter::importResource( 	CsResourceImporterUPtr Importer, 	const Json::Value& Resource ){	// Catch name being missing.	if( Importer->getResourceName().empty() )	{		PSY_LOG( "ERROR: Name not specified for resource./n" );		return BcFalse;	}	// Catch type being missing.	if( Importer->getResourceType().empty() )	{		PSY_LOG( "ERROR: Type not specified for resource./n" );		return BcFalse;	}		PSY_LOG( "INFO: Processing /"%s/" of type /"%s/"/n", 		Importer->getResourceName().c_str(), Importer->getResourceType().c_str() );		// Get first chunk used by resource.	size_t FirstChunk = ChunkHeaders_.size();	BcBool SuccessfulImport = BcFalse;	// NOTE: Eventually we will be exception safe throught the import	//       pipeline, so shouldn't need these adhoc try/catch blocks.	try	{		PSY_LOGSCOPEDINDENT;		SuccessfulImport = Importer->import( Resource );		// Check for error + critical messages.		SuccessfulImport &= Importer->getMessageCount( CsMessageCategory::ERROR ) == 0;		SuccessfulImport &= Importer->getMessageCount( CsMessageCategory::CRITICAL ) == 0;	}	catch( CsImportException ImportException )	{		PSY_LOG( "ERROR: %s", ImportException.what() );	}		// Handle success.	if( SuccessfulImport )	{		// Setup current resource header.		CurrResourceHeader_.Name_ = addString( Importer->getResourceName().c_str() );		CurrResourceHeader_.Type_ = addString( Importer->getResourceType().c_str() );		CurrResourceHeader_.Flags_ = csPEF_DEFAULT;		CurrResourceHeader_.FirstChunk_ = static_cast< BcU32 >( FirstChunk );		CurrResourceHeader_.LastChunk_ = static_cast< BcU32 >( ChunkHeaders_.size() - 1 ); // Assumes 1 chunk for resource. Fair assumption.				// Make sure chunk indices are valid.		BcAssert( CurrResourceHeader_.FirstChunk_ <= CurrResourceHeader_.LastChunk_ );		ResourceHeaders_.push_back( CurrResourceHeader_ );	}		return SuccessfulImport;}
开发者ID:Psybrus,项目名称:Psybrus,代码行数:62,


示例10: BcAssert

//////////////////////////////////////////////////////////////////////////// haveAnyValidResourcesBcBool CsPackage::haveAnyValidResources() const{	BcAssert( BcIsGameThread() );	// If the data isn't ready, we will have valid resources soon.	if( pLoader_->isDataReady() == BcFalse )	{		return BcTrue;	}	// If our resource list is empty we can exit early.	if( Resources_.size() == 0 )	{		return BcFalse;	}	// Search through list for all valid resources.	for( BcU32 Idx = 0; Idx < Resources_.size(); ++Idx )	{		const CsResourceRef<>& Resource( Resources_[ Idx ] );		if( Resource.isValid() == BcTrue )		{			return BcTrue;		}	}	//	return BcFalse;}
开发者ID:wdmchaft,项目名称:Psybrus,代码行数:32,


示例11: BcAssert

//////////////////////////////////////////////////////////////////////////// allocParticleBcBool ScnParticleSystemComponent::allocParticle( ScnParticle*& pParticle ){	// We can't be allocating whilst we're updating.	BcAssert( UpdateFence_.count() == 0 );	// TODO: Perhaps a free list of indices? Reordering of dead particles?	//       Either way I want the update to be cache friendly.	for( BcU32 Idx = 0; Idx < NoofParticles_; ++Idx )	{		BcU32 RealIdx = ( Idx + PotentialFreeParticle_ ) % NoofParticles_; // Slow. If we use powers of 2, we can &.		ScnParticle* pPotentiallyFreeParticle = &pParticleBuffer_[ RealIdx ];		if( pPotentiallyFreeParticle->Alive_ == BcFalse )		{			pParticle = pPotentiallyFreeParticle;			// Prevent it being rendered for the first frame.			pParticle->Scale_ = MaVec2d( 0.0f, 0.0 );			pParticle->Colour_ = RsColour( 0.0f, 0.0f, 0.0f, 0.0f );			++PotentialFreeParticle_;			return BcTrue;		}	}		return BcFalse;}
开发者ID:Dezzles,项目名称:Psybrus,代码行数:29,


示例12: VertPosA

//////////////////////////////////////////////////////////////////////////// buildNormalsvoid MdlMesh::buildNormals(){	for ( BcU32 i = 0; i < ( aIndices_.size() / 3 ); ++i )	{		BcU32 TA = aIndices_[ ( i * 3 ) + 0 ].iVertex_;		BcU32 TB = aIndices_[ ( i * 3 ) + 1 ].iVertex_;		BcU32 TC = aIndices_[ ( i * 3 ) + 2 ].iVertex_;		MdlVertex& VertA = aVertices_[ TA ];		MdlVertex& VertB = aVertices_[ TB ];		MdlVertex& VertC = aVertices_[ TC ];		BcVec3d VertPosA( VertA.Position_.x(), VertA.Position_.y(), VertA.Position_.z() );		BcVec3d VertPosB( VertB.Position_.x(), VertB.Position_.y(), VertB.Position_.z() );		BcVec3d VertPosC( VertC.Position_.x(), VertC.Position_.y(), VertC.Position_.z() );		BcVec3d Normal = ( VertPosA - VertPosB ).cross( ( VertPosB - VertPosC ) );		VertA.Normal_ += Normal;		VertB.Normal_ += Normal;		VertC.Normal_ += Normal;	}	for ( BcU32 i = 0; i < aVertices_.size(); ++i )	{		MdlVertex& Vert = aVertices_[ i ];		Vert.bNormal_ = BcTrue;		Vert.Normal_.normalise();		BcReal Mag = Vert.Normal_.magnitude(); 		BcAssert( BcAbs( Mag - 1.0f ) < 0.00001f );	}}
开发者ID:kolhammer,项目名称:Psybrus,代码行数:35,


示例13: BcAssert

//////////////////////////////////////////////////////////////////////////// getContext//virtualRsContext* RsCoreImplGL::getContext( OsClient* pClient ){    BcAssert( BcIsGameThread() );    TContextMapIterator It = ContextMap_.find( pClient );    if( It != ContextMap_.end() )    {        return It->second;    }    else    {        if( pClient != NULL )        {            RsContextGL* pResource = new RsContextGL( pClient, ContextMap_[ NULL ] );            createResource( pResource );            // If we have no default context, set it.            if( ContextMap_[ NULL ] == NULL )            {                ContextMap_[ NULL ] = pResource;            }            // Store mapped to client.            ContextMap_[ pClient ] = pResource;            return pResource;        }    }    return NULL;}
开发者ID:Dezzles,项目名称:Psybrus,代码行数:34,


示例14: requestChunk

//////////////////////////////////////////////////////////////////////////// fileChunkReadyvoid ScnTexture::fileChunkReady( BcU32 ChunkIdx, BcU32 ChunkID, void* pData ){	// If we have no render core get chunk 0 so we keep getting entered into.	if( RsCore::pImpl() == NULL )	{		requestChunk( 0 );		return;	}	if( ChunkID == BcHash( "header" ) )	{				// Request all texture levels.		for( BcU32 iLevel = 0; iLevel < Header_.Levels_; ++iLevel )		{			requestChunk( ++ChunkIdx );		}				// We update the header, create a new texture rather than updating.		CreateNewTexture_ = BcTrue;		}	else if( ChunkID == BcHash( "body" ) )	{		// Grab pointer to data.		BcAssert( pTextureData_ == NULL || pTextureData_ == pData );		pTextureData_ = pData;				// Setup.		setup();	}}
开发者ID:wdmchaft,项目名称:Psybrus,代码行数:32,


示例15: BcAssert

//////////////////////////////////////////////////////////////////////////// updateParticlevoid ScnParticleSystemComponent::updateParticle( ScnParticle& Particle, BcReal Tick ){	// TODO: Move each section of this into "affectors":	// - Physics affector: Move physically based on vel/accel.	// - Colour lerp affector: Some more advanced colour interpolation.	// - Maybe even fancier stuff like curve based interpolation of position, colour, scale?	// - - Advantage: Min/Max and that stuff can live in the affector (memory saving++).	// For now, KISS. This just needs to function, I can make it better later :)		BcAssert( Particle.Alive_ == BcTrue );		// Do position.	Particle.Position_ += Particle.Velocity_ * Tick;	Particle.Velocity_ += Particle.Acceleration_ * Tick;	// Calculate interpolators.	BcReal LerpValue = Particle.CurrentTime_ / Particle.MaxTime_;	Particle.Scale_.lerp( Particle.MinScale_, Particle.MaxScale_, LerpValue );	Particle.Colour_.lerp( Particle.MinColour_, Particle.MaxColour_, LerpValue );	// Advance current time.	Particle.CurrentTime_ += Tick;		// Kill particle!	if( Particle.CurrentTime_ > Particle.MaxTime_ )	{		Particle.Alive_ = BcFalse;	}}
开发者ID:wdmchaft,项目名称:Psybrus,代码行数:31,


示例16: BcAssert

//////////////////////////////////////////////////////////////////////////// reallocvoid BcStream::realloc( BcSize NewSize ){	BcAssert( NewSize > BufferSize_ );	// Round up size	NewSize = ( ( (BcSize)( NewSize ) + AllocSize_ - 1 ) & ~( AllocSize_ - 1 ) );	//	if( pDataBuffer_ != NULL )	{		BcU8* pNewBuffer = new BcU8[ NewSize ];		// Copy data to new buffer		memcpy( pNewBuffer, pDataBuffer_, BufferSize_ );		// Free old buffer		delete [] pDataBuffer_;		// Assign new buffer.		pDataBuffer_ = pNewBuffer;		BufferSize_ = NewSize;	}	else	{		// New buffer from scratch.		pDataBuffer_ = new BcU8[ NewSize ];		BufferSize_ = NewSize;	}}
开发者ID:kolhammer,项目名称:Psybrus,代码行数:31,


示例17: BcGetHardwareThreadCount

//////////////////////////////////////////////////////////////////////////// BcGetHardwareThreadCountBcU32 BcGetHardwareThreadCount(){	SYSTEM_INFO SysInfo;	::GetSystemInfo( &SysInfo );	BcU32 RetVal = (BcU32)SysInfo.dwNumberOfProcessors;	BcAssert( RetVal >= 1 );	return RetVal;}
开发者ID:Psybrus,项目名称:Psybrus,代码行数:10,


示例18: BcAssert

//////////////////////////////////////////////////////////////////////////// addChunkBcU32 CsFileWriter::addChunk( BcU32 ID, void* pData, BcU32 Size ){	BcAssert( Size > 0 );	CsFileChunkNative Chunk = { ID, new BcU8[ Size ], Size };	BcMemCopy( Chunk.pData_, pData, Size );	Chunks_.push_back( Chunk );	return Chunks_.size() - 1;}
开发者ID:kolhammer,项目名称:Psybrus,代码行数:10,


示例19: BcAssert

//////////////////////////////////////////////////////////////////////////// tickvoid SysKernel::tick(){	BcAssert( BcIsGameThread() );	if( ShuttingDown_ == BcFalse )	{		BcScopedLock< BcMutex > Lock( SystemLock_ );		// Add systems.		addSystems();			// Remove systems.			removeSystems();			// Iterate over and process all systems.		TSystemListIterator Iter = SystemList_.begin();			while( Iter != SystemList_.end() && ShuttingDown_ == BcFalse )		{			// Cache system.			SysSystem* pSystem = (*Iter);					// Process system.			if( pSystem->process() == BcFalse )			{				PendingRemoveSystemList_.push_back( pSystem );					}					// Next system.			++Iter;		}	}	else	{		BcScopedLock< BcMutex > Lock( SystemLock_ );		// Iterate over and process all systems.		TSystemListReverseIterator Iter = SystemList_.rbegin();				if( Iter != SystemList_.rend() )		{			// Cache system.			SysSystem* pSystem = (*Iter);						//  Process system.			if( pSystem->process() == BcFalse )			{				PendingRemoveSystemList_.push_back( pSystem );					}		}				// Remove systems.		removeSystems();	}		// Dispatch callbacks.	DelegateDispatcher_.dispatch();}
开发者ID:kolhammer,项目名称:Psybrus,代码行数:60,


示例20: getParentEntity

//////////////////////////////////////////////////////////////////////////// onDetach//virtualvoid ScnDebugRenderComponent::onDetach( ScnEntityWeakRef Parent ){	getParentEntity()->detach( MaterialComponent_ );	BcAssert( pImpl_ == this );	pImpl_ = NULL;	Super::onDetach( Parent );}
开发者ID:Dezzles,项目名称:Psybrus,代码行数:12,


示例21: PSY_LOGSCOPEDCATEGORY

//////////////////////////////////////////////////////////////////////////// visit//virtualvoid ScnRenderingVisitor::visit( class ScnRenderableComponent* pComponent ){	if( pViewComponent_->getRenderMask() & pComponent->getRenderMask() )	{		PSY_LOGSCOPEDCATEGORY( *pComponent->getClass()->getName() );		BcAssert( pComponent->isReady() );		pComponent->render( pViewComponent_, pFrame_, Sort_ );	}}
开发者ID:Psybrus,项目名称:Psybrus,代码行数:12,



注:本文中的BcAssert函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


C++ Beagle_StackTraceBeginM函数代码示例
C++ BattleGroundTypeId函数代码示例
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。