Trigger to update opportunity stage based on Account Status

You're very, very close. What you need to do is gather up the Account Ids and query for the Opportunities using them since each Account could have multiple Opportunities.

You also need to remove your DML from the loop to bulkify your trigger.

 trigger updateopportunities on Account(after update) 
{
    Set<Id> accountIds = new Set<Id>();

    for(Account ac : Trigger.new)
    {
         if(ac.Status__c=='Cancelled')
              accounIds.add(ac.Id);
    }

     List<Opportunity> oppsToUpdate = new List<Opportunity>();

     for(Opportunity opp : [select id, StageName from Opportunity where AccountId in: accountIds])
     {
          opp.StageName='Closed - Cancelled';
          oppsToUpdate.add(opp);
     }

     update oppsToUpdate;
}

Here's another version of the trigger with more guards in it so that it only does work when it needs to - changes to other fields on Account won't consume queries or DML.

The reason to take extra care here is that the Account object can be shared by many apps and customisations in an org, so the trigger logic can pile up. So best to add as little overhead as possible in each trigger by being as selective as possible.

trigger updateopportunities on Account(after update)  {

    Set<Id> accountIds = new Set<Id>();
    for (Account acc : Trigger.new) {
         Account old = Trigger.oldMap.get(acc.Id);
         if (acc.Status__c == 'Cancelled' && acc.Status__c != old.Status__c) {
             accountIds.add(acc.Id);
         }
    }

    if (!accountIds.isEmpty()) {
        List<Opportunity> opps = [
                select Id, StageName
                from Opportunity
                where AccountId in: accountIds
                and StageName != 'Closed - Cancelled'
                ];
        if (!opps.isEmpty()) {
            for (Opportunity opp : opps) {
                opp.StageName = 'Closed - Cancelled';
            }
            update opps;
        }
    }
}